From 1758cfd13e6277c6fb5f3c3c65361943e671012b Mon Sep 17 00:00:00 2001 From: xavo95 Date: Thu, 26 Jun 2025 06:28:24 +0000 Subject: [PATCH] 2.4.3 (#19) Reviewed-on: https://git.xeondev.com/WutheringSlaves/wicked-waifus-rs/pulls/19 --- Cargo.lock | 84 ++-- Cargo.toml | 30 +- .../configserver.default.toml | 2 +- .../src/ai_state_machine_config.rs | 85 +++- wicked-waifus-data/src/blueprint_config.rs | 205 +++++++- wicked-waifus-data/src/buff.rs | 109 +++++ wicked-waifus-data/src/gacha_view_info.rs | 17 +- wicked-waifus-data/src/instance_dungeon.rs | 9 +- wicked-waifus-data/src/level_play_data.rs | 151 +++++- wicked-waifus-data/src/lib.rs | 23 +- wicked-waifus-data/src/misc_data.rs | 450 ------------------ .../src/model_config_preload.rs | 25 + .../src/pb_components/action.rs | 61 +++ .../src/pb_components/condition.rs | 21 + wicked-waifus-data/src/pb_components/mod.rs | 59 ++- wicked-waifus-data/src/pb_components/model.rs | 85 ++++ .../src/phantom_customize_item.rs | 10 + wicked-waifus-data/src/phantom_item.rs | 58 +++ wicked-waifus-data/src/role_skin.rs | 1 - wicked-waifus-data/src/summon_cfg.rs | 12 + .../gameserver.default.toml | 7 +- .../scripts/watermask-dvd.js | 96 ++++ .../scripts/watermask-edit.js | 41 ++ wicked-waifus-game-server/src/config.rs | 2 + .../src/logic/components/attribute.rs | 3 +- .../src/logic/components/character_attach.rs | 22 + .../src/logic/components/fsm.rs | 4 +- .../src/logic/components/logic_state.rs | 24 + .../src/logic/components/mod.rs | 4 + .../src/logic/components/summoner.rs | 3 +- .../src/logic/ecs/component.rs | 36 +- .../src/logic/ecs/mod.rs | 12 +- .../src/logic/ecs/world.rs | 23 +- .../src/logic/gacha/gacha_pool.rs | 21 +- .../src/logic/gacha/pool_info.rs | 23 +- .../src/logic/gacha/service.rs | 18 +- .../src/logic/handler/advice.rs | 8 +- .../src/logic/handler/animal.rs | 26 +- .../src/logic/handler/chat.rs | 44 +- .../src/logic/handler/combat.rs | 49 +- .../src/logic/handler/coop.rs | 6 +- .../src/logic/handler/dummy.rs | 4 +- .../src/logic/handler/entity.rs | 137 +++--- .../src/logic/handler/friend.rs | 10 +- .../src/logic/handler/gacha.rs | 131 +++-- .../src/logic/handler/guide.rs | 35 +- .../src/logic/handler/inventory.rs | 37 +- .../src/logic/handler/lord_gym.rs | 4 +- .../src/logic/handler/mail.rs | 4 +- .../src/logic/handler/map.rs | 20 +- .../src/logic/handler/misc.rs | 38 +- .../src/logic/handler/mod.rs | 22 +- .../src/logic/handler/role.rs | 378 ++++++++------- .../src/logic/handler/scene.rs | 22 +- .../src/logic/handler/skill.rs | 48 +- .../src/logic/handler/teleport.rs | 53 ++- .../src/logic/handler/tutorial.rs | 28 +- .../src/logic/handler/weapon.rs | 196 ++++---- .../src/logic/math/transform.rs | 6 +- .../src/logic/player/mod.rs | 15 +- .../src/logic/player/player_inventory.rs | 111 ++++- .../src/logic/player/player_unlocked_skins.rs | 12 + .../src/logic/role/mod.rs | 9 +- .../src/logic/thread_mgr.rs | 87 ++-- .../src/logic/utils/action_utils.rs | 53 ++- .../src/logic/utils/condition_utils.rs | 110 +++-- .../src/logic/utils/entity_serializer.rs | 20 +- .../src/logic/utils/growth_utils.rs | 3 +- .../src/logic/utils/load_role_info.rs | 2 +- .../src/logic/utils/quadrant_util.rs | 3 +- .../src/logic/utils/world_util.rs | 326 +++++++------ wicked-waifus-http/src/lib.rs | 5 +- .../proto/data.proto | 27 +- 73 files changed, 2454 insertions(+), 1471 deletions(-) create mode 100644 wicked-waifus-data/src/buff.rs create mode 100644 wicked-waifus-data/src/model_config_preload.rs create mode 100644 wicked-waifus-data/src/pb_components/model.rs create mode 100644 wicked-waifus-data/src/phantom_customize_item.rs create mode 100644 wicked-waifus-data/src/phantom_item.rs create mode 100644 wicked-waifus-data/src/summon_cfg.rs create mode 100644 wicked-waifus-game-server/scripts/watermask-dvd.js create mode 100644 wicked-waifus-game-server/scripts/watermask-edit.js create mode 100644 wicked-waifus-game-server/src/logic/components/character_attach.rs create mode 100644 wicked-waifus-game-server/src/logic/components/logic_state.rs diff --git a/Cargo.lock b/Cargo.lock index 6296a64..264c864 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,13 +105,13 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.9" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ - "async-trait", "axum-core", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -139,13 +139,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", @@ -1238,9 +1237,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "md-5" @@ -1546,9 +1545,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.32" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", "syn", @@ -1565,9 +1564,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" dependencies = [ "bytes", "prost-derive", @@ -1575,9 +1574,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", "itertools", @@ -1595,9 +1594,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" dependencies = [ "anyhow", "itertools", @@ -1608,9 +1607,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" dependencies = [ "prost", ] @@ -1942,9 +1941,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -2285,9 +2284,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -2474,9 +2473,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", @@ -2486,18 +2485,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.26" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", @@ -2509,9 +2508,9 @@ dependencies = [ [[package]] name = "toml_write" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tower" @@ -2531,12 +2530,13 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags", "bytes", + "futures-core", "futures-util", "http", "http-body", @@ -2876,7 +2876,7 @@ name = "wicked-waifus-asset-updater" version = "0.1.0" dependencies = [ "git2", - "thiserror 1.0.69", + "thiserror 2.0.12", "tracing", "ureq", "zip-extract", @@ -2914,7 +2914,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "thiserror 1.0.69", + "thiserror 2.0.12", "tracing", ] @@ -2937,7 +2937,7 @@ dependencies = [ "paste", "rand 0.9.1", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tracing", "unreal-niggery-rs", @@ -2962,7 +2962,7 @@ dependencies = [ "kcp", "paste", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tracing", "wicked-waifus-commons", @@ -2996,7 +2996,7 @@ dependencies = [ "cbc", "rbase64", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tower-http", "tracing", ] @@ -3027,7 +3027,7 @@ dependencies = [ [[package]] name = "wicked-waifus-protocol" version = "0.1.0" -source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#316e3ee06f5ee0405e4cab567e67f4315c0f2cfb" +source = "git+https://github.com/xavo95/wicked-waifus-proto-dev.git?branch=2.5.1#17cd6d994259ef38c8c74ef9acf6306c24c582b8" dependencies = [ "byteorder", "crc32fast", @@ -3045,7 +3045,7 @@ dependencies = [ [[package]] name = "wicked-waifus-protocol-derive" version = "0.1.0" -source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#316e3ee06f5ee0405e4cab567e67f4315c0f2cfb" +source = "git+https://github.com/xavo95/wicked-waifus-proto-dev.git?branch=2.5.1#17cd6d994259ef38c8c74ef9acf6306c24c582b8" dependencies = [ "proc-macro2", "quote", @@ -3062,7 +3062,7 @@ dependencies = [ "prost-build", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", "wicked-waifus-protocol", "wicked-waifus-protocol-derive", ] @@ -3077,7 +3077,7 @@ dependencies = [ "rbase64", "rsa", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index db14b97..d7abe46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,14 @@ version = "0.1.0" [workspace.dependencies] # Framework -tokio = { version = "1.39.3", features = ["full"] } -tower-http = { version = "0.6.1", features = ["fs", "trace"] } -axum = "0.7.5" -axum-server = "0.7.1" +tokio = { version = "1.45.1", features = ["full"] } +tower-http = { version = "0.6.6", features = ["fs", "trace"] } +axum = "0.8.4" +axum-server = "0.7.2" zeromq = { version = "0.4.0", default-features = false, features = ["tokio-runtime", "tcp-transport"] } # Database -sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio-rustls"] } +sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-rustls"] } # Cryptography aes = "0.8.4" @@ -25,16 +25,16 @@ rand = "0.8.5" rsa = { version = "0.9.6", features = ["pem"] } # Serialization -serde = { version = "1.0.209", features = ["derive"] } -serde_json = "1.0.128" -serde_repr = "0.1.19" -toml = "0.8.19" -prost = "0.13.2" -prost-build = "0.13.2" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" +serde_repr = "0.1.20" +toml = "0.8.23" +prost = "0.14.1" +prost-build = "0.14.1" # Utility -anyhow = "1.0.86" -thiserror = "1.0.63" +anyhow = "1.0.98" +thiserror = "2.0.12" paste = "1.0.15" rbase64 = "2.0.3" dashmap = "6.1.0" @@ -42,8 +42,8 @@ hex = "0.4.3" byteorder = "1.5.0" # Tracing -tracing = "0.1.40" -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tracing = "0.1.41" +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } # Internal wicked-waifus-asset-updater = { path = "wicked-waifus-asset-updater" } diff --git a/wicked-waifus-config-server/configserver.default.toml b/wicked-waifus-config-server/configserver.default.toml index 99b3b7a..0532581 100644 --- a/wicked-waifus-config-server/configserver.default.toml +++ b/wicked-waifus-config-server/configserver.default.toml @@ -11,5 +11,5 @@ serve_dir_path = "data/assets/config-server" [asset_config] repository_url = "https://git.xeondev.com/wickedwaifus/wicked-waifus-config-server-files.git" -reference = "f088e91db3" +reference = "a7ad3d4ef8" discard_local_changes = true \ No newline at end of file diff --git a/wicked-waifus-data/src/ai_state_machine_config.rs b/wicked-waifus-data/src/ai_state_machine_config.rs index 7574bc2..328f9e9 100644 --- a/wicked-waifus-data/src/ai_state_machine_config.rs +++ b/wicked-waifus-data/src/ai_state_machine_config.rs @@ -1,5 +1,88 @@ use serde::Deserialize; -use crate::StateMachineJson; + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineTransition { + pub from: i32, + pub to: i32, + pub transition_prediction_type: i32, + pub weight: i32, + #[cfg(feature = "strict_json_fields")] + pub conditions: Vec, // TODO: Implement conditions +} + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineNodeCommon { + pub uuid: i32, + #[cfg(feature = "strict_json_fields")] + pub is_anim_state_machine: Option, + #[cfg(feature = "strict_json_fields")] + pub is_conduit_node: Option, + #[cfg(feature = "strict_json_fields")] + pub is_any_state: Option, + #[cfg(feature = "strict_json_fields")] + pub name: String, + #[cfg(feature = "strict_json_fields")] + pub take_control_type: i32, + #[cfg(feature = "strict_json_fields")] + pub transition_rule: i32, + pub children: Option>, + pub transitions: Option>, + #[cfg(feature = "strict_json_fields")] + pub on_enter_actions: Option>, // TODO: Implement actions + #[cfg(feature = "strict_json_fields")] + pub on_exit_actions: Option>, // TODO: Implement actions + #[cfg(feature = "strict_json_fields")] + pub bind_states: Option>, // TODO: Implement bindStates + #[cfg(feature = "strict_json_fields")] + pub task: Option, // TODO: Implement bindStates +} + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineNodeReferenced { + pub reference_uuid: i32, + #[serde(flatten)] + pub common: StateMachineNodeCommon, +} + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineNodeOverrideCommon { + pub override_common_uuid: i32, + #[serde(flatten)] + pub common: StateMachineNodeCommon, +} + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineNodeCustom { + #[serde(flatten)] + pub common: StateMachineNodeCommon, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub enum StateMachineNode { + Reference(StateMachineNodeReferenced), + Override(StateMachineNodeOverrideCommon), + Custom(StateMachineNodeCustom), +} + +#[derive(Clone, Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct StateMachineJson { + pub version: u32, + pub state_machines: Vec, + pub nodes: Vec, +} #[derive(Clone, Debug, Deserialize)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] diff --git a/wicked-waifus-data/src/blueprint_config.rs b/wicked-waifus-data/src/blueprint_config.rs index c4a1d2c..b169d75 100644 --- a/wicked-waifus-data/src/blueprint_config.rs +++ b/wicked-waifus-data/src/blueprint_config.rs @@ -1,6 +1,206 @@ use serde::Deserialize; -use crate::{EntityLogic, EntityType}; +#[derive(Deserialize, PartialEq, Debug, Copy, Clone)] +pub enum EntityType { + AdsorptionFoundation, + AdviseItem, + AiAlertNotifier, + AiGearController, + AiMovementGear, + AirPassage, + AiSceneItem, + Animal, + Animal2, + AnnunciatorCenter, + AnnunciatorWire, + AreaOccupation, + Audio, + AudioBox, + BatchBulletCaster, + BeamCastBullet, + BeamCaster, + BeamCrystal, + BeamDeliver, + BeamReceiver, + BondageTrap, + BuffConsumer, + BuffProducer, + BurstCrystalFoundation, + Chair, + Chair2, + ChallengeInteract, + Chessboard, + Chessman, + ClientTrigger, + Collect, + Collect2, + Collect3, + CollectAnimal, + CollectAnimalPart, + CombatAnimal, + CombatAnimal2, + CombinedVisibleGroup, + ControlConnector, + ConveyorBelt, + CookTool, + CurveControlDestructible, + CustomAoiEditor, + Destructible, + DestructibleControl, + DestructibleExploreInteractor, + DestructibleSceneBullet, + DestructibleTrigger, + Disc, + Drop, + DungeonEntry, + DynamicPortalCreater, + EffectArea, + EnrichmentArea, + EntityBatchRefresh, + EntityBundle, + EntityList, + EntityPackage, + ExploreSkillInteractor, + FishingBoat, + FollowShooter, + FollowShooter2, + FollowTrack, + FollowTrackFoundation, + Gramophone, + GravityFlip, + GroupAi, + HackingTypeFollowShooter, + HitConditionListener, + HookLockPoint, + HookSoundBox, + HookWithRange, + HorseBettingTuanzi, + InhaledItem, + InteractFoundation, + InteractFoundationWithSceneItemAttribute, + InteractGear, + InteractGearGroup, + InteractiveConditionListener, + Item, + ItemFoundation, + JigsawFoundation, + JigsawItem, + KiteHook, + LevelPlay, + LevelPlayReward, + LevelQteTrigger, + LevelSeqTrigger, + LevitateMagnet, + LifePointCenter, + Lift, + Lift2, + LightDeliver, + LocationSafety, + Monitor, + Monster, + MonsterGachaBase, + MonsterGachaItem, + MoveableTrigger, + MusicStand, + NoRenderPortal, + Npc, + Npc2, + PasserbyNpc, + PerformanceOptimizer, + PhotoTarget, + PhysicsSwing, + Portal, + Position, + ProgressBarController, + ProgressBarControllerWithAttribute, + PullingObject, + Range, + RangeTriggerTargetGear, + ReboundPlateGear, + RefreshGroup, + RenderSpecifiedRange, + RenderSpecifiedRange2, + Resurrection, + RewardNpc, + RollingFireball, + Rotator, + SceneAura, + SceneBullet, + SceneBulletCanHit, + SceneBulletTrigger, + SceneBulletWithMovement, + SceneItemStateHint, + SimpleInteract, + SimpleNPc, + SkyboxTrigger, + SlideRail, + Slots, + SoundBox, + SpawnMonster, + SpawnPasserbyNpc, + Spline, + SplineRange, + SummonGongduolaPoint, + StateSceneItem, + StateTrigger, + StatueFoundation, + SuiGuangHook, + TargetGear, + TargetGear2, + TargetGearGroup, + TargetGearGroup2, + TargetGearPro, + TargetGearWithLevelPrefabPerform, + TeleControl, + TeleControl3, + TeleControl4, + TeleControlGroup, + Teleporter, + TemplateEntitySpawner, + TemporaryTeleporter, + TimedStrikeDevice, + TimelineTrackController, + TimeScaledHook, + TimeStop, + Trample, + Trample2, + Trample3, + TrampleWithSceneItemAttribute, + TreasureBox, + Trigger, + TriggerConditionListener, + TuanziNpc, + TuningStand, + TurntableController, + VacuumCleaner, + VarManager, + Vehicle, + Vehicle2, + VehicleNpc, + VehicleSceneItem, + VisibleTrigger, + Vision, + VisionItem, + VisionTreasureBox, + WalkingPatternController, + WaterCollection, + WaterSpout, + Weapon, + WindSource, +} + +#[derive(Deserialize, PartialEq, Debug, Copy, Clone)] +pub enum EntityLogic { + Item, + Animal, + Monster, + Vehicle, + Npc, + Vision, + ClientOnly, + ServerOnly, + Custom, +} #[derive(Deserialize)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] @@ -10,10 +210,7 @@ pub struct BlueprintConfigData { pub blueprint_type: String, pub entity_type: EntityType, pub entity_logic: EntityLogic, - #[cfg(feature = "strict_json_fields")] pub model_id: i32, - #[cfg(feature = "strict_json_fields")] pub half_height: i32, - #[cfg(feature = "strict_json_fields")] pub track_height: i32, } \ No newline at end of file diff --git a/wicked-waifus-data/src/buff.rs b/wicked-waifus-data/src/buff.rs new file mode 100644 index 0000000..b2f4e71 --- /dev/null +++ b/wicked-waifus-data/src/buff.rs @@ -0,0 +1,109 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct BuffData { + pub id: i64, + pub ge_desc: String, + pub duration_policy: i32, // TODO: Enum ?? + #[cfg(feature = "strict_json_fields")] + pub duration_calculation_policy: Vec, + #[cfg(feature = "strict_json_fields")] + pub duration_magnitude: Vec, + #[cfg(feature = "strict_json_fields")] + pub duration_magnitude2: Vec, + #[cfg(feature = "strict_json_fields")] + pub b_duration_affected_by_bullet_time: bool, + #[cfg(feature = "strict_json_fields")] + pub formation_policy: i32, // TODO: Enum ?? + #[cfg(feature = "strict_json_fields")] + pub probability: i32, + #[cfg(feature = "strict_json_fields")] + pub period: i32, + #[cfg(feature = "strict_json_fields")] + pub b_execute_periodic_effect_on_application: bool, + #[cfg(feature = "strict_json_fields")] + pub periodic_inhibition_policy: i32, // TODO: Enum ?? + #[serde(rename = "GameAttributeID")] + pub game_attribute_id: i32, + #[cfg(feature = "strict_json_fields")] + pub calculation_policy: Vec, + #[cfg(feature = "strict_json_fields")] + pub modifier_magnitude: Vec, + #[cfg(feature = "strict_json_fields")] + pub modifier_magnitude2: Vec, + #[cfg(feature = "strict_json_fields")] + pub stacking_type: i32, // TODO: Enum?? + #[cfg(feature = "strict_json_fields")] + pub default_stack_count: i32, + #[cfg(feature = "strict_json_fields")] + pub stack_append_count: i32, + #[cfg(feature = "strict_json_fields")] + pub stack_limit_count: i32, + #[cfg(feature = "strict_json_fields")] + pub stack_duration_refresh_policy: i32, + #[cfg(feature = "strict_json_fields")] + pub stack_period_reset_policy: i32, + #[cfg(feature = "strict_json_fields")] + pub stack_expiration_remove_number: i32, + #[cfg(feature = "strict_json_fields")] + pub b_deny_overflow_application: bool, + #[cfg(feature = "strict_json_fields")] + pub b_clear_stack_on_overflow: bool, + #[cfg(feature = "strict_json_fields")] + pub b_require_modifier_success_to_trigger_cues: bool, + #[cfg(feature = "strict_json_fields")] + pub b_suppress_stacking_cues: bool, + pub gameplay_cue_ids: Vec, + #[cfg(feature = "strict_json_fields")] + pub granted_tags: Vec, + #[cfg(feature = "strict_json_fields")] + pub application_source_tag_requirements: Vec, + #[cfg(feature = "strict_json_fields")] + pub application_source_tag_ignores: Vec, + #[cfg(feature = "strict_json_fields")] + pub application_tag_requirements: Vec, + #[cfg(feature = "strict_json_fields")] + pub application_tag_ignores: Vec, + pub ongoing_tag_requirements: Vec, + pub ongoing_tag_ignores: Vec, + pub removal_tag_requirements: Vec, + pub removal_tag_ignores: Vec, + #[cfg(feature = "strict_json_fields")] + pub remove_buff_with_tags: Vec, + #[cfg(feature = "strict_json_fields")] + pub granted_application_immunity_tags: Vec, + #[cfg(feature = "strict_json_fields")] + pub granted_application_immunity_tag_ignores: Vec, + #[cfg(feature = "strict_json_fields")] + pub premature_expiration_effects: Vec, + #[cfg(feature = "strict_json_fields")] + pub routine_expiration_effects: Vec, + #[cfg(feature = "strict_json_fields")] + pub overflow_effects: Vec, + #[cfg(feature = "strict_json_fields")] + pub related_extra_effect_buff_id: Vec, + #[serde(rename = "ExtraEffectID")] + pub extra_effect_id: i32, + pub extra_effect_parameters: Vec, + pub extra_effect_parameters_grow1: Vec, + pub extra_effect_parameters_grow2: Vec, + #[cfg(feature = "strict_json_fields")] + pub extra_effect_requirements: Vec, + #[cfg(feature = "strict_json_fields")] + pub extra_effect_req_para: Vec, + #[cfg(feature = "strict_json_fields")] + pub extra_effect_req_setting: i32, // TODO: Enum?? + #[cfg(feature = "strict_json_fields")] + pub extra_effect_cd: Vec, + #[cfg(feature = "strict_json_fields")] + pub extra_effect_remove_stack_num: i32, + #[cfg(feature = "strict_json_fields")] + pub extra_effect_probability: Vec, + #[cfg(feature = "strict_json_fields")] + pub buff_action: Vec, + #[cfg(feature = "strict_json_fields")] + pub tag_logic: Vec, + pub dead_remove: bool, +} \ No newline at end of file diff --git a/wicked-waifus-data/src/gacha_view_info.rs b/wicked-waifus-data/src/gacha_view_info.rs index 37e3aaa..da103a1 100644 --- a/wicked-waifus-data/src/gacha_view_info.rs +++ b/wicked-waifus-data/src/gacha_view_info.rs @@ -1,5 +1,20 @@ use serde::Deserialize; -use crate::GachaViewTypeInfoId; +use serde_repr::Deserialize_repr; + +#[derive(Deserialize_repr, PartialEq, Debug, Copy, Clone)] +#[repr(i32)] +pub enum GachaViewTypeInfoId { + NoviceConvene = 1, + FeaturedResonatorConvene = 2, + FeaturedWeaponConvene = 3, + StandardResonatorConvene = 4, + StandardWeaponConvene = 5, + BeginnersChoiceConvene = 6, + AnniversaryResonatorConvene = 7, + AnniversaryWeaponConvene = 8, + NewVoyageResonatorConvene = 9, + NewVoyageWeaponConvene = 10, +} #[derive(Debug, Deserialize)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] diff --git a/wicked-waifus-data/src/instance_dungeon.rs b/wicked-waifus-data/src/instance_dungeon.rs index 4865a67..b660bad 100644 --- a/wicked-waifus-data/src/instance_dungeon.rs +++ b/wicked-waifus-data/src/instance_dungeon.rs @@ -2,7 +2,14 @@ use std::collections::HashMap; use serde::Deserialize; -use crate::{EntranceEntityData, VectorData}; +use crate::VectorData; + +#[derive(Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct EntranceEntityData { + pub dungeon_id: i32, + pub entrance_entity_id: i64, +} #[derive(Deserialize)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] diff --git a/wicked-waifus-data/src/level_play_data.rs b/wicked-waifus-data/src/level_play_data.rs index 5b6c6cf..ad92875 100644 --- a/wicked-waifus-data/src/level_play_data.rs +++ b/wicked-waifus-data/src/level_play_data.rs @@ -1,5 +1,154 @@ use serde::Deserialize; -use crate::LevelPlayDataDetail; + +#[derive(Debug, Deserialize)] +pub enum LevelPlayType { + Challenge, + SilentArea, + Dungeon, + MonsterTreasure, + Quest, + Riddle, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayOpenCondition { + pub conditions: Option>, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayActive { + pub active_type: i32, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayRewardConfigResetTypeMidNight { + pub count: i32, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "Type")] +pub enum LevelPlayRewardConfigResetType { + MidNight(LevelPlayRewardConfigResetTypeMidNight), +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayRewardConfigInteract { + pub reward_id: i32, + pub reward_entity_id: i64, + pub reward_complete_actions: Vec, + pub first_complete_actions: Option>, + pub reset: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "Type")] +pub enum LevelPlayRewardConfig { + None, + Interact(LevelPlayRewardConfigInteract), +} + +#[derive(Debug, Deserialize)] +pub enum FixedDateTime { + Daily, + Weekly +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayRefreshConfigFixedDateTime { + pub update_type: FixedDateTime, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayRefreshConfigCompleted { + pub min_refresh_cd: i32, + pub max_refresh_cd: i32, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "Type")] +pub enum LevelPlayRefreshConfig { + None, + FixedDateTime(LevelPlayRefreshConfigFixedDateTime), + Completed(LevelPlayRefreshConfigCompleted), +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayTrack { + pub track_radius: i32, + pub track_priority: i32, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayMark { + pub mark_id: i32, + pub map_bg_path: String, +} + +#[derive(Debug, Deserialize)] +pub enum OnlineType { + Multiplayer, + Local, + Hang, +} + +#[derive(Debug, Deserialize)] +pub enum ObjType { + LevelPlay, +} + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase", deny_unknown_fields)] +pub struct LevelPlayDataDetail { // Json file contains Data in name, so it has to be DataData + pub id: i32, + pub key: String, + #[cfg(feature = "strict_json_fields")] + pub internal_dest: String, + pub level_id: i32, + #[cfg(feature = "strict_json_fields")] + pub tid_name: String, + pub r#type: LevelPlayType, + pub instance_id: i32, + pub level_play_entity_id: i64, + pub level_additive_id: i32, + pub enter_radius: i32, + pub leave_radius: i32, + pub delay_refresh: bool, + pub delay_destroy: bool, + pub level_play_open_condition: LevelPlayOpenCondition, + pub level_play_active: LevelPlayActive, + pub level_play_reward_config: LevelPlayRewardConfig, + pub level_play_refresh_config: LevelPlayRefreshConfig, + pub level_play_track: LevelPlayTrack, + pub level_play_mark: Option, + pub enter_in_range_actions: Option>, + pub pack_id: i32, + pub online_type: OnlineType, + pub obj_type: ObjType, + #[cfg(feature = "strict_json_fields")] + pub children: Option>, + #[cfg(feature = "strict_json_fields")] + pub reference: Vec, + #[cfg(feature = "strict_json_fields")] + pub weak_reference: Option>, + pub exploratory_degree: Option, +} #[derive(Debug, Deserialize)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] diff --git a/wicked-waifus-data/src/lib.rs b/wicked-waifus-data/src/lib.rs index 785dcb3..8f0e7b4 100644 --- a/wicked-waifus-data/src/lib.rs +++ b/wicked-waifus-data/src/lib.rs @@ -3,7 +3,6 @@ use std::io::BufReader; use paste::paste; -pub use level_entity_config::LevelEntityConfigData; pub use misc_data::*; pub mod node_data; @@ -11,6 +10,7 @@ pub mod pb_components; pub mod text_map_data; mod misc_data; +mod level_entity_config; #[derive(thiserror::Error, Debug)] pub enum LoadDataError { @@ -24,13 +24,14 @@ macro_rules! json_data { ($($table_type:ident;)*) => { $(paste! { mod [<$table_type:snake>]; - pub use [<$table_type:snake>]::[<$table_type Data>]; })* $(paste! { pub mod [<$table_type:snake _data>] { + pub use super::[<$table_type:snake>]::*; + use std::sync::OnceLock; - type Data = super::[<$table_type Data>]; + type Data = super::[<$table_type:snake>]::[<$table_type Data>]; pub(crate) static TABLE: OnceLock> = OnceLock::new(); pub fn iter() -> std::slice::Iter<'static, Data> { @@ -58,15 +59,16 @@ macro_rules! json_hash_table_data { ($($table_type:ident, $key_param:expr, $key_type:ty;)*) => { $(paste! { mod [<$table_type:snake>]; - pub use [<$table_type:snake>]::[<$table_type Data>]; })* $(paste! { pub mod [<$table_type:snake _data>] { + pub use super::[<$table_type:snake>]::*; + use std::collections::HashMap; use std::sync::OnceLock; - pub(crate) type Data = super::[<$table_type Data>]; + pub(crate) type Data = super::[<$table_type:snake>]::[<$table_type Data>]; pub(crate) static TABLE: OnceLock> = OnceLock::new(); pub fn iter() -> std::collections::hash_map::Iter<'static, $key_type, Data> { @@ -139,9 +141,12 @@ json_data! { LevelPlayNodeData; LivenessTask; LordGym; + ModelConfigPreload; MonsterDetection; MonsterPropertyGrowth; Motion; + PhantomCustomizeItem; + PhantomItem; QuestNodeData; ResonanceAmplification; ResonantChain; @@ -166,19 +171,21 @@ json_hash_table_data! { AiBase, id, i32; AiStateMachineConfig, id, String; BlueprintConfig, blueprint_type, String; + Buff, id, i64; DragonPool, id, i32; DropPackage, id, i32; RoleExpItem, id, i32; + SummonCfg, blueprint_type, String; TemplateConfig, blueprint_type, String; } -mod level_entity_config; - pub mod level_entity_config_data { + pub use super::level_entity_config::*; + use std::collections::HashMap; use std::sync::OnceLock; - pub(crate) type Data = super::LevelEntityConfigData; + pub(crate) type Data = LevelEntityConfigData; pub(crate) static TABLE: OnceLock> = OnceLock::new(); pub fn iter() -> std::collections::hash_map::Iter<'static, String, Data> { diff --git a/wicked-waifus-data/src/misc_data.rs b/wicked-waifus-data/src/misc_data.rs index e721665..868cfb0 100644 --- a/wicked-waifus-data/src/misc_data.rs +++ b/wicked-waifus-data/src/misc_data.rs @@ -1,8 +1,4 @@ use serde::Deserialize; -use serde_repr::Deserialize_repr; - -use crate::pb_components::action::Action; -use crate::pb_components::condition::Condition; #[derive(Deserialize)] #[serde(rename_all = "PascalCase")] @@ -52,455 +48,9 @@ impl RawVectorData { } } -#[derive(Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct EntranceEntityData { - pub dungeon_id: i32, - pub entrance_entity_id: i64, -} - -#[derive(Deserialize_repr, PartialEq, Debug, Copy, Clone)] -#[repr(i32)] -pub enum GachaViewTypeInfoId { - NoviceConvene = 1, - FeaturedResonatorConvene = 2, - FeaturedWeaponConvene = 3, - StandardResonatorConvene = 4, - StandardWeaponConvene = 5, - BeginnersChoiceConvene = 6, - MultipleChoiceResonatorConvene = 7, - MultipleChoiceWeaponConvene = 8, -} - #[derive(Debug, Deserialize, Clone)] #[serde(rename_all = "PascalCase")] pub struct ConsumeItem { pub item_id: i32, pub count: i32, -} - -#[derive(Deserialize, PartialEq, Debug, Copy, Clone)] -pub enum EntityType { - AdsorptionFoundation, - AdviseItem, - AiAlertNotifier, - AiGearController, - AiMovementGear, - AirPassage, - AiSceneItem, - Animal, - Animal2, - AnnunciatorCenter, - AnnunciatorWire, - AreaOccupation, - Audio, - AudioBox, - BatchBulletCaster, - BeamCastBullet, - BeamCaster, - BeamCrystal, - BeamDeliver, - BeamReceiver, - BondageTrap, - BuffConsumer, - BuffProducer, - BurstCrystalFoundation, - Chair, - Chair2, - ChallengeInteract, - Chessboard, - Chessman, - ClientTrigger, - Collect, - Collect2, - Collect3, - CollectAnimal, - CollectAnimalPart, - CombatAnimal, - CombatAnimal2, - CombinedVisibleGroup, - ControlConnector, - ConveyorBelt, - CookTool, - CurveControlDestructible, - CustomAoiEditor, - Destructible, - DestructibleControl, - DestructibleExploreInteractor, - DestructibleSceneBullet, - DestructibleTrigger, - Disc, - Drop, - DungeonEntry, - DynamicPortalCreater, - EffectArea, - EnrichmentArea, - EntityBatchRefresh, - EntityBundle, - EntityList, - EntityPackage, - ExploreSkillInteractor, - FishingBoat, - FollowShooter, - FollowShooter2, - FollowTrack, - FollowTrackFoundation, - Gramophone, - GravityFlip, - GroupAi, - HackingTypeFollowShooter, - HookLockPoint, - HookSoundBox, - HookWithRange, - HorseBettingTuanzi, - InhaledItem, - InteractFoundation, - InteractFoundationWithSceneItemAttribute, - InteractGear, - InteractGearGroup, - InteractiveConditionListener, - Item, - ItemFoundation, - JigsawFoundation, - JigsawItem, - KiteHook, - LevelPlay, - LevelPlayReward, - LevelQteTrigger, - LevelSeqTrigger, - LevitateMagnet, - LifePointCenter, - Lift, - LightDeliver, - LocationSafety, - Monitor, - Monster, - MonsterGachaBase, - MonsterGachaItem, - MoveableTrigger, - NoRenderPortal, - Npc, - Npc2, - PasserbyNpc, - PhotoTarget, - PhysicsSwing, - Portal, - Position, - ProgressBarController, - ProgressBarControllerWithAttribute, - PullingObject, - Range, - RangeTriggerTargetGear, - ReboundPlateGear, - RefreshGroup, - RenderSpecifiedRange, - RenderSpecifiedRange2, - Resurrection, - RewardNpc, - RollingFireball, - Rotator, - SceneAura, - SceneBullet, - SceneBulletCanHit, - SceneBulletWithMovement, - SceneItemStateHint, - SimpleInteract, - SimpleNPc, - SkyboxTrigger, - SlideRail, - SoundBox, - SpawnMonster, - SpawnPasserbyNpc, - Spline, - SplineRange, - SummonGongduolaPoint, - StateSceneItem, - StateTrigger, - StatueFoundation, - SuiGuangHook, - TargetGear, - TargetGear2, - TargetGearGroup, - TargetGearGroup2, - TargetGearPro, - TargetGearWithLevelPrefabPerform, - TeleControl, - TeleControl3, - TeleControlGroup, - Teleporter, - TemplateEntitySpawner, - TemporaryTeleporter, - TimedStrikeDevice, - TimelineTrackController, - TimeStop, - Trample, - Trample2, - Trample3, - TreasureBox, - Trigger, - TriggerConditionListener, - TuanziNpc, - TurntableController, - VacuumCleaner, - VarManager, - Vehicle, - Vehicle2, - VehicleNpc, - VehicleSceneItem, - VisibleTrigger, - Vision, - VisionItem, - VisionTreasureBox, - WalkingPatternController, - WaterCollection, - WaterSpout, - Weapon, - WindSource, -} - -#[derive(Deserialize, PartialEq, Debug, Copy, Clone)] -pub enum EntityLogic { - Item, - Animal, - Monster, - Vehicle, - Npc, - Vision, - ClientOnly, - ServerOnly, - Custom, -} - -#[derive(Debug, Deserialize)] -pub enum LevelPlayType { - Challenge, - SilentArea, - Dungeon, - MonsterTreasure, - Quest, - Riddle, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayOpenCondition { - pub conditions: Option>, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayActive { - pub active_type: i32, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayRewardConfigResetTypeMidNight { - pub count: i32, -} - -#[derive(Debug, Deserialize)] -#[serde(tag = "Type")] -pub enum LevelPlayRewardConfigResetType { - MidNight(LevelPlayRewardConfigResetTypeMidNight), -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayRewardConfigInteract { - pub reward_id: i32, - pub reward_entity_id: i64, - pub reward_complete_actions: Vec, - pub first_complete_actions: Option>, - pub reset: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(tag = "Type")] -pub enum LevelPlayRewardConfig { - None, - Interact(LevelPlayRewardConfigInteract), -} - -#[derive(Debug, Deserialize)] -pub enum FixedDateTime { - Daily, - Weekly -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayRefreshConfigFixedDateTime { - pub update_type: FixedDateTime, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayRefreshConfigCompleted { - pub min_refresh_cd: i32, - pub max_refresh_cd: i32, -} - -#[derive(Debug, Deserialize)] -#[serde(tag = "Type")] -pub enum LevelPlayRefreshConfig { - None, - FixedDateTime(LevelPlayRefreshConfigFixedDateTime), - Completed(LevelPlayRefreshConfigCompleted), -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayTrack { - pub track_radius: i32, - pub track_priority: i32, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayMark { - pub mark_id: i32, - pub map_bg_path: String, -} - -#[derive(Debug, Deserialize)] -pub enum OnlineType { - Multiplayer, - Local, - Hang, -} - -#[derive(Debug, Deserialize)] -pub enum ObjType { - LevelPlay, -} - -#[derive(Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase", deny_unknown_fields)] -pub struct LevelPlayDataDetail { // Json file contains Data in name, so it has to be DataData - pub id: i32, - pub key: String, - #[cfg(feature = "strict_json_fields")] - pub internal_dest: String, - pub level_id: i32, - #[cfg(feature = "strict_json_fields")] - pub tid_name: String, - pub r#type: LevelPlayType, - pub instance_id: i32, - pub level_play_entity_id: i64, - pub level_additive_id: i32, - pub enter_radius: i32, - pub leave_radius: i32, - pub delay_refresh: bool, - pub delay_destroy: bool, - pub level_play_open_condition: LevelPlayOpenCondition, - pub level_play_active: LevelPlayActive, - pub level_play_reward_config: LevelPlayRewardConfig, - pub level_play_refresh_config: LevelPlayRefreshConfig, - pub level_play_track: LevelPlayTrack, - pub level_play_mark: Option, - pub enter_in_range_actions: Option>, - pub pack_id: i32, - pub online_type: OnlineType, - pub obj_type: ObjType, - #[cfg(feature = "strict_json_fields")] - pub children: Option>, - #[cfg(feature = "strict_json_fields")] - pub reference: Vec, - #[cfg(feature = "strict_json_fields")] - pub weak_reference: Option>, - pub exploratory_degree: Option, -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineTransition { - pub from: i32, - pub to: i32, - pub transition_prediction_type: i32, - pub weight: i32, - #[cfg(feature = "strict_json_fields")] - pub conditions: Vec, // TODO: Implement conditions -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineNodeCommon { - pub uuid: i32, - #[cfg(feature = "strict_json_fields")] - pub is_anim_state_machine: Option, - #[cfg(feature = "strict_json_fields")] - pub is_conduit_node: Option, - #[cfg(feature = "strict_json_fields")] - pub is_any_state: Option, - #[cfg(feature = "strict_json_fields")] - pub name: String, - #[cfg(feature = "strict_json_fields")] - pub take_control_type: i32, - #[cfg(feature = "strict_json_fields")] - pub transition_rule: i32, - pub children: Option>, - pub transitions: Option>, - #[cfg(feature = "strict_json_fields")] - pub on_enter_actions: Option>, // TODO: Implement actions - #[cfg(feature = "strict_json_fields")] - pub on_exit_actions: Option>, // TODO: Implement actions - #[cfg(feature = "strict_json_fields")] - pub bind_states: Option>, // TODO: Implement bindStates - #[cfg(feature = "strict_json_fields")] - pub task: Option, // TODO: Implement bindStates -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineNodeReferenced { - pub reference_uuid: i32, - #[serde(flatten)] - pub common: StateMachineNodeCommon, -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineNodeOverrideCommon { - pub override_common_uuid: i32, - #[serde(flatten)] - pub common: StateMachineNodeCommon, -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineNodeCustom { - #[serde(flatten)] - pub common: StateMachineNodeCommon, -} - -#[derive(Clone, Debug, Deserialize)] -#[serde(untagged)] -pub enum StateMachineNode { - Reference(StateMachineNodeReferenced), - Override(StateMachineNodeOverrideCommon), - Custom(StateMachineNodeCustom), -} - -#[derive(Clone, Debug, Deserialize)] -#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] -#[serde(rename_all = "PascalCase")] -pub struct StateMachineJson { - pub version: u32, - pub state_machines: Vec, - pub nodes: Vec, } \ No newline at end of file diff --git a/wicked-waifus-data/src/model_config_preload.rs b/wicked-waifus-data/src/model_config_preload.rs new file mode 100644 index 0000000..d1e6c18 --- /dev/null +++ b/wicked-waifus-data/src/model_config_preload.rs @@ -0,0 +1,25 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct ModelConfigPreloadData { + pub id: i32, + pub actor_class_path: String, + #[cfg(feature = "strict_json_fields")] + pub actor_class: Vec, + #[cfg(feature = "strict_json_fields")] + pub animations: Vec, + #[cfg(feature = "strict_json_fields")] + pub effects: Vec, + #[cfg(feature = "strict_json_fields")] + pub audios: Vec, + #[cfg(feature = "strict_json_fields")] + pub meshes: Vec, + #[cfg(feature = "strict_json_fields")] + pub materials: Vec, + #[cfg(feature = "strict_json_fields")] + pub animation_blueprints: Vec, + #[cfg(feature = "strict_json_fields")] + pub others: Vec, +} \ No newline at end of file diff --git a/wicked-waifus-data/src/pb_components/action.rs b/wicked-waifus-data/src/pb_components/action.rs index 8b9395d..4c4400e 100644 --- a/wicked-waifus-data/src/pb_components/action.rs +++ b/wicked-waifus-data/src/pb_components/action.rs @@ -1097,6 +1097,7 @@ pub enum VehicleType { FishingBoat, Gongduola, Appointed(AppointedVehicleType), + Current, } #[derive(Deserialize, Debug, Clone)] @@ -1215,6 +1216,7 @@ pub enum SystemType { ConfirmBox(SystemTypeConfirmBox), FishingItemDelivery(SystemTypeFishingItemDelivery), SoaringChallenge(SystemTypeSoaringChallenge), + ConfirmBox2, // TODO: } #[derive(Deserialize, Debug, Clone)] @@ -1439,6 +1441,7 @@ pub enum GameplayConfig { FishingRoulette, DaolingAuthentication, SundialPuzzle, + TuningStand, } #[derive(Deserialize, Debug, Clone)] @@ -1760,6 +1763,35 @@ pub struct RemoveTrialCharacter { pub character_group: Vec, } +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct CharacterGroup { + pub character_id: i64, + pub is_ai_character: bool, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct UpdateTrialCharacter { + pub character_group_new: Option>, + pub auto_change: Option, + pub is_remove_tips: Option, + pub enable_map_and_teleport: Option, + pub dungeon_list: Option>, + pub enter_range_entities: Option>, + pub create_temp_team: Option, + // TODO: IsDisableRollBackRestoreCharacter ActiveRange +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct RestoreTrialCharacter { + // TODO +} + #[derive(Deserialize, Debug, Clone)] #[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] #[serde(rename_all = "PascalCase")] @@ -2351,6 +2383,30 @@ pub struct RequestSystemFunction { pub config: serde_json::Value, } +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct SetTimeScale { + #[cfg(feature = "strict_json_fields")] + pub config: serde_json::Value, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct EndCommonTip { + #[cfg(feature = "strict_json_fields")] + pub config: serde_json::Value, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct SetupMoraleSystem { + #[cfg(feature = "strict_json_fields")] + pub config: serde_json::Value, +} + #[derive(Deserialize, Debug, Clone)] #[serde(tag = "Name")] pub enum Action { @@ -2465,6 +2521,8 @@ pub enum Action { RemoveTrialFollowShooter(ActionFields), AddTrialCharacter(ActionFields), RemoveTrialCharacter(ActionFields), + UpdateTrialCharacter(ActionFields), + RestoreTrialCharacter(ActionFields), SetAreaState(ActionFields), SwitchSubLevels(ActionFields), ChangeTeamPosition(ActionFields), @@ -2538,6 +2596,9 @@ pub enum Action { StopUiScreenEffect(ActionFields), StopNewMoveWithSpline(ActionFields), RequestSystemFunction(ActionFields), + SetTimeScale(ActionFields), + EndCommonTip(ActionFields), + SetupMoraleSystem(ActionFields), } #[derive(Deserialize, Debug, Clone)] diff --git a/wicked-waifus-data/src/pb_components/condition.rs b/wicked-waifus-data/src/pb_components/condition.rs index 3ef24cc..316ac84 100644 --- a/wicked-waifus-data/src/pb_components/condition.rs +++ b/wicked-waifus-data/src/pb_components/condition.rs @@ -336,6 +336,7 @@ pub enum VehicleType { FishingBoat, Gongduola, SceneItemAutoMoveVehicle, + CoBathingEmptyVehicle, } #[derive(Deserialize, Debug, Clone)] @@ -1198,6 +1199,24 @@ pub struct CheckDangoCultivationProgress { pub UiType: serde_json::Value, } +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct CheckPlayerMoraleLevelRange { + // TODO: + #[cfg(feature = "strict_json_fields")] + pub UiType: serde_json::Value, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct ProgramSpecialProcess { + // TODO: + #[cfg(feature = "strict_json_fields")] + pub UiType: serde_json::Value, +} + #[derive(Deserialize, Debug, Clone)] #[serde(tag = "Type")] pub enum Condition { @@ -1305,6 +1324,8 @@ pub enum Condition { FinishBvbChallenge(FinishBvbChallenge), CompareActorVar(CompareActorVar), CheckDangoCultivationProgress(CheckDangoCultivationProgress), + CheckPlayerMoraleLevelRange(CheckPlayerMoraleLevelRange), + ProgramSpecialProcess(ProgramSpecialProcess), } #[derive(Deserialize, Debug, Clone)] diff --git a/wicked-waifus-data/src/pb_components/mod.rs b/wicked-waifus-data/src/pb_components/mod.rs index 105daf9..f2a4c72 100644 --- a/wicked-waifus-data/src/pb_components/mod.rs +++ b/wicked-waifus-data/src/pb_components/mod.rs @@ -9,6 +9,7 @@ pub mod condition; pub mod entity_state; pub mod flow; pub mod interact; +pub mod model; pub mod monster; pub mod option; pub mod reward; @@ -69,8 +70,7 @@ pub struct ComponentsData { pub guide_line_creator_component: Option, #[cfg(feature = "strict_json_fields")] pub photo_target_component: Option, - #[cfg(feature = "strict_json_fields")] - pub model_component: Option, + pub model_component: Option, #[cfg(feature = "strict_json_fields")] pub entity_group_component: Option, #[cfg(feature = "strict_json_fields")] @@ -222,14 +222,51 @@ pub struct ComponentsData { impl ComponentsData { pub fn merge_with_template(&self, template: &Self) -> Self { Self { - base_info_component: self.base_info_component.as_ref().or(template.base_info_component.as_ref()).cloned(), - ai_component: self.ai_component.as_ref().or(template.ai_component.as_ref()).cloned(), - attribute_component: self.attribute_component.as_ref().or(template.attribute_component.as_ref()).cloned(), - teleport_component: self.teleport_component.as_ref().or(template.teleport_component.as_ref()).cloned(), - monster_component: self.monster_component.as_ref().or(template.monster_component.as_ref()).cloned(), - interact_component: self.interact_component.as_ref().or(template.interact_component.as_ref()).cloned(), - entity_state_component: self.entity_state_component.as_ref().or(template.entity_state_component.as_ref()).cloned(), - reward_component: self.reward_component.as_ref().or(template.reward_component.as_ref()).cloned(), + base_info_component: self + .base_info_component + .as_ref() + .or(template.base_info_component.as_ref()) + .cloned(), + ai_component: self + .ai_component + .as_ref() + .or(template.ai_component.as_ref()) + .cloned(), + attribute_component: self + .attribute_component + .as_ref() + .or(template.attribute_component.as_ref()) + .cloned(), + teleport_component: self + .teleport_component + .as_ref() + .or(template.teleport_component.as_ref()) + .cloned(), + monster_component: self + .monster_component + .as_ref() + .or(template.monster_component.as_ref()) + .cloned(), + interact_component: self + .interact_component + .as_ref() + .or(template.interact_component.as_ref()) + .cloned(), + entity_state_component: self + .entity_state_component + .as_ref() + .or(template.entity_state_component.as_ref()) + .cloned(), + reward_component: self + .reward_component + .as_ref() + .or(template.reward_component.as_ref()) + .cloned(), + model_component: self + .model_component + .as_ref() + .or(template.model_component.as_ref()) + .cloned(), } } -} \ No newline at end of file +} diff --git a/wicked-waifus-data/src/pb_components/model.rs b/wicked-waifus-data/src/pb_components/model.rs new file mode 100644 index 0000000..c17e3f5 --- /dev/null +++ b/wicked-waifus-data/src/pb_components/model.rs @@ -0,0 +1,85 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct ModelIdType { + pub model_id: i32 +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct PrefabStateList { + #[cfg(feature = "strict_json_fields")] + pub scene_interaction_state: i32, + #[cfg(feature = "strict_json_fields")] + pub level_tag: i64, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct LevelPrefabType { + #[cfg(feature = "strict_json_fields")] + pub blueprint_path: String, + #[cfg(feature = "strict_json_fields")] + pub prefab_path: String, + #[cfg(feature = "strict_json_fields")] + pub prefab_state_list: Vec, + #[cfg(feature = "strict_json_fields")] + pub effect_state_list: Vec, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct MeshType { + #[cfg(feature = "strict_json_fields")] + pub mesh: String, +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct DaType { + #[cfg(feature = "strict_json_fields")] + pub da: String, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(tag = "Type")] +pub enum NpcModel { + Mesh(MeshType), + Da(DaType), +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct NpcType { + #[cfg(feature = "strict_json_fields")] + pub blueprint_path: String, + #[cfg(feature = "strict_json_fields")] + pub npc_model: NpcModel, + #[cfg(feature = "strict_json_fields")] + pub abp: String, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(tag = "Type")] +pub enum ModelType { + ModelId(ModelIdType), + LevelPrefab(LevelPrefabType), + Npc(NpcType), +} + +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct ModelComponent { + pub half_height: Option, + pub track_height: Option, + pub disabled: Option, + pub model_type: Option, +} \ No newline at end of file diff --git a/wicked-waifus-data/src/phantom_customize_item.rs b/wicked-waifus-data/src/phantom_customize_item.rs new file mode 100644 index 0000000..f174438 --- /dev/null +++ b/wicked-waifus-data/src/phantom_customize_item.rs @@ -0,0 +1,10 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct PhantomCustomizeItemData { + pub item_id: i32, + pub phantom_id: i32, + pub skin_item_id: i32, +} \ No newline at end of file diff --git a/wicked-waifus-data/src/phantom_item.rs b/wicked-waifus-data/src/phantom_item.rs new file mode 100644 index 0000000..290da92 --- /dev/null +++ b/wicked-waifus-data/src/phantom_item.rs @@ -0,0 +1,58 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct MainProp { + pub rand_group_id: i32, + pub rand_num: i32, +} + +#[derive(Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct PhantomItemData { + pub item_id: i32, + pub monster_id: i32, + #[cfg(feature = "strict_json_fields")] + pub monster_name: String, + pub element_type: Vec, + pub main_prop: MainProp, + pub level_up_group_id: i32, + pub skill_id: i32, + pub calabash_buffs: Vec, + pub rarity: i32, + pub mesh_id: i32, + pub zoom: [f32; 3], + pub location: [f32; 3], + pub rotator: [f32; 3], + #[cfg(feature = "strict_json_fields")] + pub stand_anim: String, + #[cfg(feature = "strict_json_fields")] + pub type_description: String, + #[cfg(feature = "strict_json_fields")] + pub attributes_description: String, + #[cfg(feature = "strict_json_fields")] + pub icon: String, + #[cfg(feature = "strict_json_fields")] + pub icon_middle: String, + #[cfg(feature = "strict_json_fields")] + pub icon_small: String, + #[cfg(feature = "strict_json_fields")] + pub mesh: String, + pub quality_id: i32, + pub max_capcity: i32, + pub item_access: Vec, + pub obtained_show: i32, + #[cfg(feature = "strict_json_fields")] + pub obtained_show_description: String, + pub num_limit: i32, + pub show_in_bag: bool, + pub sort_index: i32, + #[cfg(feature = "strict_json_fields")] + pub skill_icon: String, + pub destructible: bool, + pub red_dot_disable_rule: i32, + pub fetter_group: Vec, + pub phantom_type: i32, + pub parent_monster_id: i32, +} \ No newline at end of file diff --git a/wicked-waifus-data/src/role_skin.rs b/wicked-waifus-data/src/role_skin.rs index a246d24..930d838 100644 --- a/wicked-waifus-data/src/role_skin.rs +++ b/wicked-waifus-data/src/role_skin.rs @@ -77,7 +77,6 @@ pub struct RoleSkinData { pub ui_mesh_id: i32, #[cfg(feature = "strict_json_fields")] pub role_body: String, - #[cfg(feature = "strict_json_fields")] #[serde(rename = "UiScenePerformanceABP")] pub ui_scene_performance_abp: String, #[cfg(feature = "strict_json_fields")] diff --git a/wicked-waifus-data/src/summon_cfg.rs b/wicked-waifus-data/src/summon_cfg.rs new file mode 100644 index 0000000..ffda5bc --- /dev/null +++ b/wicked-waifus-data/src/summon_cfg.rs @@ -0,0 +1,12 @@ +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct SummonCfgData { + pub id: i32, + pub blueprint_type: String, + #[cfg(feature = "strict_json_fields")] + pub name: String, + pub born_buff_id: Vec, +} \ No newline at end of file diff --git a/wicked-waifus-game-server/gameserver.default.toml b/wicked-waifus-game-server/gameserver.default.toml index d367b4e..6a86926 100644 --- a/wicked-waifus-game-server/gameserver.default.toml +++ b/wicked-waifus-game-server/gameserver.default.toml @@ -19,7 +19,7 @@ load_textmaps = true quadrant_size = 1000000 [asset_config] -asset_url = "https://git.xeondev.com/wickedwaifus/wicked-waifus-data/releases/download/pioneer_2.4.4/bundle.zip" +asset_url = "https://git.xeondev.com/wickedwaifus/wicked-waifus-data/releases/download/pioneer_2.5.2/bundle.zip" buffer_size = 268435456 [default_unlocks] @@ -39,4 +39,7 @@ unlock_all_role_skins = false # TODO: Set this to the same value as unlock_all_role_skins, without it, it fails(maybe jinshi weapon skin problem??) unlock_all_weapon_skins = false unlock_all_fly_skins = false -unlock_all_wing_skins = false \ No newline at end of file +unlock_all_wing_skins = false +unlock_all_echo_skins = false +unlock_all_echo = false +# TODO: Add max level here too?? \ No newline at end of file diff --git a/wicked-waifus-game-server/scripts/watermask-dvd.js b/wicked-waifus-game-server/scripts/watermask-dvd.js new file mode 100644 index 0000000..397aba6 --- /dev/null +++ b/wicked-waifus-game-server/scripts/watermask-dvd.js @@ -0,0 +1,96 @@ +const UE = require("ue"); +const Info_1 = require("../../../Core/Common/Info"); +const MathUtils_1 = require("../../../Core/Utils/MathUtils"); +const UiLayerType_1 = require("../../Ui/Define/UiLayerType"); +const UiLayer_1 = require("../../Ui/UiLayer"); + +var _a = require("../Module/WaterMask/WaterMaskController").WaterMaskView; + +_a.LOo = 0.12; +_a.yOo = 700; +_a.IOo = 700; + +let colorCycle = [ + "#FF0000", + "#FF7F00", + "#FFFF00", + "#00FF00", + "#0000FF", + "#4B0082", + "#9400D3", +]; +let colorIndex = 0; +let directionX = 3; +let directionY = 3; +const SPEED = 8; +const TEXT_OFFSET_X = 270; +const TEXT_OFFSET_Y = 20; + +_a.vOo = function () { + void 0 !== _a.SOo && _a.EOo(); + let e = UiLayer_1.UiLayer.GetLayerRootUiItem( + UiLayerType_1.ELayerType.WaterMask, + ); + _a.SOo = UE.KuroActorManager.SpawnActor( + Info_1.Info.World, + UE.UIContainerActor.StaticClass(), + MathUtils_1.MathUtils.DefaultTransform, + void 0, + ); + let t = _a.SOo.RootComponent; + t.SetDisplayName("WaterMaskContainer"); + UE.KuroStaticLibrary.SetActorPermanent(_a.SOo, !0, !0); + _a.SOo.K2_AttachRootComponentTo(e); + + let rootComponent = t.GetRootCanvas().GetOwner().RootComponent; + let screenWidth = rootComponent.widget.width; + let screenHeight = rootComponent.widget.height; + + let textActor = UE.KuroActorManager.SpawnActor( + Info_1.Info.World, + UE.UITextActor.StaticClass(), + MathUtils_1.MathUtils.DefaultTransform, + void 0, + ); + let textRoot = textActor.RootComponent; + textActor.K2_AttachRootComponentTo(t); + textRoot.SetDisplayName("NangPoRao:fuckhadros:"); + let textComponent = textActor.GetComponentByClass(UE.UIText.StaticClass()); + + textComponent.SetFontSize(48); + textComponent.SetOverflowType(0); + textComponent.SetAlpha(_a.LOo); + textComponent.SetFont(UE.LGUIFontData.GetDefaultFont()); + textComponent.SetText("{PLAYER_USERNAME}{CUSTOM_TEXT}"); + textComponent.SetColor(UE.Color.FromHex(colorCycle[colorIndex])); + + let posX = 0; + let posY = 0; + const halfWidth = screenWidth / 2 - TEXT_OFFSET_X; + const halfHeight = screenHeight / 2 - TEXT_OFFSET_Y; + + function updatePosition() { + posX += directionX; + posY += directionY; + + if (posX > halfWidth || posX < -halfWidth) { + directionX *= -1; + colorIndex = (colorIndex + 1) % colorCycle.length; + textComponent.SetColor(UE.Color.FromHex(colorCycle[colorIndex])); + textComponent.SetAlpha(_a.LOo); + } + + if (posY > halfHeight || posY < -halfHeight) { + directionY *= -1; + colorIndex = (colorIndex + 1) % colorCycle.length; + textComponent.SetColor(UE.Color.FromHex(colorCycle[colorIndex])); + textComponent.SetAlpha(_a.LOo); + } + + textRoot.SetUIRelativeLocation(new UE.Vector(posX, posY, 0)); + } + + setInterval(updatePosition, 16); +}; + +_a.vOo(); \ No newline at end of file diff --git a/wicked-waifus-game-server/scripts/watermask-edit.js b/wicked-waifus-game-server/scripts/watermask-edit.js new file mode 100644 index 0000000..30a9be9 --- /dev/null +++ b/wicked-waifus-game-server/scripts/watermask-edit.js @@ -0,0 +1,41 @@ +const UE = require("ue"), + Info_1 = require("../../../Core/Common/Info"), + MathUtils_1 = require("../../../Core/Utils/MathUtils"), + EventDefine_1 = require("../../Common/Event/EventDefine"), + EventSystem_1 = require("../../Common/Event/EventSystem"), + UiControllerBase_1 = require("../../Ui/Base/UiControllerBase"), + UiLayerType_1 = require("../../Ui/Define/UiLayerType"), + UiLayer_1 = require("../../Ui/UiLayer"); + +var _a = require('../Module/WaterMask/WaterMaskController').WaterMaskView; +_a.LOo = 0.18; +_a.yOo = 700; +_a.IOo = 700; +_a.vOo = function () { + void 0 !== _a.SOo && _a.EOo(); + var e = UiLayer_1.UiLayer.GetLayerRootUiItem(UiLayerType_1.ELayerType.WaterMask), + t = (_a.SOo = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UIContainerActor.StaticClass(), + MathUtils_1.MathUtils.DefaultTransform, void 0), _a.SOo.RootComponent), + e = (t.SetDisplayName("WaterMaskContainer"), UE.KuroStaticLibrary.SetActorPermanent(_a.SOo, !0, !0), _a.SOo + .K2_AttachRootComponentTo(e), t.GetRootCanvas().GetOwner().RootComponent), + i = e.widget.width % _a.yOo / 2, + r = e.widget.height % _a.IOo / 2, + n = e.widget.width / 2, + _ = e.widget.height / 2, + s = Math.ceil(e.widget.width / _a.yOo), + o = Math.ceil(e.widget.height / _a.IOo), + v = "{PLAYER_USERNAME}{CUSTOM_TEXT}"; // EDIT ME! + for (let a = 0; a < s; a++) + for (let e = 0; e < o; e++) { + var E = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UITextActor.StaticClass(), MathUtils_1 + .MathUtils.DefaultTransform, void 0), + U = E.RootComponent, + U = (E.K2_AttachRootComponentTo(t), U.SetDisplayName("WaterMaskText"), E.GetComponentByClass(UE + .UIText.StaticClass())); + U.SetFontSize(_a.vFt), U.SetOverflowType(0), U.SetAlpha(_a.LOo), U.SetFont(UE.LGUIFontData + .GetDefaultFont()), U.SetText(v), U.SetUIRelativeLocation(new UE.Vector(a * _a.yOo - n + i, e * + _a.IOo - _ + r, 0)), U.SetUIRelativeRotation(new UE.Rotator(0, _a.TOo, 0)), UE.KuroStaticLibrary + .SetActorPermanent(E, !0, !0) + } +}; +_a.vOo(); \ No newline at end of file diff --git a/wicked-waifus-game-server/src/config.rs b/wicked-waifus-game-server/src/config.rs index 7db903b..b7be543 100644 --- a/wicked-waifus-game-server/src/config.rs +++ b/wicked-waifus-game-server/src/config.rs @@ -49,6 +49,8 @@ pub struct DefaultUnlocks { pub unlock_all_weapon_skins: bool, pub unlock_all_fly_skins: bool, pub unlock_all_wing_skins: bool, + pub unlock_all_echo_skins: bool, + pub unlock_all_echo: bool, } impl TomlConfig for ServiceConfig { diff --git a/wicked-waifus-game-server/src/logic/components/attribute.rs b/wicked-waifus-game-server/src/logic/components/attribute.rs index 89a4b06..76fce9b 100644 --- a/wicked-waifus-game-server/src/logic/components/attribute.rs +++ b/wicked-waifus-game-server/src/logic/components/attribute.rs @@ -1,10 +1,9 @@ -use wicked_waifus_data::BasePropertyData; use wicked_waifus_protocol::{ entity_component_pb::ComponentPb, AttrData, AttributeComponentPb, EAttributeType, EntityComponentPb, LivingStatus, }; use std::collections::HashMap; - +use wicked_waifus_data::base_property_data::BasePropertyData; use crate::logic::ecs::component::Component; use crate::logic::utils::load_role_info::attribute_from_data; diff --git a/wicked-waifus-game-server/src/logic/components/character_attach.rs b/wicked-waifus-game-server/src/logic/components/character_attach.rs new file mode 100644 index 0000000..a76085e --- /dev/null +++ b/wicked-waifus-game-server/src/logic/components/character_attach.rs @@ -0,0 +1,22 @@ +use wicked_waifus_protocol::entity_component_pb::ComponentPb; +use wicked_waifus_protocol::{CharacterAttachComponentPb, CharacterAttachInfo, EntityComponentPb}; + +use crate::logic::ecs::component::Component; + +pub struct CharacterAttach { + pub pb_combine_part_info_list: Vec, + pub pb_combine_target_server_id: i64, +} + +impl Component for CharacterAttach { + fn set_pb_data(&self, pb: &mut wicked_waifus_protocol::EntityPb) { + pb.component_pbs.push(EntityComponentPb { + component_pb: Some(ComponentPb::CharacterAttachComponentPb( + CharacterAttachComponentPb { + pb_combine_part_info_list: self.pb_combine_part_info_list.clone(), + pb_combine_target_server_id: self.pb_combine_target_server_id, + }, + )), + }) + } +} diff --git a/wicked-waifus-game-server/src/logic/components/fsm.rs b/wicked-waifus-game-server/src/logic/components/fsm.rs index 3f7eb26..4710ca7 100644 --- a/wicked-waifus-game-server/src/logic/components/fsm.rs +++ b/wicked-waifus-game-server/src/logic/components/fsm.rs @@ -5,8 +5,8 @@ use indexmap::IndexMap; use wicked_waifus_protocol::{DFsm, DFsmBlackBoard, EntityComponentPb, EntityFsmComponentPb, FsmCustomBlackboardDatas}; use wicked_waifus_protocol::entity_component_pb::ComponentPb; -use wicked_waifus_data::{ai_base_data, ai_state_machine_config_data, AiStateMachineConfigData, StateMachineJson, StateMachineNode, StateMachineNodeCommon}; - +use wicked_waifus_data::{ai_base_data, ai_state_machine_config_data}; +use wicked_waifus_data::ai_state_machine_config_data::{AiStateMachineConfigData, StateMachineJson, StateMachineNode, StateMachineNodeCommon}; use crate::logic::ecs::component::Component; static COMMON_FSM: OnceLock = OnceLock::new(); diff --git a/wicked-waifus-game-server/src/logic/components/logic_state.rs b/wicked-waifus-game-server/src/logic/components/logic_state.rs new file mode 100644 index 0000000..f1e5933 --- /dev/null +++ b/wicked-waifus-game-server/src/logic/components/logic_state.rs @@ -0,0 +1,24 @@ +use wicked_waifus_protocol::entity_component_pb::ComponentPb; +use wicked_waifus_protocol::{EntityComponentPb, LogicStateComponentPb}; + +use crate::logic::ecs::component::Component; + +pub struct LogicState { + pub position_state: i32, + pub move_state: i32, + pub direction_state: i32, + pub position_sub_state: i32, +} + +impl Component for LogicState { + fn set_pb_data(&self, pb: &mut wicked_waifus_protocol::EntityPb) { + pb.component_pbs.push(EntityComponentPb { + component_pb: Some(ComponentPb::LogicStateComponentPb(LogicStateComponentPb { + position_state: self.position_state, + move_state: self.move_state, + direction_state: self.direction_state, + position_sub_state: self.position_sub_state, + })), + }) + } +} diff --git a/wicked-waifus-game-server/src/logic/components/mod.rs b/wicked-waifus-game-server/src/logic/components/mod.rs index 6c0dc6a..782cc4a 100644 --- a/wicked-waifus-game-server/src/logic/components/mod.rs +++ b/wicked-waifus-game-server/src/logic/components/mod.rs @@ -1,11 +1,13 @@ mod attribute; mod autonomous; +mod character_attach; mod concomitant; mod entity_config; mod equip; mod fight_buff; mod fsm; mod interact; +mod logic_state; mod monster_ai; mod movement; mod owner_player; @@ -23,12 +25,14 @@ mod weapon_skin; pub use attribute::Attribute; pub use autonomous::Autonomous; +pub use character_attach::CharacterAttach; pub use concomitant::Concomitant; pub use entity_config::EntityConfig; pub use equip::Equip; pub use fight_buff::FightBuff; pub use fsm::Fsm; pub use interact::Interact; +pub use logic_state::LogicState; pub use monster_ai::MonsterAi; pub use movement::Movement; pub use owner_player::OwnerPlayer; diff --git a/wicked-waifus-game-server/src/logic/components/summoner.rs b/wicked-waifus-game-server/src/logic/components/summoner.rs index 9f1bf54..34353be 100644 --- a/wicked-waifus-game-server/src/logic/components/summoner.rs +++ b/wicked-waifus-game-server/src/logic/components/summoner.rs @@ -4,6 +4,7 @@ use wicked_waifus_protocol::entity_component_pb::ComponentPb; use crate::logic::ecs::component::Component; pub struct Summoner { + pub summoner_id: i64, pub summon_cfg_id: i32, pub summon_skill_id: i32, pub summon_type: i32, @@ -13,7 +14,7 @@ impl Component for Summoner { fn set_pb_data(&self, pb: &mut wicked_waifus_protocol::EntityPb) { pb.component_pbs.push(EntityComponentPb { component_pb: Some(ComponentPb::SummonerComponent(SummonerComponentPb { - summoner_id: pb.id + 1, + summoner_id: self.summoner_id, summon_cfg_id: self.summon_cfg_id, summon_skill_id: self.summon_skill_id, player_id: pb.player_id, diff --git a/wicked-waifus-game-server/src/logic/ecs/component.rs b/wicked-waifus-game-server/src/logic/ecs/component.rs index c8556ee..0313a0c 100644 --- a/wicked-waifus-game-server/src/logic/ecs/component.rs +++ b/wicked-waifus-game-server/src/logic/ecs/component.rs @@ -23,27 +23,29 @@ macro_rules! impl_component_container { } impl_component_container! { - Position; - EntityConfig; - OwnerPlayer; - Visibility; Attribute; - PlayerOwnedEntityMarker; - Movement; - Equip; - VisionSkill; - MonsterAi; - Fsm; - RoleSkin; - FightBuff; - StateTag; - Tag; Autonomous; - Interact; + CharacterAttach; Concomitant; - Summoner; - SoarWingSkin; + EntityConfig; + Equip; + FightBuff; + Fsm; + Interact; + LogicState; + MonsterAi; + Movement; + OwnerPlayer; ParaglidingSkin; + PlayerOwnedEntityMarker; + Position; + RoleSkin; + SoarWingSkin; + StateTag; + Summoner; + Tag; + Visibility; + VisionSkill; WeaponSkin; } diff --git a/wicked-waifus-game-server/src/logic/ecs/mod.rs b/wicked-waifus-game-server/src/logic/ecs/mod.rs index e48d54f..84bef44 100644 --- a/wicked-waifus-game-server/src/logic/ecs/mod.rs +++ b/wicked-waifus-game-server/src/logic/ecs/mod.rs @@ -25,8 +25,8 @@ macro_rules! find_component { // Query specified components from all entities (and) #[macro_export] macro_rules! query_with { - ($world_entitys:expr, $($comp:ident),*) => { - $world_entitys.components().iter().filter(|(_, comps)| { + ($world_entities:expr, $($comp:ident),*) => { + $world_entities.components().iter().filter(|(_, comps)| { $(comps.iter().any(|comp| matches!(&*comp.borrow(), ComponentContainer::$comp(_))) && ) * true }) @@ -44,8 +44,8 @@ macro_rules! query_with { // Query specified components from all entities (or) #[macro_export] macro_rules! query_hn_with { - ($world_entitys:expr, $($comp:ident),*) => { - $world_entitys.components().iter().filter(|(_, comps)| { + ($world_entities:expr, $($comp:ident),*) => { + $world_entities.components().iter().filter(|(_, comps)| { $(comps.iter().any(|comp| matches!(&*comp.borrow(), ComponentContainer::$comp(_))) || ) * false }) @@ -70,8 +70,8 @@ macro_rules! ident_as_none { // Query components of specified entity #[macro_export] macro_rules! query_components { - ($world_entitys:expr, $entity_id:expr, $($comp:ident),*) => { - $world_entitys.components().iter().find(|(id, _)| $entity_id == i64::from(**id)) + ($world_entities:expr, $entity_id:expr, $($comp:ident),*) => { + $world_entities.components().iter().find(|(id, _)| $entity_id == i64::from(**id)) .map(|(_, comps)| { ($( $crate::find_component!(comps, $comp), diff --git a/wicked-waifus-game-server/src/logic/ecs/world.rs b/wicked-waifus-game-server/src/logic/ecs/world.rs index 3692c68..f4d3140 100644 --- a/wicked-waifus-game-server/src/logic/ecs/world.rs +++ b/wicked-waifus-game-server/src/logic/ecs/world.rs @@ -7,6 +7,7 @@ use std::collections::hash_map::{Keys, Values}; use std::collections::HashMap; use wicked_waifus_protocol::FightBuffInformation; +#[derive(Default)] pub struct WorldEntity { components: HashMap>>, entity_manager: EntityManager, @@ -15,7 +16,7 @@ pub struct WorldEntity { pub struct World { pub player_cur_map_id: i32, - pub world_entitys: HashMap, // i32 -> map_id + pub world_entities: HashMap, // i32 -> map_id pub in_world_players: HashMap, // joined players metadata } @@ -23,7 +24,7 @@ impl World { pub fn new() -> Self { Self { player_cur_map_id: 8, - world_entitys: HashMap::new(), + world_entities: HashMap::new(), in_world_players: HashMap::new(), } } @@ -42,13 +43,13 @@ impl World { } pub fn get_mut_world_entity(&mut self) -> &mut WorldEntity { - self.world_entitys + self.world_entities .get_mut(&self.player_cur_map_id) .unwrap_or_else(|| panic!("Failed to get cur map data: {}", self.player_cur_map_id)) } pub fn get_world_entity(&self) -> &WorldEntity { - self.world_entitys + self.world_entities .get(&self.player_cur_map_id) .unwrap_or_else(|| panic!("Failed to get cur map data: {}", self.player_cur_map_id)) } @@ -64,7 +65,7 @@ impl WorldEntity { entity, self.components .entry(entity.entity_id) - .or_insert(Vec::new()), + .or_default(), ) } @@ -114,14 +115,4 @@ impl WorldEntity { pub fn generate_role_permanent_buffs(&mut self, entity_id: i64) -> Vec { self.buff_manager.create_permanent_buffs(entity_id) } -} - -impl Default for WorldEntity { - fn default() -> Self { - Self { - components: HashMap::new(), - entity_manager: EntityManager::default(), - buff_manager: BufManager::default(), - } - } -} +} \ No newline at end of file diff --git a/wicked-waifus-game-server/src/logic/gacha/gacha_pool.rs b/wicked-waifus-game-server/src/logic/gacha/gacha_pool.rs index e78570b..c266559 100644 --- a/wicked-waifus-game-server/src/logic/gacha/gacha_pool.rs +++ b/wicked-waifus-game-server/src/logic/gacha/gacha_pool.rs @@ -2,10 +2,10 @@ use rand::prelude::IndexedRandom; use rand::Rng; use wicked_waifus_protocol::{ErrorCode, GachaResult, GachaReward}; -use wicked_waifus_data::GachaViewTypeInfoId::{ - BeginnersChoiceConvene, FeaturedResonatorConvene, FeaturedWeaponConvene, - MultipleChoiceResonatorConvene, MultipleChoiceWeaponConvene, NoviceConvene, - StandardResonatorConvene, StandardWeaponConvene, +use wicked_waifus_data::gacha_view_info_data::GachaViewTypeInfoId::{ + AnniversaryResonatorConvene, AnniversaryWeaponConvene, BeginnersChoiceConvene, + FeaturedResonatorConvene, FeaturedWeaponConvene, NewVoyageResonatorConvene, + NewVoyageWeaponConvene, NoviceConvene, StandardResonatorConvene, StandardWeaponConvene, }; use crate::logic::gacha::pool_info::PoolInfo; @@ -118,7 +118,10 @@ impl GachaPool { let weapon_id = role.equip_weapon; player.role_list.insert(item_id, role); // TODO notifies player update - player.inventory.add_weapon(role_id, 0, 1, 0, 0, 0, weapon_id).unwrap(); + player + .inventory + .add_weapon(role_id, 0, 1, 0, 0, 0, weapon_id) + .unwrap(); // TODO notifies weapon update } } @@ -151,13 +154,15 @@ impl GachaPool { }, 2 => match self.info.pool_type { NoviceConvene | StandardResonatorConvene => &[1405, 1301, 1503, 1104, 1203], - // TODO: Review MultipleChoiceConvene + // TODO: Review MultipleChoiceConvene(anniversary and new voyage) FeaturedResonatorConvene | FeaturedWeaponConvene | StandardWeaponConvene | BeginnersChoiceConvene - | MultipleChoiceResonatorConvene - | MultipleChoiceWeaponConvene => &self.info.rate_up_five_star[..], + | AnniversaryResonatorConvene + | AnniversaryWeaponConvene + | NewVoyageResonatorConvene + | NewVoyageWeaponConvene => &self.info.rate_up_five_star[..], }, _ => unreachable!(), }; diff --git a/wicked-waifus-game-server/src/logic/gacha/pool_info.rs b/wicked-waifus-game-server/src/logic/gacha/pool_info.rs index a4ebdb6..f14a7f0 100644 --- a/wicked-waifus-game-server/src/logic/gacha/pool_info.rs +++ b/wicked-waifus-game-server/src/logic/gacha/pool_info.rs @@ -1,10 +1,10 @@ use std::time::SystemTime; -use wicked_waifus_data::GachaViewTypeInfoId; -use wicked_waifus_data::GachaViewTypeInfoId::{ - BeginnersChoiceConvene, FeaturedResonatorConvene, FeaturedWeaponConvene, - MultipleChoiceResonatorConvene, MultipleChoiceWeaponConvene, NoviceConvene, - StandardResonatorConvene, StandardWeaponConvene, +use wicked_waifus_data::gacha_view_info_data::GachaViewTypeInfoId; +use wicked_waifus_data::gacha_view_info_data::GachaViewTypeInfoId::{ + AnniversaryResonatorConvene, AnniversaryWeaponConvene, BeginnersChoiceConvene, + FeaturedResonatorConvene, FeaturedWeaponConvene, NewVoyageResonatorConvene, + NewVoyageWeaponConvene, NoviceConvene, StandardResonatorConvene, StandardWeaponConvene, }; use crate::logic::gacha::category::PoolCategory; @@ -78,11 +78,14 @@ impl PoolInfo { StandardResonatorConvene | StandardWeaponConvene => { (50001, 0, 80, PitySystem::default()) } - // TODO: Review MultipleChoiceConvene - FeaturedResonatorConvene - | MultipleChoiceResonatorConvene - | MultipleChoiceWeaponConvene => (50002, 0, 0, PitySystem::default()), - FeaturedWeaponConvene => (50005, 0, 0, PitySystem::default()), + // TODO: Review MultipleChoiceConvene(anniversary and new voyage) + FeaturedResonatorConvene | AnniversaryResonatorConvene | NewVoyageResonatorConvene => { + (50002, 0, 0, PitySystem::default()) + } + // TODO: Review MultipleChoiceConvene(anniversary and new voyage) + FeaturedWeaponConvene | AnniversaryWeaponConvene | NewVoyageWeaponConvene => { + (50005, 0, 0, PitySystem::default()) + } BeginnersChoiceConvene => match pool_id { 51..56 => (50006, 0, 1, PitySystem::default()), _ => (50001, 0, 80, PitySystem::default()), diff --git a/wicked-waifus-game-server/src/logic/gacha/service.rs b/wicked-waifus-game-server/src/logic/gacha/service.rs index 80435cb..05f79a4 100644 --- a/wicked-waifus-game-server/src/logic/gacha/service.rs +++ b/wicked-waifus-game-server/src/logic/gacha/service.rs @@ -5,10 +5,10 @@ use rand::prelude::StdRng; use rand::SeedableRng; use wicked_waifus_data::gacha_view_info_data; -use wicked_waifus_data::GachaViewTypeInfoId::{ - BeginnersChoiceConvene, FeaturedResonatorConvene, FeaturedWeaponConvene, - MultipleChoiceResonatorConvene, MultipleChoiceWeaponConvene, NoviceConvene, - StandardResonatorConvene, StandardWeaponConvene, +use wicked_waifus_data::gacha_view_info_data::GachaViewTypeInfoId::{ + AnniversaryResonatorConvene, AnniversaryWeaponConvene, BeginnersChoiceConvene, + FeaturedResonatorConvene, FeaturedWeaponConvene, NewVoyageResonatorConvene, + NewVoyageWeaponConvene, NoviceConvene, StandardResonatorConvene, StandardWeaponConvene, }; use wicked_waifus_protocol::{ErrorCode, GachaResult}; @@ -41,11 +41,15 @@ impl GachaService { NoviceConvene | StandardResonatorConvene | StandardWeaponConvene => { PoolCategory::Permanent } - // TODO: Review MultipleChoiceConvene + // TODO: Review MultipleChoiceConvene(anniversary and new voyage) FeaturedResonatorConvene | FeaturedWeaponConvene - | MultipleChoiceResonatorConvene - | MultipleChoiceWeaponConvene => PoolCategory::Event(Self::THREE_WEEKS), + | StandardWeaponConvene + | BeginnersChoiceConvene + | AnniversaryResonatorConvene + | AnniversaryWeaponConvene + | NewVoyageResonatorConvene + | NewVoyageWeaponConvene => PoolCategory::Event(Self::THREE_WEEKS), BeginnersChoiceConvene => match element.id { 51..56 => PoolCategory::Special(Self::ONE_WEEK), _ => PoolCategory::Permanent, diff --git a/wicked-waifus-game-server/src/logic/handler/advice.rs b/wicked-waifus-game-server/src/logic/handler/advice.rs index 92291d7..d975790 100644 --- a/wicked-waifus-game-server/src/logic/handler/advice.rs +++ b/wicked-waifus-game-server/src/logic/handler/advice.rs @@ -1,13 +1,13 @@ +use crate::logic::thread_mgr::NetContext; use wicked_waifus_protocol::{AdviceSetRequest, AdviceSetResponse, ErrorCode}; -use crate::logic::player::Player; pub fn on_advice_set_request( - player: &mut Player, + ctx: &mut NetContext, request: AdviceSetRequest, response: &mut AdviceSetResponse, ) { - player.advise.is_show = request.is_show; + ctx.player.advise.is_show = request.is_show; response.is_show = request.is_show; response.error_code = ErrorCode::Success.into(); -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/animal.rs b/wicked-waifus-game-server/src/logic/handler/animal.rs index a2c7b45..a37eb2b 100644 --- a/wicked-waifus-game-server/src/logic/handler/animal.rs +++ b/wicked-waifus-game-server/src/logic/handler/animal.rs @@ -1,17 +1,21 @@ -use wicked_waifus_protocol::{AnimalDestroyRequest, AnimalDestroyResponse, AnimalDieRequest, AnimalDieResponse, AnimalDropRequest, AnimalDropResponse, EEntityType, ERemoveEntityType, EntityLivingStatusNotify, ErrorCode, LivingStatus}; +use wicked_waifus_protocol::{ + AnimalDestroyRequest, AnimalDestroyResponse, AnimalDieRequest, AnimalDieResponse, + AnimalDropRequest, AnimalDropResponse, EEntityType, ERemoveEntityType, + EntityLivingStatusNotify, ErrorCode, LivingStatus, +}; use crate::logic::ecs::component::ComponentContainer; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::world_util; use crate::query_components; pub fn on_animal_die_request( - player: &mut Player, + ctx: &mut NetContext, request: AnimalDieRequest, response: &mut AnimalDieResponse, ) { tracing::warn!("AnimalDieRequest not fully implemented"); - player.notify(EntityLivingStatusNotify { + ctx.player.notify(EntityLivingStatusNotify { id: request.entity_id, living_status: LivingStatus::Dead.into(), drop_vision_item: vec![], @@ -21,7 +25,7 @@ pub fn on_animal_die_request( } pub fn on_animal_drop_request( - _player: &mut Player, + _ctx: &mut NetContext, _request: AnimalDropRequest, response: &mut AnimalDropResponse, ) { @@ -32,15 +36,13 @@ pub fn on_animal_drop_request( } pub fn on_animal_destroy_request( - player: &mut Player, + ctx: &mut NetContext, request: AnimalDestroyRequest, response: &mut AnimalDestroyResponse, ) { + let entity_id = request.entity_id; { - let entity_id = request.entity_id; - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let (Some(config), ) = query_components!(world,entity_id,EntityConfig) else { + let (Some(config), ) = query_components!(ctx.world.get_world_entity(), entity_id, EntityConfig) else { response.error_code = ErrorCode::ErrAnimalEntityNotExist.into(); return; }; @@ -48,7 +50,7 @@ pub fn on_animal_destroy_request( response.error_code = ErrorCode::ErrNotAnimalEntity.into(); } } - world_util::remove_entity(player, request.entity_id, ERemoveEntityType::RemoveTypeNormal); + world_util::remove_entity(ctx, request.entity_id, ERemoveEntityType::RemoveTypeNormal); response.error_code = ErrorCode::Success.into(); } @@ -62,4 +64,4 @@ fn get_animal_reward() { // NormalItemUpdateNotify // UpdateHandBookActiveStateMapNotify // ItemRewardNotify -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/chat.rs b/wicked-waifus-game-server/src/logic/handler/chat.rs index b653d63..4e74858 100644 --- a/wicked-waifus-game-server/src/logic/handler/chat.rs +++ b/wicked-waifus-game-server/src/logic/handler/chat.rs @@ -1,17 +1,21 @@ use tracing::debug; -use wicked_waifus_protocol::{ErrorCode, PrivateChatDataRequest, PrivateChatDataResponse, PrivateChatHistoryRequest, PrivateChatHistoryResponse, PrivateChatOperateRequest, PrivateChatOperateResponse, PrivateChatOperateType, PrivateChatRequest, PrivateChatResponse}; +use wicked_waifus_protocol::{ + ErrorCode, PrivateChatDataRequest, PrivateChatDataResponse, PrivateChatHistoryRequest, + PrivateChatHistoryResponse, PrivateChatOperateRequest, PrivateChatOperateResponse, + PrivateChatOperateType, PrivateChatRequest, PrivateChatResponse, +}; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_private_chat_request( - player: &mut Player, + ctx: &mut NetContext, request: PrivateChatRequest, response: &mut PrivateChatResponse, ) { - let own_id = player.basic_info.id; + let own_id = ctx.player.basic_info.id; // TODO: Implement block and ban checks?? Ignore them for the time being - let result = player.player_chat.validate_message( + let result = ctx.player.player_chat.validate_message( own_id, request.target_uid, request.chat_content_type, @@ -19,7 +23,7 @@ pub fn on_private_chat_request( ); match result { Ok(message) => { - player.player_chat.add_message(own_id, message.clone()); + ctx.player.player_chat.add_message(own_id, message.clone()); // TODO: Check how to search a player from a different world(db search or session search) // let other_player = ...; // let other_player_message = message.clone(); @@ -37,38 +41,37 @@ pub fn on_private_chat_request( // ) // }) } - Err(error_code) => response.error_code = error_code + Err(error_code) => response.error_code = error_code, }; } pub fn on_private_chat_data_request( - _: &Player, + _: &NetContext, _: PrivateChatDataRequest, _: &mut PrivateChatDataResponse, ) { - } pub fn on_private_chat_history_request( - player: &Player, + ctx: &NetContext, request: PrivateChatHistoryRequest, response: &mut PrivateChatHistoryResponse, ) { - match player.player_chat.build_private_chat_history_content_proto( - request.target_uid, - request.start_index, - ) { + match ctx + .player + .player_chat + .build_private_chat_history_content_proto(request.target_uid, request.start_index) + { Ok(chat_history_content_proto) => { response.error_code = ErrorCode::Success.into(); response.data = Some(chat_history_content_proto) } - Err(error_code) => response.error_code = error_code + Err(error_code) => response.error_code = error_code, } } - pub fn on_private_chat_operate_request( - _player: &Player, + _ctx: &NetContext, request: PrivateChatOperateRequest, response: &mut PrivateChatOperateResponse, ) { @@ -78,7 +81,10 @@ pub fn on_private_chat_operate_request( response.error_code = ErrorCode::Success.into(); } else { // TODO: Additional checks - debug!("on_private_chat_operate_request called for unimplemented case: {:?}", request); + debug!( + "on_private_chat_operate_request called for unimplemented case: {:?}", + request + ); response.error_code = ErrorCode::Success.into(); } -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/combat.rs b/wicked-waifus-game-server/src/logic/handler/combat.rs index c7e18f2..f8be7e8 100644 --- a/wicked-waifus-game-server/src/logic/handler/combat.rs +++ b/wicked-waifus-game-server/src/logic/handler/combat.rs @@ -5,15 +5,15 @@ use wicked_waifus_protocol::combat_message::{ }; use wicked_waifus_protocol::{ AttributeChangedNotify, CombatCommon, DErrorResult, DamageExecuteRequest, - DamageExecuteResponse, EAttributeType, ERemoveEntityType, ErrorCode, - FsmConditionPassRequest, FsmConditionPassResponse, GameplayAttributeData, - PlayerBattleStateChangeNotify, SwitchRoleRequest, SwitchRoleResponse, + DamageExecuteResponse, EAttributeType, ERemoveEntityType, ErrorCode, FsmConditionPassRequest, + FsmConditionPassResponse, GameplayAttributeData, PlayerBattleStateChangeNotify, + SwitchRoleRequest, SwitchRoleResponse, }; use wicked_waifus_data::damage_data; use crate::logic::ecs::component::ComponentContainer; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::world_util; use crate::query_components; @@ -49,7 +49,7 @@ fn create_combat_notify( } pub fn on_combat_message_combat_send_pack_request( - player: &mut Player, + ctx: &mut NetContext, request: CombatSendPackRequest, response: &mut CombatSendPackResponse, ) { @@ -58,13 +58,13 @@ pub fn on_combat_message_combat_send_pack_request( if let Some(ref request_message) = request_data.message { match request_message { combat_request_data::Message::SwitchRoleRequest(ref request) => { - handle_switch_role_request(player, request_data, request, response); + handle_switch_role_request(ctx, request_data, request, response); } combat_request_data::Message::FsmConditionPassRequest(ref request) => { - handle_fsm_condition_request(player, request_data, request, response); + handle_fsm_condition_request(ctx, request_data, request, response); } combat_request_data::Message::DamageExecuteRequest(ref request) => { - handle_damage_execute_request(player, request_data, request, response); + handle_damage_execute_request(ctx, request_data, request, response); } _ => {} } @@ -75,13 +75,18 @@ pub fn on_combat_message_combat_send_pack_request( } fn handle_switch_role_request( - player: &mut Player, + ctx: &mut NetContext, combat_request: &CombatRequestData, request: &SwitchRoleRequest, response: &mut CombatSendPackResponse, ) { // Find current formation and update current role - if let Some(formation) = player.formation_list.values_mut().find(|f| f.is_current) { + if let Some(formation) = ctx + .player + .formation_list + .values_mut() + .find(|f| f.is_current) + { formation.cur_role = request.role_id; let receive_pack = response @@ -105,7 +110,7 @@ fn handle_switch_role_request( } fn handle_damage_execute_request( - player: &mut Player, + ctx: &mut NetContext, combat_request: &CombatRequestData, request: &DamageExecuteRequest, response: &mut CombatSendPackResponse, @@ -114,8 +119,7 @@ fn handle_damage_execute_request( .receive_pack_notify .get_or_insert_with(Default::default); - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); + let world = ctx.world.get_mut_world_entity(); let config_id = world.get_config_id(request.attacker_entity_id.try_into().unwrap()); let mut damage = 1; // TODO: Fix the formula with real parameters(10 field equation) if config_id.to_string().len() == 4 { @@ -160,6 +164,7 @@ fn handle_damage_execute_request( ..Default::default() }), )); + let mut entities_to_remove = Vec::new(); if let Some((value, _)) = query_components!(world, request.target_entity_id, Attribute) .0 .unwrap() @@ -185,19 +190,18 @@ fn handle_damage_execute_request( }), )); if updated_value == 0 { - world_util::remove_entity( - player, - request.target_entity_id, - ERemoveEntityType::HpIsZero, - ); + entities_to_remove.push(request.target_entity_id); } } + for entity in entities_to_remove { + world_util::remove_entity(ctx, entity, ERemoveEntityType::HpIsZero); + } response.error_code = ErrorCode::Success.into(); } fn handle_battle( - player: &mut Player, + ctx: &mut NetContext, combat_request: &CombatRequestData, response: &mut CombatSendPackResponse, condition: bool, @@ -209,15 +213,14 @@ fn handle_battle( receive_pack.data.push(create_combat_notify( combat_request.combat_common.unwrap(), combat_notify_data::Message::PlayerBattleStateChangeNotify(PlayerBattleStateChangeNotify { - player_id: player.basic_info.id, - + player_id: ctx.player.basic_info.id, in_battle: condition, }), )); } fn handle_fsm_condition_request( - player: &mut Player, + ctx: &mut NetContext, combat_request: &CombatRequestData, request: &FsmConditionPassRequest, response: &mut CombatSendPackResponse, @@ -238,5 +241,5 @@ fn handle_fsm_condition_request( }), }), )); - handle_battle(player, combat_request, response, true); + handle_battle(ctx, combat_request, response, true); } diff --git a/wicked-waifus-game-server/src/logic/handler/coop.rs b/wicked-waifus-game-server/src/logic/handler/coop.rs index 5848b4c..f40f22c 100644 --- a/wicked-waifus-game-server/src/logic/handler/coop.rs +++ b/wicked-waifus-game-server/src/logic/handler/coop.rs @@ -1,8 +1,8 @@ +use crate::logic::thread_mgr::NetContext; use wicked_waifus_protocol::{ErrorCode, LobbyListRequest, LobbyListResponse}; -use crate::logic::player::Player; pub fn on_lobby_list_request( - _player: &mut Player, + _ctx: &mut NetContext, request: LobbyListRequest, response: &mut LobbyListResponse, ) { @@ -15,4 +15,4 @@ pub fn on_lobby_list_request( } } response.error_code = ErrorCode::Success.into(); -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/dummy.rs b/wicked-waifus-game-server/src/logic/handler/dummy.rs index 8501869..d2468b3 100644 --- a/wicked-waifus-game-server/src/logic/handler/dummy.rs +++ b/wicked-waifus-game-server/src/logic/handler/dummy.rs @@ -1,4 +1,4 @@ -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; macro_rules! dummy_handler { ($($type_name:ident;)*) => { @@ -9,7 +9,7 @@ macro_rules! dummy_handler { $(::paste::paste! { pub fn []( - _player: &Player, + _ctx: &NetContext, _request: [<$type_name Request>], _response: &mut [<$type_name Response>], ) { diff --git a/wicked-waifus-game-server/src/logic/handler/entity.rs b/wicked-waifus-game-server/src/logic/handler/entity.rs index 7626be5..8207df3 100644 --- a/wicked-waifus-game-server/src/logic/handler/entity.rs +++ b/wicked-waifus-game-server/src/logic/handler/entity.rs @@ -1,24 +1,30 @@ -use wicked_waifus_protocol::{EntityAccessInfo, EntityAccessRangeRequest, EntityAccessRangeResponse, EntityActiveRequest, EntityActiveResponse, EntityFollowTrackRequest, EntityFollowTrackResponse, EntityInteractRequest, EntityInteractResponse, EntityOnLandedRequest, EntityOnLandedResponse, EntityPb, EntityPositionRequest, EntityPositionResponse, ErrorCode, GetRewardTreasureBoxRequest, GetRewardTreasureBoxResponse, MovePackagePush}; +use wicked_waifus_protocol::{ + EntityAccessInfo, EntityAccessRangeRequest, EntityAccessRangeResponse, EntityActiveRequest, + EntityActiveResponse, EntityFollowTrackRequest, EntityFollowTrackResponse, + EntityInteractRequest, EntityInteractResponse, EntityOnLandedRequest, EntityOnLandedResponse, + EntityPb, EntityPositionRequest, EntityPositionResponse, ErrorCode, + GetRewardTreasureBoxRequest, GetRewardTreasureBoxResponse, MovePackagePush, +}; use wicked_waifus_data::pb_components::option::OptionType; -use crate::{logic, logic::ecs::component::ComponentContainer, logic::player::Player, query_components}; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::action_utils::perform_action; use crate::logic::utils::condition_utils::check_condition; +use crate::{logic, logic::ecs::component::ComponentContainer, query_components}; pub fn on_entity_active_request( - player: &Player, + ctx: &NetContext, request: EntityActiveRequest, response: &mut EntityActiveResponse, ) { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); + let world = ctx.world.get_world_entity(); if !world.is_in_all_world_map(request.entity_id as i32) { tracing::debug!( "EntityActiveRequest: entity with id {} doesn't exist, player_id: {}", request.entity_id, - player.basic_info.id + ctx.player.basic_info.id ); return; }; @@ -29,17 +35,19 @@ pub fn on_entity_active_request( ..Default::default() }; - world.get_entity_components(request.entity_id as i32) + world + .get_entity_components(request.entity_id as i32) .into_iter() .for_each(|comp| comp.set_pb_data(&mut pb)); pb.component_pbs }; // TODO: Remove attribute - if let (Some(position), Some(_attribute)) = - query_components!(world, request.entity_id, Position, Attribute) + if let (Some(position), Some(_attribute), Some(visibility)) = + query_components!(world, request.entity_id, Position, Attribute, Visibility) { - response.is_visible = true; + response.is_visible = visibility.is_visible; + response.pos = Some(position.0.get_position_protobuf()); response.rot = Some(position.0.get_rotation_protobuf()); @@ -51,13 +59,12 @@ pub fn on_entity_active_request( "EntityActiveRequest: entity with id {} not found", request.entity_id ); - response.error_code = ErrorCode::ErrEntityNotFound.into(); // TODO: replace with appropriate error code - return; + response.error_code = ErrorCode::ErrEntityNotFound.into(); // TODO: replace with appropriate error code; }; } pub fn on_entity_on_landed_request( - _: &Player, + _: &NetContext, request: EntityOnLandedRequest, _: &mut EntityOnLandedResponse, ) { @@ -69,7 +76,7 @@ pub fn on_entity_on_landed_request( } pub fn on_entity_position_request( - _: &Player, + _: &NetContext, request: EntityPositionRequest, _: &mut EntityPositionResponse, ) { @@ -81,27 +88,25 @@ pub fn on_entity_position_request( ); } -pub fn on_move_package_push(player: &mut Player, push: MovePackagePush) { +pub fn on_move_package_push(ctx: &mut NetContext, push: MovePackagePush) { for moving_entity in push.moving_entities { - // Query components borrows world component so lets wrap it { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); + let world = ctx.world.get_world_entity(); if !world.is_in_all_world_map(moving_entity.entity_id as i32) { tracing::debug!( - "MovePackage: entity with id {} doesn't exist", - moving_entity.entity_id - ); + "MovePackage: entity with id {} doesn't exist", + moving_entity.entity_id + ); continue; } let Some(mut movement) = query_components!(world, moving_entity.entity_id, Movement).0 else { tracing::warn!( - "MovePackage: entity {} doesn't have movement component", - moving_entity.entity_id - ); + "MovePackage: entity {} doesn't have movement component", + moving_entity.entity_id + ); continue; }; @@ -110,24 +115,25 @@ pub fn on_move_package_push(player: &mut Player, push: MovePackagePush) { .extend(moving_entity.move_infos); } - let map = logic::utils::quadrant_util::get_map(player.basic_info.cur_map_id); + let map = logic::utils::quadrant_util::get_map(ctx.player.basic_info.cur_map_id); let quadrant_id = map.get_quadrant_id( - player.location.position.position.x * 100.0, - player.location.position.position.y * 100.0, + ctx.player.location.position.position.x * 100.0, + ctx.player.location.position.position.y * 100.0, ); // TODO: This may require some changes for Co-Op - if quadrant_id != player.quadrant_id { - let (entities_to_remove, entities_to_add) = map.get_update_entities(player.quadrant_id, quadrant_id); - player.quadrant_id = quadrant_id; - logic::utils::world_util::remove_entities(player, &entities_to_remove); - logic::utils::world_util::add_entities(player, &entities_to_add, false); + if quadrant_id != ctx.player.quadrant_id { + let (entities_to_remove, entities_to_add) = + map.get_update_entities(ctx.player.quadrant_id, quadrant_id); + ctx.player.quadrant_id = quadrant_id; + logic::utils::world_util::remove_entities(ctx, &entities_to_remove); + logic::utils::world_util::add_entities(ctx, &entities_to_add, false); } } } pub fn on_entity_access_range_request( - _: &Player, + _: &NetContext, request: EntityAccessRangeRequest, response: &mut EntityAccessRangeResponse, ) { @@ -147,26 +153,40 @@ pub fn on_entity_access_range_request( } pub fn on_entity_interact_request( - player: &mut Player, + ctx: &mut NetContext, request: EntityInteractRequest, response: &mut EntityInteractResponse, ) { - let config_id = get_config_id_from_entity_id(player, request.entity_id); - tracing::debug!("EntityInteractRequest with ID: {} and ConfigID {}", request.entity_id, config_id); + let config_id = get_config_id_from_entity_id(ctx, request.entity_id); + tracing::debug!( + "EntityInteractRequest with ID: {} and ConfigID {}", + request.entity_id, + config_id + ); // TODO: add cases outside LevelEntityConfig if exist - let Some(entity) = wicked_waifus_data::level_entity_config_data::get(player.basic_info.cur_map_id, config_id) else { + let Some(entity) = wicked_waifus_data::level_entity_config_data::get( + ctx.player.basic_info.cur_map_id, + config_id, + ) else { response.error_code = ErrorCode::ErrEntityNotFound.into(); return; }; - let Some(template_config) = wicked_waifus_data::template_config_data::get(&entity.blueprint_type) else { + let Some(template_config) = + wicked_waifus_data::template_config_data::get(&entity.blueprint_type) + else { response.error_code = ErrorCode::ErrEntityNotFound.into(); return; }; - let Some(interact_component) = entity.components_data.interact_component.as_ref() - .or(template_config.components_data.interact_component.as_ref()).cloned() else { + let Some(interact_component) = entity + .components_data + .interact_component + .as_ref() + .or(template_config.components_data.interact_component.as_ref()) + .cloned() + else { response.error_code = ErrorCode::ErrInteractComponentNotExist.into(); return; }; @@ -179,7 +199,7 @@ pub fn on_entity_interact_request( let mut check = true; if let Some(conditions) = option.condition { for element in conditions.conditions { - check = check_condition(player, request.entity_id, &entity, template_config, element); + check = check_condition(ctx, request.entity_id, entity, template_config, element); if !check { break; } @@ -190,7 +210,13 @@ pub fn on_entity_interact_request( match option_type { OptionType::Actions(actions) => { for action in actions.actions { - perform_action(player, request.entity_id, &entity, template_config, action); + perform_action( + ctx, + request.entity_id, + entity, + template_config, + action, + ); } } OptionType::Flow(_) => { @@ -206,15 +232,16 @@ pub fn on_entity_interact_request( } pub fn on_entity_follow_track_request( - player: &Player, + ctx: &mut NetContext, request: EntityFollowTrackRequest, response: &mut EntityFollowTrackResponse, ) { - let config_id = get_config_id_from_entity_id(player, request.entity_id); + let config_id = get_config_id_from_entity_id(ctx, request.entity_id); let position = { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let position = query_components!(world, request.entity_id, Position).0.unwrap(); + let world = ctx.world.get_world_entity(); + let position = query_components!(world, request.entity_id, Position) + .0 + .unwrap(); position.0.clone() }; tracing::debug!( @@ -226,17 +253,19 @@ pub fn on_entity_follow_track_request( } pub fn on_get_reward_treasure_box_request( - player: &Player, + ctx: &NetContext, request: GetRewardTreasureBoxRequest, _response: &mut GetRewardTreasureBoxResponse, ) { - let config_id = get_config_id_from_entity_id(player, request.entity_id); - tracing::debug!("GetRewardTreasureBoxRequest with ID: {} and ConfigID {config_id}", request.entity_id); + let config_id = get_config_id_from_entity_id(ctx, request.entity_id); + tracing::debug!( + "GetRewardTreasureBoxRequest with ID: {} and ConfigID {config_id}", + request.entity_id + ); } -fn get_config_id_from_entity_id(player: &Player, entity_id: i64) -> i64 { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); +fn get_config_id_from_entity_id(ctx: &NetContext, entity_id: i64) -> i64 { + let world = ctx.world.get_world_entity(); let entity_config = query_components!(world, entity_id, EntityConfig).0.unwrap(); entity_config.config_id as i64 -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/friend.rs b/wicked-waifus-game-server/src/logic/handler/friend.rs index 7c93df3..59d7380 100644 --- a/wicked-waifus-game-server/src/logic/handler/friend.rs +++ b/wicked-waifus-game-server/src/logic/handler/friend.rs @@ -1,11 +1,11 @@ -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use wicked_waifus_protocol::{ ErrorCode, FriendAllRequest, FriendAllResponse, FriendInfo, PlayerBasicInfoGetRequest, PlayerBasicInfoGetResponse, PlayerDetails, }; pub fn on_friend_all_request( - _player: &Player, + _ctx: &NetContext, _: FriendAllRequest, response: &mut FriendAllResponse, ) { @@ -23,7 +23,7 @@ pub fn on_friend_all_request( } // pub fn on_friend_apply_send_request( -// _player: &Player, +// _ctx: &NetContext, // _request: FriendApplySendRequest, // _response: &mut FriendApplySendResponse, // ) { @@ -31,7 +31,7 @@ pub fn on_friend_all_request( // } // // pub fn on_friend_recently_team_request( -// _player: &Player, +// _ctx: &NetContext, // _request: FriendRecentlyTeamRequest, // _response: &mut FriendRecentlyTeamResponse, // ) { @@ -39,7 +39,7 @@ pub fn on_friend_all_request( // } pub fn on_player_basic_info_get_request( - _player: &Player, + _ctx: &NetContext, request: PlayerBasicInfoGetRequest, response: &mut PlayerBasicInfoGetResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/gacha.rs b/wicked-waifus-game-server/src/logic/handler/gacha.rs index 8e0128e..5831eb8 100644 --- a/wicked-waifus-game-server/src/logic/handler/gacha.rs +++ b/wicked-waifus-game-server/src/logic/handler/gacha.rs @@ -2,31 +2,35 @@ use std::collections::HashMap; use std::sync::{Mutex, OnceLock}; use std::time::UNIX_EPOCH; -use wicked_waifus_data::{gacha_pool_data, gacha_view_info_data, GachaPoolData, text_map_data}; -use wicked_waifus_data::GachaViewTypeInfoId::{BeginnersChoiceConvene, NoviceConvene}; -use wicked_waifus_protocol::{ErrorCode, GachaConsume, GachaInfo, GachaInfoRequest, GachaInfoResponse, - GachaPoolInfo, GachaRequest, GachaResponse, GachaResult, GachaReward, - GachaUsePoolRequest, GachaUsePoolResponse, WeaponItem}; - use crate::logic::gacha::gacha_pool::GachaPool; use crate::logic::gacha::pool_info::PoolInfo; use crate::logic::gacha::service::GachaService; use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; +use wicked_waifus_data::gacha_pool_data::GachaPoolData; +use wicked_waifus_data::gacha_view_info_data::GachaViewTypeInfoId::{ + BeginnersChoiceConvene, NoviceConvene, +}; +use wicked_waifus_data::{gacha_pool_data, gacha_view_info_data, text_map_data}; +use wicked_waifus_protocol::{ + ErrorCode, GachaConsume, GachaInfo, GachaInfoRequest, GachaInfoResponse, GachaPoolInfo, + GachaRequest, GachaResponse, GachaResult, GachaReward, GachaUsePoolRequest, + GachaUsePoolResponse, WeaponItem, +}; static GACHA_SERVICE: OnceLock> = OnceLock::new(); -pub fn on_gacha_request( - player: &mut Player, - request: GachaRequest, - response: &mut GachaResponse, -) { - let mut gacha_service = GACHA_SERVICE.get_or_init(|| Mutex::new(GachaService::new())).lock().unwrap(); +pub fn on_gacha_request(ctx: &mut NetContext, request: GachaRequest, response: &mut GachaResponse) { + let mut gacha_service = GACHA_SERVICE + .get_or_init(|| Mutex::new(GachaService::new())) + .lock() + .unwrap(); // TODO: ensure we have enough elements before pulling - match gacha_service.pull(player, request.gacha_id, request.gacha_times) { + match gacha_service.pull(ctx.player, request.gacha_id, request.gacha_times) { Ok(results) => { - match consume_tides(player, request.gacha_id, request.gacha_times) { + match consume_tides(ctx.player, request.gacha_id, request.gacha_times) { Ok(_) => { let _summary = process_gacha_results(&results); //update_player_inventory(player, summary); @@ -48,20 +52,22 @@ pub fn on_gacha_request( } pub fn on_gacha_info_request( - _player: &Player, + _ctx: &NetContext, request: GachaInfoRequest, response: &mut GachaInfoResponse, ) { tracing::debug!("received gacha request for language: {}", request.language); let text_map = text_map_data::get_textmap(request.language); - let gacha_service = GACHA_SERVICE.get_or_init(|| Mutex::new(GachaService::new())).lock().unwrap(); + let gacha_service = GACHA_SERVICE + .get_or_init(|| Mutex::new(GachaService::new())) + .lock() + .unwrap(); let active_pools = gacha_service.get_active_pools(); - response.gacha_infos = active_pools.into_iter() - .filter_map(|(pool_id, pool)| { - create_gacha_info(pool_id, pool, text_map) - }) + response.gacha_infos = active_pools + .into_iter() + .filter_map(|(pool_id, pool)| create_gacha_info(pool_id, pool, text_map)) .collect(); response.error_code = ErrorCode::Success.into(); @@ -73,7 +79,7 @@ pub fn on_gacha_info_request( } pub fn on_gacha_use_pool_request( - _player: &Player, + _ctx: &NetContext, _request: GachaUsePoolRequest, response: &mut GachaUsePoolResponse, ) { @@ -81,9 +87,11 @@ pub fn on_gacha_use_pool_request( response.error_code = ErrorCode::Success.into(); } -fn create_gacha_info(pool_id: i32, - pool: &GachaPool, - textmap: &HashMap) -> Option { +fn create_gacha_info( + pool_id: i32, + pool: &GachaPool, + textmap: &HashMap, +) -> Option { let pools: Vec = gacha_pool_data::iter() .filter(|p| p.gacha_id == pool_id) .filter_map(|p| create_pool_info(p, &pool.info, textmap)) @@ -103,8 +111,15 @@ fn create_gacha_info(pool_id: i32, gacha_consumes, use_pool_id: pools[0].id, pools, - begin_time: pool.info.start_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64, - end_time: pool.info.end_time.map_or(0, |end_time| end_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64), + begin_time: pool + .info + .start_time + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + end_time: pool.info.end_time.map_or(0, |end_time| { + end_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64 + }), daily_limit_times: pool.info.daily_limit, total_limit_times: pool.info.total_limit, resources_id: pool.info.resources_id().to_string(), @@ -121,29 +136,51 @@ fn create_pool_info( // TODO: debug textmap logic gacha_view_info_data::iter() .find(|view| view.id == pool.id) - .map(|view| { - GachaPoolInfo { - id: pool.id, - begin_time: pool_info.start_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64, - end_time: pool_info.end_time.map_or(0, |end_time| end_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64), - title: textmap.get(&view.summary_title).unwrap_or(&view.summary_title).to_string(), - description: textmap.get(&view.summary_describe).unwrap_or(&view.summary_describe).to_string(), - ui_type: view.r#type as i32, - theme_color: view.theme_color.clone(), - show_id_list: view.show_id_list.clone(), - up_list: view.up_list.clone(), - preview_id_list: view.preview_id_list.clone(), - } + .map(|view| GachaPoolInfo { + id: pool.id, + begin_time: pool_info + .start_time + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + end_time: pool_info.end_time.map_or(0, |end_time| { + end_time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64 + }), + title: textmap + .get(&view.summary_title) + .unwrap_or(&view.summary_title) + .to_string(), + description: textmap + .get(&view.summary_describe) + .unwrap_or(&view.summary_describe) + .to_string(), + ui_type: view.r#type as i32, + theme_color: view.theme_color.clone(), + show_id_list: view.show_id_list.clone(), + up_list: view.up_list.clone(), + preview_id_list: view.preview_id_list.clone(), }) } fn handle_gacha_consumes(pool_info: &PoolInfo) -> Vec { match (pool_info.pool_type, pool_info.pool_id) { - (NoviceConvene, _) => vec![GachaConsume { times: 10, consume: 0 }], // 8 - (BeginnersChoiceConvene, 51..56) => vec![GachaConsume { times: 1, consume: 0 }], // 1, + (NoviceConvene, _) => vec![GachaConsume { + times: 10, + consume: 0, + }], // 8 + (BeginnersChoiceConvene, 51..56) => vec![GachaConsume { + times: 1, + consume: 0, + }], // 1, (_, _) => vec![ - GachaConsume { times: 1, consume: 0 }, // 1 - GachaConsume { times: 10, consume: 0 }, // 10 + GachaConsume { + times: 1, + consume: 0, + }, // 1 + GachaConsume { + times: 10, + consume: 0, + }, // 10 ], } } @@ -214,9 +251,9 @@ fn consume_tides(_player: &mut Player, pool_id: i32, pull_count: i32) -> Result< (50001, discounted_cost) } 2 | 31..=35 | 41..=45 => (50001, pull_count), // Standard, permanent weapon, and beginner character -> Lustrous Tide - 100001..=100100 => (50002, pull_count), // Character -> Radiant Tide - 200001..=200100 => (50005, pull_count), // Weapon -> Forging Tide - 51..56 => (50006, pull_count), // Special -> Voucher of Reciprocal Tides + 100001..=100100 => (50002, pull_count), // Character -> Radiant Tide + 200001..=200100 => (50005, pull_count), // Weapon -> Forging Tide + 51..56 => (50006, pull_count), // Special -> Voucher of Reciprocal Tides _ => return Err(ErrorCode::ErrGachaPoolConfigNotFound), }; @@ -228,4 +265,4 @@ fn consume_tides(_player: &mut Player, pool_id: i32, pull_count: i32) -> Result< //player.remove_item(currency_id, actual_cost); Ok(()) -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/guide.rs b/wicked-waifus-game-server/src/logic/handler/guide.rs index 6c27cbc..90a44f6 100644 --- a/wicked-waifus-game-server/src/logic/handler/guide.rs +++ b/wicked-waifus-game-server/src/logic/handler/guide.rs @@ -1,51 +1,54 @@ -use wicked_waifus_protocol::{ErrorCode, GuideFinishRequest, GuideFinishResponse, GuideInfoRequest, GuideInfoResponse, GuideTriggerRequest, GuideTriggerResponse}; - use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; +use wicked_waifus_protocol::{ + ErrorCode, GuideFinishRequest, GuideFinishResponse, GuideInfoRequest, GuideInfoResponse, + GuideTriggerRequest, GuideTriggerResponse, +}; pub fn on_guide_info_request( - player: &Player, + ctx: &NetContext, _: GuideInfoRequest, response: &mut GuideInfoResponse, ) { - response.guide_group_finish_list = player.guides.finished_guides.iter() - .cloned() - .collect(); + response.guide_group_finish_list = ctx.player.guides.finished_guides.iter().cloned().collect(); } pub fn on_guide_trigger_request( - player: &mut Player, + ctx: &mut NetContext, request: GuideTriggerRequest, response: &mut GuideTriggerResponse, ) { - response.error_code = check_if_guide_exists_and_is_repeatable(player, request.group_id); + response.error_code = check_if_guide_exists_and_is_repeatable(ctx.player, request.group_id); if response.error_code == >::into(ErrorCode::Success) { // TODO: We need to check if guide can be repeated or not // if player.guides.started_guides.contains(&request.group_id) { // response.error_code = ErrorCode::GuideGroupDoing.into(); // return; // } - player.guides.started_guides.insert(request.group_id); + ctx.player.guides.started_guides.insert(request.group_id); } } pub fn on_guide_finish_request( - player: &mut Player, + ctx: &mut NetContext, request: GuideFinishRequest, response: &mut GuideFinishResponse, ) { - response.error_code = check_if_guide_exists_and_is_repeatable(player, request.group_id); + response.error_code = check_if_guide_exists_and_is_repeatable(ctx.player, request.group_id); if response.error_code == >::into(ErrorCode::Success) { - if !player.guides.started_guides.contains(&request.group_id) { + if !ctx.player.guides.started_guides.contains(&request.group_id) { response.error_code = ErrorCode::GuideGroupNoClient.into(); return; } - player.guides.started_guides.remove(&request.group_id); - player.guides.finished_guides.insert(request.group_id); + ctx.player.guides.started_guides.remove(&request.group_id); + ctx.player.guides.finished_guides.insert(request.group_id); } } fn check_if_guide_exists_and_is_repeatable(player: &Player, guide_id: i32) -> i32 { - let Some(guide) = wicked_waifus_data::guide_group_data::iter().find(|guide| guide.id == guide_id) else { + let Some(guide) = + wicked_waifus_data::guide_group_data::iter().find(|guide| guide.id == guide_id) + else { return ErrorCode::GuideGroupIdNoMatch.into(); }; // TODO: We need to check if guide can be repeated or not @@ -53,4 +56,4 @@ fn check_if_guide_exists_and_is_repeatable(player: &Player, guide_id: i32) -> i3 return ErrorCode::GuideGroupIsNotRepeat.into(); } ErrorCode::Success.into() -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/inventory.rs b/wicked-waifus-game-server/src/logic/handler/inventory.rs index 4837ca0..155a8c2 100644 --- a/wicked-waifus-game-server/src/logic/handler/inventory.rs +++ b/wicked-waifus-game-server/src/logic/handler/inventory.rs @@ -1,35 +1,48 @@ -use wicked_waifus_protocol::{ItemExchangeInfo, ItemExchangeInfoRequest, ItemExchangeInfoResponse, NormalItemRequest, NormalItemResponse, PhantomItemRequest, PhantomItemResponse, WeaponItemRequest, WeaponItemResponse}; - -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; +use wicked_waifus_protocol::{ + ItemExchangeInfo, ItemExchangeInfoRequest, ItemExchangeInfoResponse, NormalItemRequest, + NormalItemResponse, PhantomItemRequest, PhantomItemResponse, WeaponItemRequest, + WeaponItemResponse, +}; pub fn on_normal_item_request( - player: &mut Player, + ctx: &NetContext, _: NormalItemRequest, response: &mut NormalItemResponse, ) { tracing::debug!("Received NormalItemRequest, returning player inventory"); - response.normal_item_list = player.inventory.to_normal_item_list(); + response.normal_item_list = ctx.player.inventory.to_normal_item_list(); } pub fn on_weapon_item_request( - player: &mut Player, + ctx: &NetContext, _: WeaponItemRequest, response: &mut WeaponItemResponse, ) { - response.weapon_item_list = player.inventory.to_weapon_item_list(); + response.weapon_item_list = ctx.player.inventory.to_weapon_item_list(); } pub fn on_phantom_item_request( - _player: &mut Player, + ctx: &mut NetContext, _: PhantomItemRequest, - _response: &mut PhantomItemResponse, + response: &mut PhantomItemResponse, ) { - // TODO: Implement this - tracing::warn!("Unhandled PhantomItemRequest"); + let (items, equip_info, prop_info) = ctx.player.inventory.get_echoes_list(); + response.phantom_item_list = items; + response.equip_info_list = equip_info; + response.ows = prop_info; + response.max_cost = 8; // TODO: Max cost from calabash + response.phantom_skin_list = ctx + .player + .unlocked_skins + .echo_skins + .iter() + .copied() + .collect(); } pub fn on_item_exchange_info_request( - _player: &mut Player, + _ctx: &mut NetContext, _: ItemExchangeInfoRequest, response: &mut ItemExchangeInfoResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/lord_gym.rs b/wicked-waifus-game-server/src/logic/handler/lord_gym.rs index 0e84f26..ebdf782 100644 --- a/wicked-waifus-game-server/src/logic/handler/lord_gym.rs +++ b/wicked-waifus-game-server/src/logic/handler/lord_gym.rs @@ -1,9 +1,9 @@ use wicked_waifus_protocol::{LordGymInfoRequest, LordGymInfoResponse}; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_lord_gym_info_request( - _player: &Player, + _ctx: &NetContext, request: LordGymInfoRequest, _response: &mut LordGymInfoResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/mail.rs b/wicked-waifus-game-server/src/logic/handler/mail.rs index 4116f25..c066594 100644 --- a/wicked-waifus-game-server/src/logic/handler/mail.rs +++ b/wicked-waifus-game-server/src/logic/handler/mail.rs @@ -1,9 +1,9 @@ use wicked_waifus_protocol::{MailBind, MailBindInfoRequest, MailBindInfoResponse}; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_mail_bind_info_request( - _: &Player, + _: &NetContext, _: MailBindInfoRequest, response: &mut MailBindInfoResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/map.rs b/wicked-waifus-game-server/src/logic/handler/map.rs index f5b1094..9355bf1 100644 --- a/wicked-waifus-game-server/src/logic/handler/map.rs +++ b/wicked-waifus-game-server/src/logic/handler/map.rs @@ -6,10 +6,10 @@ use wicked_waifus_protocol::{ PlayerAccessEffectAreaResponse, }; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_dark_coast_delivery_request( - _player: &mut Player, + _ctx: &mut NetContext, request: DarkCoastDeliveryRequest, response: &mut DarkCoastDeliveryResponse, ) { @@ -40,36 +40,36 @@ pub fn on_dark_coast_delivery_request( } pub fn on_map_cancel_trace_request( - player: &mut Player, + ctx: &mut NetContext, request: MapCancelTraceRequest, response: &mut MapCancelTraceResponse, ) { - player.map_trace.traces.remove(&request.mark_id); + ctx.player.map_trace.traces.remove(&request.mark_id); response.mark_id = request.mark_id; response.error_code = ErrorCode::Success.into(); } pub fn on_map_trace_request( - player: &mut Player, + ctx: &mut NetContext, request: MapTraceRequest, response: &mut MapTraceResponse, ) { - player.map_trace.traces.insert(request.mark_id); + ctx.player.map_trace.traces.insert(request.mark_id); response.mark_id = request.mark_id; response.error_code = ErrorCode::Success.into(); } pub fn on_map_trace_info_request( - player: &Player, + ctx: &NetContext, _: MapTraceInfoRequest, response: &mut MapTraceInfoResponse, ) { - response.mark_id_list = player.map_trace.traces.iter().cloned().collect(); + response.mark_id_list = ctx.player.map_trace.traces.iter().cloned().collect(); response.error_code = ErrorCode::Success.into(); } pub fn on_map_unlock_field_info_request( - _player: &mut Player, + _ctx: &NetContext, _: MapUnlockFieldInfoRequest, response: &mut MapUnlockFieldInfoResponse, ) { @@ -81,7 +81,7 @@ pub fn on_map_unlock_field_info_request( } pub fn on_player_access_effect_area_request( - _player: &Player, + _ctx: &NetContext, request: PlayerAccessEffectAreaRequest, response: &mut PlayerAccessEffectAreaResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/misc.rs b/wicked-waifus-game-server/src/logic/handler/misc.rs index a56eff0..d605a11 100644 --- a/wicked-waifus-game-server/src/logic/handler/misc.rs +++ b/wicked-waifus-game-server/src/logic/handler/misc.rs @@ -1,28 +1,32 @@ -use wicked_waifus_protocol::{ErrorCode, InputSettingRequest, InputSettingResponse, InputSettingUpdateRequest, InputSettingUpdateResponse, LanguageSettingUpdateRequest, LanguageSettingUpdateResponse, MonthCardRequest, MonthCardResponse, ServerPlayStationPlayOnlyStateRequest, ServerPlayStationPlayOnlyStateResponse, UpdateVoxelEnvRequest, UpdateVoxelEnvResponse, VersionInfoPush, WebSignRequest, WebSignResponse, Zih}; +use wicked_waifus_protocol::{ + ErrorCode, InputSettingRequest, InputSettingResponse, InputSettingUpdateRequest, + InputSettingUpdateResponse, LanguageSettingUpdateRequest, LanguageSettingUpdateResponse, + MonthCardRequest, MonthCardResponse, ServerPlayStationPlayOnlyStateRequest, + ServerPlayStationPlayOnlyStateResponse, UpdateVoxelEnvRequest, UpdateVoxelEnvResponse, + VersionInfoPush, WebSignRequest, WebSignResponse, Zih, +}; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_month_card_request( - player: &mut Player, + ctx: &mut NetContext, _: MonthCardRequest, response: &mut MonthCardResponse, ) { // TODO: Check if we should send MonthCardUseNotify - response.days = player.month_card.days; - response.is_daily_got = wicked_waifus_commons::time_util::unix_days() == player.month_card.last_received_day; + response.days = ctx.player.month_card.days; + response.is_daily_got = + wicked_waifus_commons::time_util::unix_days() == ctx.player.month_card.last_received_day; response.error_code = ErrorCode::Success.into(); } -pub fn on_web_sign_request( - _: &mut Player, - _: WebSignRequest, - response: &mut WebSignResponse, -) { - response.notice_sign = "Welcome to Wicked Waifus PS provided by Reversed Rooms Dev Team".to_string(); +pub fn on_web_sign_request(_: &mut NetContext, _: WebSignRequest, response: &mut WebSignResponse) { + response.notice_sign = + "Welcome to Wicked Waifus PS provided by Reversed Rooms Dev Team".to_string(); } pub fn on_input_setting_request( - _: &Player, + _: &NetContext, _: InputSettingRequest, response: &mut InputSettingResponse, ) { @@ -30,7 +34,7 @@ pub fn on_input_setting_request( } pub fn on_input_setting_update_request( - _: &Player, + _: &NetContext, _: InputSettingUpdateRequest, response: &mut InputSettingUpdateResponse, ) { @@ -38,7 +42,7 @@ pub fn on_input_setting_update_request( } pub fn on_language_setting_update_request( - _: &Player, + _: &NetContext, _: LanguageSettingUpdateRequest, response: &mut LanguageSettingUpdateResponse, ) { @@ -46,14 +50,14 @@ pub fn on_language_setting_update_request( } pub fn on_server_play_station_play_only_state_request( - _: &Player, + _: &NetContext, _: ServerPlayStationPlayOnlyStateRequest, response: &mut ServerPlayStationPlayOnlyStateResponse, ) { response.cross_play_enabled = false; } -pub fn on_version_info_push(_player: &Player, push: VersionInfoPush) { +pub fn on_version_info_push(_player: &NetContext, push: VersionInfoPush) { // TODO: Shall we do safety check and ensure we have compatible versions? tracing::debug!( "Client versions: launcher: {}, app: {}, resources: {}", @@ -64,7 +68,7 @@ pub fn on_version_info_push(_player: &Player, push: VersionInfoPush) { } pub fn on_update_voxel_env_request( - _: &Player, + _: &NetContext, request: UpdateVoxelEnvRequest, response: &mut UpdateVoxelEnvResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/mod.rs b/wicked-waifus-game-server/src/logic/handler/mod.rs index 2fd2085..65db536 100644 --- a/wicked-waifus-game-server/src/logic/handler/mod.rs +++ b/wicked-waifus-game-server/src/logic/handler/mod.rs @@ -45,7 +45,7 @@ mod weapon; macro_rules! handle_request { ($($name:ident $(, $inner_package:ident)?;)*) => { - fn handle_request(player: &mut super::player::Player, mut msg: Message) { + fn handle_request(ctx: &mut super::thread_mgr::NetContext, mut msg: Message) { use ::wicked_waifus_protocol::{MessageID, Protobuf}; ::paste::paste! { @@ -53,16 +53,16 @@ macro_rules! handle_request { $( ::wicked_waifus_protocol::$($inner_package::)?[<$name Request>]::MESSAGE_ID => { let Ok(request) = ::wicked_waifus_protocol::$($inner_package::)?[<$name Request>]::decode(&*msg.remove_payload()) else { - tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Request>]), player.basic_info.id); + tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Request>]), ctx.player.basic_info.id); return; }; tracing::debug!("logic: processing request {}", stringify!($($inner_package::)?[<$name Request>])); let mut response = ::wicked_waifus_protocol::$($inner_package::)?[<$name Response>]::default(); - [](player, request, &mut response); + [](ctx, request, &mut response); - player.respond(response, msg.get_rpc_id()); + ctx.player.respond(response, msg.get_rpc_id()); }, )* unhandled => { @@ -81,7 +81,7 @@ macro_rules! handle_request { macro_rules! handle_push { ($($name:ident $(, $inner_package:ident)?;)*) => { - fn handle_push(player: &mut super::player::Player, mut msg: Message) { + fn handle_push(ctx: &mut super::thread_mgr::NetContext, mut msg: Message) { use ::wicked_waifus_protocol::{MessageID, Protobuf}; ::paste::paste! { @@ -89,13 +89,13 @@ macro_rules! handle_push { $( ::wicked_waifus_protocol::$($inner_package::)?[<$name Push>]::MESSAGE_ID => { let Ok(push) = ::wicked_waifus_protocol::$($inner_package::)?[<$name Push>]::decode(&*msg.remove_payload()) else { - tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Push>]), player.basic_info.id); + tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Push>]), ctx.player.basic_info.id); return; }; tracing::debug!("logic: processing push {}", stringify!($($inner_package::)?[<$name Push>])); - [](player, push); + [](ctx, push); }, )* unhandled => { @@ -297,15 +297,15 @@ handle_push! { VersionInfo; } -pub fn handle_logic_message(player: &mut super::player::Player, msg: Message) { +pub fn handle_logic_message(ctx: &mut super::thread_mgr::NetContext, msg: Message) { match msg { - Message::Request { .. } => handle_request(player, msg), - Message::Push { .. } => handle_push(player, msg), + Message::Request { .. } => handle_request(ctx, msg), + Message::Push { .. } => handle_push(ctx, msg), _ => tracing::warn!( "handle_logic_message: wrong message type: {}, message_id: {}, player_id: {}", msg.get_message_type(), msg.get_message_id(), - player.basic_info.id, + ctx.player.basic_info.id, ), } } diff --git a/wicked-waifus-game-server/src/logic/handler/role.rs b/wicked-waifus-game-server/src/logic/handler/role.rs index 0e2688c..65f96fc 100644 --- a/wicked-waifus-game-server/src/logic/handler/role.rs +++ b/wicked-waifus-game-server/src/logic/handler/role.rs @@ -2,21 +2,35 @@ use std::collections::HashSet; use crate::logic::components::{ParaglidingSkin, RoleSkin, SoarWingSkin, WeaponSkin}; use crate::logic::ecs::component::ComponentContainer; -use crate::logic::player::{ItemUsage, Player}; +use crate::logic::player::ItemUsage; use crate::logic::role::{Role, RoleFormation}; +use crate::logic::thread_mgr::NetContext; use crate::modify_component; -use wicked_waifus_protocol::{ArrayIntInt, ClientCurrentRoleReportRequest, ClientCurrentRoleReportResponse, ERemoveEntityType, EntityAddNotify, EntityEquipSkinChangeNotify, EntityFlySkinChangeData, EntityPb, EntityRemoveInfo, EntityRemoveNotify, EquipFlySkinData, ErrorCode, FlySkinConfigData, FlySkinWearAllRoleRequest, FlySkinWearAllRoleResponse, FlySkinWearRequest, FlySkinWearResponse, FormationAttrRequest, FormationAttrResponse, PbUpLevelRoleRequest, PbUpLevelRoleResponse, PlayerMotionRequest, PlayerMotionResponse, RoleBreakThroughViewRequest, RoleBreakThroughViewResponse, RoleFavorListRequest, RoleFavorListResponse, RoleFlyEquipChangeNotify, RoleLevelUpViewRequest, RoleLevelUpViewResponse, RoleShowListUpdateRequest, RoleShowListUpdateResponse, RoleSkinChangeRequest, RoleSkinChangeResponse, SoarWingOrParaglidingSkinChangeNotify, UnlockRoleSkinListRequest, UnlockRoleSkinListResponse, UpdateFormationRequest, UpdateFormationResponse, WeaponSkinComponentPb}; +use wicked_waifus_protocol::{ + ArrayIntInt, ClientCurrentRoleReportRequest, ClientCurrentRoleReportResponse, + ERemoveEntityType, EntityAddNotify, EntityEquipSkinChangeNotify, EntityFlySkinChangeData, + EntityPb, EntityRemoveInfo, EntityRemoveNotify, EquipFlySkinData, ErrorCode, FlySkinConfigData, + FlySkinWearAllRoleRequest, FlySkinWearAllRoleResponse, FlySkinWearRequest, FlySkinWearResponse, + FormationAttrRequest, FormationAttrResponse, PbUpLevelRoleRequest, PbUpLevelRoleResponse, + PlayerMotionRequest, PlayerMotionResponse, RoleBreakThroughViewRequest, + RoleBreakThroughViewResponse, RoleFavorListRequest, RoleFavorListResponse, + RoleFlyEquipChangeNotify, RoleLevelUpViewRequest, RoleLevelUpViewResponse, + RoleShowListUpdateRequest, RoleShowListUpdateResponse, RoleSkinChangeRequest, + RoleSkinChangeResponse, SoarWingOrParaglidingSkinChangeNotify, UnlockRoleSkinListRequest, + UnlockRoleSkinListResponse, UpdateFormationRequest, UpdateFormationResponse, + WeaponSkinComponentPb, +}; pub fn on_role_show_list_update_request( - player: &mut Player, + ctx: &mut NetContext, request: RoleShowListUpdateRequest, response: &mut RoleShowListUpdateResponse, ) { - let role_ids: HashSet = player.role_list.keys().cloned().collect(); + let role_ids: HashSet = ctx.player.role_list.keys().cloned().collect(); let all_exist = request.role_list.iter().all(|id| role_ids.contains(id)); if all_exist { - player.basic_info.role_show_list = request.role_list; + ctx.player.basic_info.role_show_list = request.role_list; response.error_code = ErrorCode::Success.into(); } else { response.error_code = ErrorCode::InvalidRequest.into(); // TODO: replace with appropriate error code @@ -24,7 +38,7 @@ pub fn on_role_show_list_update_request( } pub fn on_client_current_role_report_request( - _player: &Player, + _ctx: &NetContext, request: ClientCurrentRoleReportRequest, response: &mut ClientCurrentRoleReportResponse, ) { @@ -33,7 +47,7 @@ pub fn on_client_current_role_report_request( } pub fn on_role_favor_list_request( - _player: &Player, + _ctx: &NetContext, _request: RoleFavorListRequest, response: &mut RoleFavorListResponse, ) { @@ -42,7 +56,7 @@ pub fn on_role_favor_list_request( } pub fn on_formation_attr_request( - _player: &Player, + _ctx: &NetContext, _request: FormationAttrRequest, response: &mut FormationAttrResponse, ) { @@ -50,12 +64,11 @@ pub fn on_formation_attr_request( } pub fn on_update_formation_request( - player: &mut Player, + ctx: &mut NetContext, request: UpdateFormationRequest, response: &mut UpdateFormationResponse, ) { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); + let world = ctx.world.get_mut_world_entity(); for formation in request.formations { let formation_id = formation.formation_id; @@ -64,11 +77,12 @@ pub fn on_update_formation_request( if is_current { // update player current formation id - player.cur_formation_id = formation_id; + ctx.player.cur_formation_id = formation_id; // search old formation id and set real_formation_id, set is_current to false let mut real_formation_id = formation_id; - if let Some(rf) = player + if let Some(rf) = ctx + .player .formation_list .values_mut() .find(|rf| rf.is_current && rf.id != formation_id) @@ -77,7 +91,7 @@ pub fn on_update_formation_request( rf.is_current = false; } - if let Some(old_formation) = player.formation_list.get(&real_formation_id) { + if let Some(old_formation) = ctx.player.formation_list.get(&real_formation_id) { let removed_entities: Vec = old_formation .role_ids .iter() @@ -86,39 +100,44 @@ pub fn on_update_formation_request( removed_entities.iter().for_each(|&entity_id| { world.remove_entity(entity_id as i32); }); - player.notify(player.build_player_entity_remove_notify( - removed_entities, - ERemoveEntityType::RemoveTypeNormal, - )); + ctx.player + .notify(ctx.player.build_player_entity_remove_notify( + removed_entities, + ERemoveEntityType::RemoveTypeNormal, + )); } - let added_roles: Vec = formation + let added_roles: Vec<&Role> = formation .role_ids .iter() - .map(|&role_id| Role::new(role_id)) + .map(|role_id| ctx.player.role_list.get(role_id).unwrap()) .collect(); if !added_roles.is_empty() { // add new roles - player.notify(player.build_player_entity_add_notify(added_roles, world)); + ctx.player.notify( + ctx.player + .build_player_entity_add_notify(added_roles, world), + ); } // send update group formation notify - player.notify(player.build_update_group_formation_notify( - RoleFormation { - id: formation_id, - cur_role, - role_ids: formation.role_ids.clone(), - is_current, - }, - world, - )); + ctx.player + .notify(ctx.player.build_update_group_formation_notify( + RoleFormation { + id: formation_id, + cur_role, + role_ids: formation.role_ids.clone(), + is_current, + }, + world, + )); response.formation = Some(formation.clone()); } // update all formation and check formation_list - player + ctx.player .formation_list .entry(formation_id) .and_modify(|r| { @@ -134,13 +153,14 @@ pub fn on_update_formation_request( }); } - player.notify(player.build_update_formation_notify()); + ctx.player + .notify(ctx.player.build_update_formation_notify()); response.error_code = ErrorCode::Success.into(); } pub fn on_player_motion_request( - _: &Player, + _: &NetContext, request: PlayerMotionRequest, response: &mut PlayerMotionResponse, ) { @@ -151,20 +171,20 @@ pub fn on_player_motion_request( } pub fn on_unlock_role_skin_list_request( - player: &Player, + ctx: &NetContext, _request: UnlockRoleSkinListRequest, response: &mut UnlockRoleSkinListResponse, ) { - response.role_skin_list = player.unlocked_skins.role_skins.iter().cloned().collect(); + response.role_skin_list = ctx.player.unlocked_skins.role_skins.iter().cloned().collect(); } pub fn on_role_skin_change_request( - player: &mut Player, + ctx: &mut NetContext, request: RoleSkinChangeRequest, response: &mut RoleSkinChangeResponse, ) { // TODO: Should we verify role id first against bindata? - let role = player.role_list.get_mut(&request.role_id); + let role = ctx.player.role_list.get_mut(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; @@ -179,7 +199,7 @@ pub fn on_role_skin_change_request( }; // Verify Skin is unlocked - if !player.unlocked_skins.role_skins.contains(&skin_data.id) { + if !ctx.player.unlocked_skins.role_skins.contains(&skin_data.id) { response.error_code = ErrorCode::ErrRoleSkinLocked.into(); return; } @@ -198,67 +218,67 @@ pub fn on_role_skin_change_request( } role.weapon_skin_id = skin_data.suit_weapon_skin_id; } - { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let entity_id = world.get_entity_id(request.role_id); + + let world = ctx.world.get_world_entity(); + let entity_id = world.get_entity_id(request.role_id); + modify_component!( + world.get_entity_components(entity_id as i32), + RoleSkin, + |skin_component: &mut RoleSkin| { + skin_component.skin_id = role.skin_id; + } + ); + if request.is_wear_weapon_skin { + // Check for suit_weapon_skin_id == 0 has already been done modify_component!( world.get_entity_components(entity_id as i32), - RoleSkin, - |skin_component: &mut RoleSkin| { - skin_component.skin_id = role.skin_id; + WeaponSkin, + |skin_component: &mut WeaponSkin| { + skin_component.skin_id = skin_data.suit_weapon_skin_id; } ); - if request.is_wear_weapon_skin { - // Check for suit_weapon_skin_id == 0 has already been done - modify_component!( - world.get_entity_components(entity_id as i32), - WeaponSkin, - |skin_component: &mut WeaponSkin| { - skin_component.skin_id = skin_data.suit_weapon_skin_id; - } - ); - // Since the whole entity is recreated this shouldn't be needed but meh, whatever - player.notify(EntityEquipSkinChangeNotify { - entity_id, - weapon_skin_component_pb: Some(WeaponSkinComponentPb { - weapon_skin_id:skin_data.suit_weapon_skin_id, - }), - }); - } - player.notify(EntityRemoveNotify { - remove_infos: vec![EntityRemoveInfo { - entity_id, - r#type: 0, - }], - is_remove: false, - }); - - let mut pb = EntityPb { - id: entity_id, - ..Default::default() - }; - - world - .get_entity_components(entity_id as i32) - .into_iter() - .for_each(|comp| comp.set_pb_data(&mut pb)); - - player.notify(EntityAddNotify { - entity_pbs: vec![pb], - remove_tag_ids: false, + // Since the whole entity is recreated this shouldn't be needed but meh, whatever + ctx.player.notify(EntityEquipSkinChangeNotify { + entity_id, + weapon_skin_component_pb: Some(WeaponSkinComponentPb { + weapon_skin_id: skin_data.suit_weapon_skin_id, + }), }); } - player.notify(player.build_update_formation_notify()); + ctx.player.notify(EntityRemoveNotify { + remove_infos: vec![EntityRemoveInfo { + entity_id, + r#type: 0, + }], + is_remove: false, + }); + + let mut pb = EntityPb { + id: entity_id, + ..Default::default() + }; + + world + .get_entity_components(entity_id as i32) + .into_iter() + .for_each(|comp| comp.set_pb_data(&mut pb)); + + ctx.player.notify(EntityAddNotify { + entity_pbs: vec![pb], + remove_tag_ids: false, + }); + // player.notify(player.build_update_group_formation_notify(aaa, world)); + ctx.player + .notify(ctx.player.build_update_formation_notify()); response.error_code = ErrorCode::Success.into(); } pub fn on_fly_skin_wear_request( - player: &mut Player, + ctx: &mut NetContext, request: FlySkinWearRequest, response: &mut FlySkinWearResponse, ) { - let role = player.role_list.get_mut(&request.role_id); + let role = ctx.player.role_list.get_mut(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; @@ -275,14 +295,14 @@ pub fn on_fly_skin_wear_request( match skin.skin_type { 0 => { // Verify Skin is unlocked - if !player.unlocked_skins.fly_skins.contains(&skin.id) { + if !ctx.player.unlocked_skins.fly_skins.contains(&skin.id) { response.error_code = ErrorCode::ErrRoleSkinLocked.into(); return; } role.fly_skin_id = request.skin_id } 1 => { - if !player.unlocked_skins.wing_skins.contains(&skin.id) { + if !ctx.player.unlocked_skins.wing_skins.contains(&skin.id) { response.error_code = ErrorCode::ErrRoleSkinLocked.into(); return; } @@ -293,43 +313,40 @@ pub fn on_fly_skin_wear_request( return; } } - { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let entity_id = world.get_entity_id(request.role_id); - match skin.skin_type { - 0 => { - modify_component!( - world.get_entity_components(entity_id as i32), - SoarWingSkin, - |skin_component: &mut SoarWingSkin| { - skin_component.skin_id = role.skin_id; - } - ); - } - 1 => { - modify_component!( - world.get_entity_components(entity_id as i32), - ParaglidingSkin, - |skin_component: &mut ParaglidingSkin| { - skin_component.skin_id = role.skin_id; - } - ); - } - _ => unreachable!("Already tested above"), + let world = ctx.world.get_world_entity(); + let entity_id = world.get_entity_id(request.role_id); + match skin.skin_type { + 0 => { + modify_component!( + world.get_entity_components(entity_id as i32), + SoarWingSkin, + |skin_component: &mut SoarWingSkin| { + skin_component.skin_id = role.skin_id; + } + ); } - player.notify(SoarWingOrParaglidingSkinChangeNotify { - fly_skin_data: vec![EntityFlySkinChangeData { - entity_id, - fly_skin_config_data: vec![FlySkinConfigData { - skin_id: request.skin_id, - fly_skin_id: skin.skin_type, - }], - }], - }); + 1 => { + modify_component!( + world.get_entity_components(entity_id as i32), + ParaglidingSkin, + |skin_component: &mut ParaglidingSkin| { + skin_component.skin_id = role.skin_id; + } + ); + } + _ => unreachable!("Already tested above"), } + ctx.player.notify(SoarWingOrParaglidingSkinChangeNotify { + fly_skin_data: vec![EntityFlySkinChangeData { + entity_id, + fly_skin_config_data: vec![FlySkinConfigData { + skin_id: request.skin_id, + fly_skin_id: skin.skin_type, + }], + }], + }); - player.notify(RoleFlyEquipChangeNotify { + ctx.player.notify(RoleFlyEquipChangeNotify { fly_skin_data: vec![EquipFlySkinData { role_id: request.role_id, skin_id: request.skin_id, @@ -339,7 +356,7 @@ pub fn on_fly_skin_wear_request( } pub fn on_fly_skin_wear_all_role_request( - player: &mut Player, + ctx: &mut NetContext, request: FlySkinWearAllRoleRequest, response: &mut FlySkinWearAllRoleResponse, ) { @@ -353,20 +370,20 @@ pub fn on_fly_skin_wear_all_role_request( match skin.skin_type { 0 => { // Verify Skin is unlocked - if !player.unlocked_skins.fly_skins.contains(&skin.id) { + if !ctx.player.unlocked_skins.fly_skins.contains(&skin.id) { response.error_code = ErrorCode::ErrRoleSkinLocked.into(); return; } - for role in player.role_list.values_mut() { + for role in ctx.player.role_list.values_mut() { role.fly_skin_id = request.skin_id; } } 1 => { - if !player.unlocked_skins.wing_skins.contains(&skin.id) { + if !ctx.player.unlocked_skins.wing_skins.contains(&skin.id) { response.error_code = ErrorCode::ErrRoleSkinLocked.into(); return; } - for role in player.role_list.values_mut() { + for role in ctx.player.role_list.values_mut() { role.wing_skin_id = request.skin_id; } } @@ -375,8 +392,9 @@ pub fn on_fly_skin_wear_all_role_request( return; } } - player.notify(RoleFlyEquipChangeNotify { - fly_skin_data: player + ctx.player.notify(RoleFlyEquipChangeNotify { + fly_skin_data: ctx + .player .role_list .values() .map(|r| EquipFlySkinData { @@ -385,61 +403,59 @@ pub fn on_fly_skin_wear_all_role_request( }) .collect::>(), }); - { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let data = player - .role_list - .values() - .filter_map(|role| { - let entity_id = world.get_entity_id(role.role_id); - if entity_id == -1 { - None - } else { - match skin.skin_type { - 0 => { - modify_component!( - world.get_entity_components(entity_id as i32), - SoarWingSkin, - |skin_component: &mut SoarWingSkin| { - skin_component.skin_id = role.skin_id; - } - ); - } - 1 => { - modify_component!( - world.get_entity_components(entity_id as i32), - ParaglidingSkin, - |skin_component: &mut ParaglidingSkin| { - skin_component.skin_id = role.skin_id; - } - ); - } - _ => unreachable!("Already tested above"), + let world = ctx.world.get_world_entity(); + let data = ctx + .player + .role_list + .values() + .filter_map(|role| { + let entity_id = world.get_entity_id(role.role_id); + if entity_id == -1 { + None + } else { + match skin.skin_type { + 0 => { + modify_component!( + world.get_entity_components(entity_id as i32), + SoarWingSkin, + |skin_component: &mut SoarWingSkin| { + skin_component.skin_id = role.skin_id; + } + ); } - Some(EntityFlySkinChangeData { - entity_id, - fly_skin_config_data: vec![FlySkinConfigData { - skin_id: request.skin_id, - fly_skin_id: skin.skin_type, - }], - }) + 1 => { + modify_component!( + world.get_entity_components(entity_id as i32), + ParaglidingSkin, + |skin_component: &mut ParaglidingSkin| { + skin_component.skin_id = role.skin_id; + } + ); + } + _ => unreachable!("Already tested above"), } - }) - .collect::>(); - player.notify(SoarWingOrParaglidingSkinChangeNotify { - fly_skin_data: data, - }); - } + Some(EntityFlySkinChangeData { + entity_id, + fly_skin_config_data: vec![FlySkinConfigData { + skin_id: request.skin_id, + fly_skin_id: skin.skin_type, + }], + }) + } + }) + .collect::>(); + ctx.player.notify(SoarWingOrParaglidingSkinChangeNotify { + fly_skin_data: data, + }); response.error_code = ErrorCode::Success.into(); } pub fn on_role_level_up_view_request( - player: &mut Player, + ctx: &mut NetContext, request: RoleLevelUpViewRequest, response: &mut RoleLevelUpViewResponse, ) { - let role = player.role_list.get(&request.role_id); + let role = ctx.player.role_list.get(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; @@ -454,24 +470,24 @@ pub fn on_role_level_up_view_request( let items = wicked_waifus_data::role_exp_item_data::iter() .map(|(&id, _)| id) .collect::>(); - response.item_list = player.inventory.to_array_int_int_filtered(&items); + response.item_list = ctx.player.inventory.to_array_int_int_filtered(&items); response.error_code = ErrorCode::Success.into(); } pub fn on_pb_up_level_role_request( - player: &mut Player, + ctx: &mut NetContext, request: PbUpLevelRoleRequest, response: &mut PbUpLevelRoleResponse, ) { response.role_id = request.role_id; - let role = player.role_list.get(&request.role_id); + let role = ctx.player.role_list.get(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; }; // TODO: no shell_credit??? :turtle_skull: - let items = player.inventory.consume_items( + let items = ctx.player.inventory.consume_items( &request .item_list .iter() @@ -525,11 +541,11 @@ pub fn on_pb_up_level_role_request( // on_role_break_through_view_request pub fn on_role_break_through_view_request( - player: &mut Player, + ctx: &mut NetContext, request: RoleBreakThroughViewRequest, response: &mut RoleBreakThroughViewResponse, ) { - let role = player.role_list.get(&request.role_id); + let role = ctx.player.role_list.get(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; diff --git a/wicked-waifus-game-server/src/logic/handler/scene.rs b/wicked-waifus-game-server/src/logic/handler/scene.rs index de6cda2..bbaddf5 100644 --- a/wicked-waifus-game-server/src/logic/handler/scene.rs +++ b/wicked-waifus-game-server/src/logic/handler/scene.rs @@ -10,10 +10,10 @@ const UID_FIX: &str = include_str!("../../../scripts/uidfix.js"); const CENSORSHIP_FIX: &str = include_str!("../../../scripts/censorshipfix.js"); const DEBUG_DISABLE: &str = include_str!("../../../scripts/debug_disable.js"); -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_scene_trace_request( - _player: &Player, + _ctx: &NetContext, request: SceneTraceRequest, _: &mut SceneTraceResponse, ) { @@ -21,22 +21,22 @@ pub fn on_scene_trace_request( } pub fn on_scene_loading_finish_request( - player: &Player, + ctx: &NetContext, _request: SceneLoadingFinishRequest, response: &mut SceneLoadingFinishResponse, ) { - player.notify(JsPatchNotify { + ctx.player.notify(JsPatchNotify { content: WATER_MASK.to_string(), }); - player.notify(JsPatchNotify { + ctx.player.notify(JsPatchNotify { content: UID_FIX - .replace("{PLAYER_USERNAME}", &player.basic_info.name) + .replace("{PLAYER_USERNAME}", &ctx.player.basic_info.name) .replace("{SELECTED_COLOR}", "50FC71"), }); - player.notify(JsPatchNotify { + ctx.player.notify(JsPatchNotify { content: CENSORSHIP_FIX.to_string(), }); - player.notify(JsPatchNotify { + ctx.player.notify(JsPatchNotify { content: DEBUG_DISABLE.to_string(), }); @@ -45,7 +45,7 @@ pub fn on_scene_loading_finish_request( } pub fn on_update_scene_date_request( - _player: &Player, + _ctx: &NetContext, _request: UpdateSceneDateRequest, response: &mut UpdateSceneDateResponse, ) { @@ -54,7 +54,7 @@ pub fn on_update_scene_date_request( } pub fn on_access_path_time_server_config_request( - _player: &Player, + _ctx: &NetContext, _request: AccessPathTimeServerConfigRequest, response: &mut AccessPathTimeServerConfigResponse, ) { @@ -63,7 +63,7 @@ pub fn on_access_path_time_server_config_request( } pub fn on_player_head_data_request( - _player: &Player, + _ctx: &NetContext, _request: PlayerHeadDataRequest, response: &mut PlayerHeadDataResponse, ) { diff --git a/wicked-waifus-game-server/src/logic/handler/skill.rs b/wicked-waifus-game-server/src/logic/handler/skill.rs index 244a092..fcdfe9c 100644 --- a/wicked-waifus-game-server/src/logic/handler/skill.rs +++ b/wicked-waifus-game-server/src/logic/handler/skill.rs @@ -1,23 +1,26 @@ use crate::logic::ecs::component::ComponentContainer; -use wicked_waifus_protocol::{ErrorCode, ExploreSkillRouletteSetRequest, ExploreSkillRouletteSetResponse, VisionExploreSkillSetRequest, VisionExploreSkillSetResponse, VisionSkillChangeNotify, VisionSkillInformation}; +use wicked_waifus_protocol::{ + ErrorCode, ExploreSkillRouletteSetRequest, ExploreSkillRouletteSetResponse, + VisionExploreSkillSetRequest, VisionExploreSkillSetResponse, VisionSkillChangeNotify, + VisionSkillInformation, +}; -use crate::{logic::player::Player, query_with}; +use crate::logic::thread_mgr::NetContext; +use crate::query_with; pub fn on_vision_explore_skill_set_request( - player: &mut Player, + ctx: &mut NetContext, request: VisionExploreSkillSetRequest, response: &mut VisionExploreSkillSetResponse, ) { - player.explore_tools.active_explore_skill = request.skill_id; + ctx.player.explore_tools.active_explore_skill = request.skill_id; - for (entity, owner, mut vision_skill) in query_with!( - player.world.borrow().get_world_entity(), - OwnerPlayer, - VisionSkill - ) { - if owner.0 == player.basic_info.id { + for (entity, owner, mut vision_skill) in + query_with!(ctx.world.get_world_entity(), OwnerPlayer, VisionSkill) + { + if owner.0 == ctx.player.basic_info.id { vision_skill.skill_id = request.skill_id; - player.notify(VisionSkillChangeNotify { + ctx.player.notify(VisionSkillChangeNotify { entity_id: entity.into(), vision_skill_infos: vec![VisionSkillInformation { skill_id: request.skill_id, @@ -32,25 +35,34 @@ pub fn on_vision_explore_skill_set_request( } pub fn on_explore_skill_roulette_set_request( - player: &mut Player, + ctx: &mut NetContext, request: ExploreSkillRouletteSetRequest, response: &mut ExploreSkillRouletteSetResponse, ) { let mut illegal_skill = false; for skill_roulette in &request.skill_roulettes { for skill_id in &skill_roulette.skill_ids { - if *skill_id != 0 && !player.explore_tools.unlocked_explore_skills.contains(skill_id) { + if *skill_id != 0 + && !ctx + .player + .explore_tools + .unlocked_explore_skills + .contains(skill_id) + { illegal_skill = true; - break + break; } } } match illegal_skill { true => response.error_code = ErrorCode::ErrRouletteFuncIdInvaild.into(), false => { - player.explore_tools.roulette = request.skill_roulettes.get(0).unwrap().skill_ids.iter() - .map(|&skill_id| skill_id) - .collect::>() + ctx.player.explore_tools.roulette = request + .skill_roulettes + .first() + .unwrap() + .skill_ids + .to_vec() .as_slice() .try_into() .unwrap(); @@ -58,4 +70,4 @@ pub fn on_explore_skill_roulette_set_request( response.skill_roulettes = request.skill_roulettes; } } -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/teleport.rs b/wicked-waifus-game-server/src/logic/handler/teleport.rs index 5cc9c17..84de68e 100644 --- a/wicked-waifus-game-server/src/logic/handler/teleport.rs +++ b/wicked-waifus-game-server/src/logic/handler/teleport.rs @@ -1,37 +1,51 @@ -use wicked_waifus_protocol::{ErrorCode, JoinSceneNotify, LeaveSceneNotify, TeleportDataRequest, TeleportDataResponse, TeleportFinishRequest, TeleportFinishResponse, TeleportNotify, TeleportReason, TeleportTransferRequest, TeleportTransferResponse, TransitionOptionPb}; +use wicked_waifus_protocol::{ + ErrorCode, JoinSceneNotify, LeaveSceneNotify, TeleportDataRequest, TeleportDataResponse, + TeleportFinishRequest, TeleportFinishResponse, TeleportNotify, TeleportReason, + TeleportTransferRequest, TeleportTransferResponse, TransitionOptionPb, +}; -use wicked_waifus_data::{level_entity_config_data, RawVectorData}; use wicked_waifus_data::pb_components::teleport::TeleportComponent; +use wicked_waifus_data::{level_entity_config_data, RawVectorData}; use crate::logic::math::Vector3f; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::world_util; pub fn on_teleport_data_request( - player: &mut Player, + ctx: &NetContext, _: TeleportDataRequest, response: &mut TeleportDataResponse, ) { response.error_code = ErrorCode::Success.into(); - response.ids = player.teleports.teleports_data.iter() + response.ids = ctx + .player + .teleports + .teleports_data + .iter() .map(|teleport| teleport.id) .collect::>(); } pub fn on_teleport_transfer_request( - player: &mut Player, + ctx: &mut NetContext, request: TeleportTransferRequest, response: &mut TeleportTransferResponse, ) { tracing::debug!("received transfer request for teleport id: {}", request.id); - let Some(teleport) = wicked_waifus_data::teleporter_data::iter() - .find(|teleporter| request.id == teleporter.id) else { + let Some(teleport) = + wicked_waifus_data::teleporter_data::iter().find(|teleporter| request.id == teleporter.id) + else { response.error_code = ErrorCode::ErrTeleportIdNotExist.into(); return; }; - println!("received transfer request for teleport entity id: {}", &teleport.teleport_entity_config_id); - let Some(tp) = level_entity_config_data::get(teleport.map_id, teleport.teleport_entity_config_id) else { + println!( + "received transfer request for teleport entity id: {}", + &teleport.teleport_entity_config_id + ); + let Some(tp) = + level_entity_config_data::get(teleport.map_id, teleport.teleport_entity_config_id) + else { response.error_code = ErrorCode::ErrTeleportEntityNotExist.into(); return; }; @@ -41,8 +55,7 @@ pub fn on_teleport_transfer_request( return; }; - if teleport_component.disabled.unwrap_or(false) || - teleport_component.teleporter_id.is_none() { + if teleport_component.disabled.unwrap_or(false) || teleport_component.teleporter_id.is_none() { response.error_code = ErrorCode::ErrTeleportGmGetCreatureGenCfgFailed.into(); } if teleport_component.teleporter_id.unwrap() != request.id { @@ -58,8 +71,8 @@ pub fn on_teleport_transfer_request( response.yaw = 0f32; response.roll = 0f32; - if player.basic_info.cur_map_id == teleport.map_id { - player.notify(TeleportNotify { + if ctx.player.basic_info.cur_map_id == teleport.map_id { + ctx.player.notify(TeleportNotify { map_id: teleport.map_id, pos: Some(teleport_position.to_protobuf()), rot: None, @@ -71,14 +84,14 @@ pub fn on_teleport_transfer_request( }); } else { // remove entity - player.notify(LeaveSceneNotify { - player_id: player.basic_info.id, + ctx.player.notify(LeaveSceneNotify { + player_id: ctx.player.basic_info.id, scene_id: "".to_string(), transition_option: Some(TransitionOptionPb::default()), }); - let scene_info = world_util::build_scene_information(&player); + let scene_info = world_util::build_scene_information(ctx); // TODO: Trigger initial join world flow?? - player.notify(JoinSceneNotify { + ctx.player.notify(JoinSceneNotify { scene_info: Some(scene_info), max_entity_id: i64::MAX, transition_option: Some(TransitionOptionPb::default()), @@ -88,7 +101,7 @@ pub fn on_teleport_transfer_request( } pub fn on_teleport_finish_request( - _player: &mut Player, + _ctx: &mut NetContext, _: TeleportFinishRequest, response: &mut TeleportFinishResponse, ) { @@ -103,4 +116,4 @@ fn get_teleport_position(transform: &[RawVectorData], component: &TeleportCompon entity_position.add_teleport_position(teleport_position); } entity_position -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/handler/tutorial.rs b/wicked-waifus-game-server/src/logic/handler/tutorial.rs index bcd8208..8d97c1e 100644 --- a/wicked-waifus-game-server/src/logic/handler/tutorial.rs +++ b/wicked-waifus-game-server/src/logic/handler/tutorial.rs @@ -4,14 +4,15 @@ use wicked_waifus_protocol::{ TutorialReceiveResponse, TutorialUnlockRequest, TutorialUnlockResponse, }; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; pub fn on_tutorial_info_request( - player: &mut Player, + ctx: &NetContext, _: TutorialInfoRequest, response: &mut TutorialInfoResponse, ) { - response.unlock_list = player + response.unlock_list = ctx + .player .tutorials .tutorials .iter() @@ -24,7 +25,7 @@ pub fn on_tutorial_info_request( } pub fn on_tutorial_receive_request( - player: &mut Player, + ctx: &mut NetContext, request: TutorialReceiveRequest, response: &mut TutorialReceiveResponse, ) { @@ -35,12 +36,13 @@ pub fn on_tutorial_receive_request( return; }; - let Some(tutorial) = player + let Some(tutorial) = ctx + .player .tutorials .tutorials .iter() - .find(|tutorial| tutorial.id == request.id) else { - + .find(|tutorial| tutorial.id == request.id) + else { response.error_code = ErrorCode::GuideTutorialNotUnlock.into(); return; }; @@ -51,7 +53,10 @@ pub fn on_tutorial_receive_request( } // TODO: Search the rewards in drop_package - tracing::debug!("Tutorial receive request with drop: {}", tutorial_data.drop_id); + tracing::debug!( + "Tutorial receive request with drop: {}", + tutorial_data.drop_id + ); // TODO: Fill in the item map response.error_code = ErrorCode::Success.into(); @@ -59,7 +64,7 @@ pub fn on_tutorial_receive_request( } pub fn on_tutorial_unlock_request( - player: &mut Player, + ctx: &mut NetContext, request: TutorialUnlockRequest, response: &mut TutorialUnlockResponse, ) { @@ -70,7 +75,8 @@ pub fn on_tutorial_unlock_request( return; }; - if let Some(tutorial) = player + if let Some(tutorial) = ctx + .player .tutorials .tutorials .iter() @@ -84,7 +90,7 @@ pub fn on_tutorial_unlock_request( return; } - let tutorial = player.unlock_tutorial(request.id); + let tutorial = ctx.player.unlock_tutorial(request.id); response.un_lock_info = Some(TutorialInfo { id: tutorial.id, create_time: tutorial.create_time, diff --git a/wicked-waifus-game-server/src/logic/handler/weapon.rs b/wicked-waifus-game-server/src/logic/handler/weapon.rs index 559468e..7c0a67e 100644 --- a/wicked-waifus-game-server/src/logic/handler/weapon.rs +++ b/wicked-waifus-game-server/src/logic/handler/weapon.rs @@ -1,29 +1,26 @@ use crate::logic::components::{Equip, WeaponSkin}; use crate::logic::ecs::component::ComponentContainer; use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use crate::modify_component; -use wicked_waifus_protocol::{EntityEquipChangeNotify, EntityEquipSkinChangeNotify, EquipComponentPb, EquipTakeOnNotify, EquipTakeOnRequest, EquipTakeOnResponse, EquipWeaponSkinRequest, EquipWeaponSkinResponse, ErrorCode, LoadEquipData, SendEquipSkinRequest, SendEquipSkinResponse, WeaponSkinComponentPb, WeaponSkinDeleteNotify, WeaponSkinRequest, WeaponSkinResponse}; +use wicked_waifus_protocol::{ + EntityEquipChangeNotify, EntityEquipSkinChangeNotify, EquipComponentPb, EquipTakeOnNotify, + EquipTakeOnRequest, EquipTakeOnResponse, EquipWeaponSkinRequest, EquipWeaponSkinResponse, + ErrorCode, LoadEquipData, SendEquipSkinRequest, SendEquipSkinResponse, WeaponSkinComponentPb, + WeaponSkinDeleteNotify, WeaponSkinRequest, WeaponSkinResponse, +}; pub fn on_weapon_skin_request( - player: &Player, + ctx: &NetContext, _request: WeaponSkinRequest, response: &mut WeaponSkinResponse, ) { - response.equip_list = player - .role_list - .values() - .filter(|role| role.weapon_skin_id != 0) - .map(|role| LoadEquipData { - role_id: role.role_id, - skin_id: role.weapon_skin_id, - }) - .collect(); - + response.equip_list = get_player_weapons(ctx.player); response.error_code = ErrorCode::Success.into(); } pub fn on_equip_weapon_skin_request( - player: &mut Player, + ctx: &mut NetContext, request: EquipWeaponSkinRequest, response: &mut EquipWeaponSkinResponse, ) { @@ -31,7 +28,7 @@ pub fn on_equip_weapon_skin_request( return; }; - let role = player.role_list.get_mut(&equip_data.role_id); + let role = ctx.player.role_list.get_mut(&equip_data.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; @@ -46,50 +43,44 @@ pub fn on_equip_weapon_skin_request( }; // Verify Skin is unlocked - if !player.unlocked_skins.weapon_skins.contains(&skin_data.id) { + if !ctx + .player + .unlocked_skins + .weapon_skins + .contains(&skin_data.id) + { response.error_code = ErrorCode::WeaponSkinUnLockErr.into(); return; } role.weapon_skin_id = equip_data.skin_id; - { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let entity_id = world.get_entity_id(equip_data.role_id); - modify_component!( - world.get_entity_components(entity_id as i32), - WeaponSkin, - |skin_component: &mut WeaponSkin| { - skin_component.skin_id = equip_data.skin_id; - } - ); - player.notify(EntityEquipSkinChangeNotify { - entity_id, - weapon_skin_component_pb: Some(WeaponSkinComponentPb { - weapon_skin_id: equip_data.skin_id, - }), - }); - } + let world = ctx.world.get_world_entity(); + let entity_id = world.get_entity_id(equip_data.role_id); + modify_component!( + world.get_entity_components(entity_id as i32), + WeaponSkin, + |skin_component: &mut WeaponSkin| { + skin_component.skin_id = equip_data.skin_id; + } + ); + ctx.player.notify(EntityEquipSkinChangeNotify { + entity_id, + weapon_skin_component_pb: Some(WeaponSkinComponentPb { + weapon_skin_id: equip_data.skin_id, + }), + }); // Is the all list needed or only the new one?? - response.data_list = player - .role_list - .values() - .filter(|role| role.weapon_skin_id != 0) - .map(|role| LoadEquipData { - role_id: role.role_id, - skin_id: role.weapon_skin_id, - }) - .collect(); + response.data_list = get_player_weapons(ctx.player); response.error_code = ErrorCode::Success.into(); } pub fn on_send_equip_skin_request( - player: &mut Player, + ctx: &mut NetContext, request: SendEquipSkinRequest, response: &mut SendEquipSkinResponse, ) { - let role = player.role_list.get_mut(&request.role_id); + let role = ctx.player.role_list.get_mut(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; @@ -97,79 +88,90 @@ pub fn on_send_equip_skin_request( let old_skin_id = role.weapon_skin_id; role.weapon_skin_id = 0; - { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let entity_id = world.get_entity_id(request.role_id); - modify_component!( - world.get_entity_components(entity_id as i32), - WeaponSkin, - |skin_component: &mut WeaponSkin| { - skin_component.skin_id = 0; - } - ); - player.notify(EntityEquipSkinChangeNotify { - entity_id, - weapon_skin_component_pb: Some(WeaponSkinComponentPb { - weapon_skin_id: 0, - }), - }); - player.notify(WeaponSkinDeleteNotify { - role_id: request.role_id, - skin_id: old_skin_id, - }) - } + let world = ctx.world.get_world_entity(); + let entity_id = world.get_entity_id(request.role_id); + modify_component!( + world.get_entity_components(entity_id as i32), + WeaponSkin, + |skin_component: &mut WeaponSkin| { + skin_component.skin_id = 0; + } + ); + ctx.player.notify(EntityEquipSkinChangeNotify { + entity_id, + weapon_skin_component_pb: Some(WeaponSkinComponentPb { weapon_skin_id: 0 }), + }); + ctx.player.notify(WeaponSkinDeleteNotify { + role_id: request.role_id, + skin_id: old_skin_id, + }); response.error_code = ErrorCode::Success.into(); } pub fn on_equip_take_on_request( - player: &mut Player, + ctx: &mut NetContext, request: EquipTakeOnRequest, response: &mut EquipTakeOnResponse, ) { let Some(equip_data) = request.data else { return; }; - - // TODO: Add sanity checks(add from another role, a.k.a.: switch from roles) - player.notify(EquipTakeOnNotify { data_list: vec![equip_data] }); - let role = player.role_list.get_mut(&equip_data.role_id); + // TODO: Add sanity checks(add from another role, a.k.a.: switch from roles) + ctx.player.notify(EquipTakeOnNotify { + data_list: vec![equip_data], + }); + + let role = ctx.player.role_list.get_mut(&equip_data.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; }; - - let Some((id, breach)) = player.inventory.get_weapon_equip_info(equip_data.equip_inc_id) else { + + let Some((id, breach)) = ctx + .player + .inventory + .get_weapon_equip_info(equip_data.equip_inc_id) + else { response.error_code = ErrorCode::ErrItemNotFound.into(); return; }; role.equip_weapon = id; - + // TODO: Change attributes based on weapon (PbRolePropsNotify + buffs + CombatNotifyAttributeChangedNotify) - - { - // TODO: remove from old one if in scene in case of weapon switch - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); - let entity_id = world.get_entity_id(equip_data.role_id); - modify_component!( - world.get_entity_components(entity_id as i32), - Equip, - |equip_component: &mut Equip| { - equip_component.weapon_id = id; - equip_component.weapon_breach_level = breach; - } - ); - player.notify(EntityEquipChangeNotify { - entity_id, - equip_component: Some(EquipComponentPb { - weapon_id: id, - weapon_breach_level: breach, - }), - }) - } + + // TODO: remove from old one if in scene in case of weapon switch + let world = ctx.world.get_world_entity(); + let entity_id = world.get_entity_id(equip_data.role_id); + modify_component!( + world.get_entity_components(entity_id as i32), + Equip, + |equip_component: &mut Equip| { + equip_component.weapon_id = id; + equip_component.weapon_breach_level = breach; + } + ); + ctx.player.notify(EntityEquipChangeNotify { + entity_id, + equip_component: Some(EquipComponentPb { + weapon_id: id, + weapon_breach_level: breach, + }), + }); // TODO: Should we return all of them?? response.data_list = vec![equip_data]; response.error_code = ErrorCode::Success.into(); -} \ No newline at end of file +} + +#[inline(always)] +fn get_player_weapons(player: &Player) -> Vec { + player + .role_list + .values() + .filter(|role| role.weapon_skin_id != 0) + .map(|role| LoadEquipData { + role_id: role.role_id, + skin_id: role.weapon_skin_id, + }) + .collect() +} diff --git a/wicked-waifus-game-server/src/logic/math/transform.rs b/wicked-waifus-game-server/src/logic/math/transform.rs index c5d067c..659498b 100644 --- a/wicked-waifus-game-server/src/logic/math/transform.rs +++ b/wicked-waifus-game-server/src/logic/math/transform.rs @@ -30,9 +30,9 @@ impl Transform { } pub fn set_rotation_from_protobuf(&mut self, rotator: &Rotator) { - self.rotation.x = rotator.pitch; - self.rotation.y = rotator.yaw; - self.rotation.z = rotator.roll; + self.rotation.x = rotator.roll; + self.rotation.y = rotator.pitch; + self.rotation.z = rotator.yaw; } pub fn load_from_save(data: TransformData) -> Self { diff --git a/wicked-waifus-game-server/src/logic/player/mod.rs b/wicked-waifus-game-server/src/logic/player/mod.rs index bf4b517..8b5b4fd 100644 --- a/wicked-waifus-game-server/src/logic/player/mod.rs +++ b/wicked-waifus-game-server/src/logic/player/mod.rs @@ -1,7 +1,5 @@ pub use in_world_player::InWorldPlayer; -use std::cell::RefCell; use std::collections::HashMap; -use std::rc::Rc; use std::sync::Arc; use wicked_waifus_commons::time_util; use wicked_waifus_data::motion_data; @@ -24,10 +22,7 @@ use wicked_waifus_protocol::{ }; use wicked_waifus_protocol_internal::{PlayerBasicData, PlayerRoleData, PlayerSaveData}; -use super::{ - ecs::world::World, - role::{Role, RoleFormation}, -}; +use super::role::{Role, RoleFormation}; use crate::logic::components::RoleSkin; use crate::logic::ecs::world::WorldEntity; use crate::logic::player::basic_info::PlayerBasicInfo; @@ -97,7 +92,7 @@ pub struct Player { pub mc_element: PlayerMcElement, pub unlocked_skins: PlayerUnlockedSkins, // Runtime - pub world: Rc>, + pub world_owner_id: i32, pub last_save_time: u64, pub quadrant_id: u64, } @@ -308,6 +303,8 @@ impl Player { .collect::>(), now_chapter: global_status.now_chapter, received_chapter: global_status.received_chapter, + i_k1: vec![], + r_k1: vec![], }) .collect::>(), } @@ -435,7 +432,7 @@ impl Player { } } - pub fn build_player_entity_add_notify(&self, role_list: Vec, world: &mut WorldEntity) -> EntityAddNotify { + pub fn build_player_entity_add_notify(&self, role_list: Vec<&Role>, world: &mut WorldEntity) -> EntityAddNotify { create_player_entity_pb!( role_list, self.basic_info.cur_map_id, @@ -662,7 +659,7 @@ impl Player { .unlocked_skins .map(PlayerUnlockedSkins::load_from_save) .unwrap_or_default(), - world: Rc::new(RefCell::new(World::new())), + world_owner_id: 0, last_save_time: time_util::unix_timestamp(), quadrant_id: 0, } diff --git a/wicked-waifus-game-server/src/logic/player/player_inventory.rs b/wicked-waifus-game-server/src/logic/player/player_inventory.rs index 4348dcd..788d6c3 100644 --- a/wicked-waifus-game-server/src/logic/player/player_inventory.rs +++ b/wicked-waifus-game-server/src/logic/player/player_inventory.rs @@ -1,15 +1,22 @@ use std::collections::HashMap; use std::sync::atomic::AtomicI32; -use wicked_waifus_protocol::{ArrayIntInt, NormalItem, WeaponItem}; +use wicked_waifus_protocol::{ + ArrayIntInt, NormalItem, PhantomItem, PhantomPropInfo, RolePhantomEquipInfo, + RolePhantomPropInfo, WeaponItem, +}; use crate::config; use crate::logic::utils::seq_utils::{SequenceGenerator, Sequencer}; -use wicked_waifus_protocol_internal::{PlayerInventoryData, PlayerInventoryWeaponData}; +use wicked_waifus_protocol_internal::{ + PlayerInventoryData, PlayerInventoryPhantomData, PlayerInventoryWeaponData, +}; pub struct PlayerInventory { items: HashMap, weapons_seq: SequenceGenerator, weapons: HashMap, + echoes_seq: SequenceGenerator, + echoes: HashMap, } pub struct ItemUsage { @@ -38,8 +45,10 @@ impl PlayerInventory { pub fn load_from_save(data: PlayerInventoryData) -> Self { Self { weapons_seq: SequenceGenerator::from_data(&data.weapons), + echoes_seq: SequenceGenerator::from_data(&data.echoes), items: data.items.clone(), weapons: data.weapons.clone(), + echoes: data.echoes.clone(), } } @@ -47,6 +56,8 @@ impl PlayerInventory { PlayerInventoryData { items: self.items.clone(), weapons: self.weapons.clone(), + echoes: self.echoes.clone(), + echo_presets: Default::default(), } } @@ -212,6 +223,75 @@ impl PlayerInventory { .map(|weapon_data| (weapon_data.id, weapon_data.breach)) } + pub fn get_echoes_list( + &self, + ) -> ( + Vec, + Vec, + Vec, + ) { + let mut equip_info: HashMap> = HashMap::new(); + // TODO: probably change vec to hashmaps so comulative attributes are O(1) search range + let mut prop_info: HashMap, Vec)> = HashMap::new(); + + let echoes = self + .echoes + .iter() + .map(|(&inc_id, data)| { + if data.role_id != 0 { + equip_info.entry(data.role_id).or_default().push(inc_id); + // TODO add propInfo here + prop_info.entry(data.role_id).or_default(); + } + + PhantomItem { + id: data.id, + incr_id: inc_id, + func_value: data.func_value, + phantom_level: data.level, + phantom_exp: data.exp, + phantom_main_prop: data + .main_prop + .iter() + .map(|data| PhantomPropInfo { + phantom_prop_id: data.prop_id, + value: data.value, + }) + .collect(), + phantom_sub_prop: data + .sub_prop + .iter() + .map(|data| PhantomPropInfo { + phantom_prop_id: data.prop_id, + value: data.value, + }) + .collect(), + fetter_group_id: data.fetter_group_id, + skin_id: data.skin_id, + } + }) + .collect(); + + let equip_info = equip_info + .iter() + .map(|(&role_id, info)| RolePhantomEquipInfo { + role_id, + phantom_item_incr_id: info.clone(), + }) + .collect(); + + let prop_info = prop_info + .iter() + .map(|(&role_id, info)| RolePhantomPropInfo { + role_id, + base_prop: info.0.clone(), + add_prop: info.1.clone(), + }) + .collect(); + + (echoes, equip_info, prop_info) + } + #[inline(always)] fn add_internal(&mut self, id: i32, quantity: i32) -> i32 { *self @@ -307,10 +387,37 @@ impl Default for PlayerInventory { .collect::>(), false => Default::default(), }; + let mut echoes_seq = SequenceGenerator::new(); + let echoes: HashMap = + if default_unlocks.unlock_all_echo { + wicked_waifus_data::phantom_item_data::iter() + .filter(|data| data.item_id % 10 == 5) // TODO: Naruse?? + .flat_map(|data| { + let phantom_incr_id = echoes_seq.take_id(); + data.fetter_group.iter() + .map(move |&fetter_group_id| { + ( + phantom_incr_id, + PlayerInventoryPhantomData { + id: data.item_id, + func_value: 0, + level: 25, // TODO: Max level config + fetter_group_id, + ..Default::default() + }, + ) + }) + }) + .collect() + } else { + HashMap::new() + }; Self { items: HashMap::new(), weapons_seq, weapons, + echoes_seq, + echoes, } } } diff --git a/wicked-waifus-game-server/src/logic/player/player_unlocked_skins.rs b/wicked-waifus-game-server/src/logic/player/player_unlocked_skins.rs index a2630b9..f968221 100644 --- a/wicked-waifus-game-server/src/logic/player/player_unlocked_skins.rs +++ b/wicked-waifus-game-server/src/logic/player/player_unlocked_skins.rs @@ -7,6 +7,7 @@ pub struct PlayerUnlockedSkins { pub weapon_skins: HashSet, pub fly_skins: HashSet, pub wing_skins: HashSet, + pub echo_skins: HashSet, } impl PlayerUnlockedSkins { @@ -16,6 +17,7 @@ impl PlayerUnlockedSkins { weapon_skins: data.weapon_skins.iter().cloned().collect(), fly_skins: data.fly_skins.iter().cloned().collect(), wing_skins: data.wing_skins.iter().cloned().collect(), + echo_skins: data.echo_skins.iter().cloned().collect(), } } @@ -25,6 +27,7 @@ impl PlayerUnlockedSkins { weapon_skins: self.weapon_skins.iter().cloned().collect(), fly_skins: self.fly_skins.iter().cloned().collect(), wing_skins: self.wing_skins.iter().cloned().collect(), + echo_skins: self.echo_skins.iter().cloned().collect(), } } } @@ -67,6 +70,15 @@ impl Default for PlayerUnlockedSkins { } else { HashSet::new() }, + + echo_skins: if unlocks.unlock_all_echo_skins { + wicked_waifus_data::phantom_customize_item_data::iter() + .filter(|data| data.skin_item_id != 0) + .map(|data| data.skin_item_id) + .collect() + } else { + HashSet::new() + }, } } } diff --git a/wicked-waifus-game-server/src/logic/role/mod.rs b/wicked-waifus-game-server/src/logic/role/mod.rs index 268b552..6769769 100644 --- a/wicked-waifus-game-server/src/logic/role/mod.rs +++ b/wicked-waifus-game-server/src/logic/role/mod.rs @@ -7,7 +7,8 @@ use crate::logic::utils::growth_utils::get_role_props_by_level; use crate::logic::utils::load_role_info::load_key_value; pub use formation::RoleFormation; use wicked_waifus_commons::time_util; -use wicked_waifus_data::{role_info_data, BasePropertyData}; +use wicked_waifus_data::base_property_data::BasePropertyData; +use wicked_waifus_data::role_info_data; use wicked_waifus_protocol_internal::{RoleData, RoleStats}; use crate::logic::player::Element; @@ -147,11 +148,7 @@ impl Role { .max() .unwrap_or(0) } else { - wicked_waifus_data::resonant_chain_data::iter() - .filter(|level_data| level_data.group_id == data.resonant_chain_group_id) - .map(|level_data| level_data.group_index) - .min() - .unwrap_or(0) + 0 }; // TODO: add weapon and echo stats let base_stats = &get_role_props_by_level(role_id, level, breakthrough); diff --git a/wicked-waifus-game-server/src/logic/thread_mgr.rs b/wicked-waifus-game-server/src/logic/thread_mgr.rs index 4455981..e57de11 100644 --- a/wicked-waifus-game-server/src/logic/thread_mgr.rs +++ b/wicked-waifus-game-server/src/logic/thread_mgr.rs @@ -1,7 +1,6 @@ use wicked_waifus_commons::time_util; use wicked_waifus_protocol_internal::PlayerSaveData; use wicked_waifus_protocol::{message::Message, AfterJoinSceneNotify, EnterGameResponse, JoinSceneNotify, SilenceNpcNotify, TransitionOptionPb}; -use std::collections::hash_map::Entry::Vacant; use std::{ cell::RefCell, collections::{HashMap, VecDeque}, @@ -122,6 +121,11 @@ fn logic_thread_func(receiver: mpsc::Receiver, load: Arc { + pub player: &'logic mut Player, + pub world: &'logic mut World, +} + fn handle_logic_input(state: &mut LogicState, input: LogicInput) { match input { LogicInput::AddPlayer { @@ -130,64 +134,56 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) { session, player_save_data, } => { - let (player, is_player) = if let Vacant(e) = state.players.entry(player_id) { - ( - e.insert(RefCell::new(Player::load_from_save(player_save_data))), - true, - ) - } else { - if let Some(player) = state.players.get_mut(&player_id) { - (player, false) - } else { - tracing::warn!("logic_thread: get player requested, but player {player_id} with data doesn't exist"); - return; - } - }; + let mut player = state.players.entry(player_id).or_insert_with(|| { + RefCell::new(Player::load_from_save(player_save_data)) + }).borrow_mut(); - let mut player = player.borrow_mut(); - if is_player { - player - .world - .borrow_mut() - .world_entitys - .insert(player.basic_info.cur_map_id, WorldEntity::default()); - state.worlds.insert(player_id, player.world.clone()); - } + // TODO: shall we search in coop? + player.world_owner_id = player_id; + let mut world = state.worlds.entry(player_id).or_insert_with(|| { + let mut world = World::new(); + world.world_entities.insert( + player.basic_info.cur_map_id, + WorldEntity::default(), + ); + Rc::new(RefCell::new(world)) + }).borrow_mut(); player.init(); player.set_session(session); player.respond(EnterGameResponse::default(), enter_rpc_id); player.notify_general_data(); - player - .world - .borrow_mut() - .set_in_world_player_data(player.build_in_world_player()); + world.set_in_world_player_data(player.build_in_world_player()); - world_util::add_player_entities(&player); - let scene_info = world_util::build_scene_information(&player); + let mut ctx = NetContext { + player: &mut player, + world: &mut world, + }; + world_util::add_player_entities(&mut ctx); + let scene_info = world_util::build_scene_information(&mut ctx); - player.notify(SilenceNpcNotify::default()); + ctx.player.notify(SilenceNpcNotify::default()); - player.notify(JoinSceneNotify { + ctx.player.notify(JoinSceneNotify { scene_info: Some(scene_info), max_entity_id: i64::MAX, transition_option: Some(TransitionOptionPb::default()), }); - player.notify(AfterJoinSceneNotify::default()); - player.notify(player.build_update_formation_notify()); + ctx.player.notify(AfterJoinSceneNotify::default()); + ctx.player.notify(ctx.player.build_update_formation_notify()); - let map = logic::utils::quadrant_util::get_map(player.basic_info.cur_map_id); + let map = logic::utils::quadrant_util::get_map(ctx.player.basic_info.cur_map_id); let quadrant_id = map.get_quadrant_id( - player.location.position.position.x * 100.0, - player.location.position.position.y * 100.0, + ctx.player.location.position.position.x * 100.0, + ctx.player.location.position.position.y * 100.0, ); - player.quadrant_id = quadrant_id; - player.notify_month_card(); + ctx.player.quadrant_id = quadrant_id; + ctx.player.notify_month_card(); let entities = map.get_initial_entities(quadrant_id); - world_util::add_entities(&player, &entities, false); + world_util::add_entities(&mut ctx, &entities, false); drop(player); @@ -200,8 +196,17 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) { tracing::warn!("logic_thread: process message requested, but player with id {player_id} doesn't exist"); return; }; - - super::handler::handle_logic_message(&mut player.borrow_mut(), message); + let mut player = player.borrow_mut(); + let Some(world) = state.worlds.get_mut(&player.world_owner_id) else { + tracing::warn!("logic_thread: process message requested, but world for player id {} doesn't exist", player.world_owner_id); + return; + }; + let mut world = world.borrow_mut(); + let mut net_context = NetContext { + player: &mut player, + world: &mut world, + }; + super::handler::handle_logic_message(&mut net_context, message); } LogicInput::RemovePlayer { player_id } => { let Some(player) = state.players.remove(&player_id) else { diff --git a/wicked-waifus-game-server/src/logic/utils/action_utils.rs b/wicked-waifus-game-server/src/logic/utils/action_utils.rs index 7fd494e..fab4537 100644 --- a/wicked-waifus-game-server/src/logic/utils/action_utils.rs +++ b/wicked-waifus-game-server/src/logic/utils/action_utils.rs @@ -6,7 +6,8 @@ use wicked_waifus_data::pb_components::action::{Action, ChangeSelfEntityState, U use wicked_waifus_data::pb_components::entity_state::EntityStateComponent; use crate::logic::ecs::component::ComponentContainer; -use crate::logic::player::{ItemUsage, Player}; +use crate::logic::player::ItemUsage; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::tag_utils; use crate::query_components; @@ -18,23 +19,23 @@ macro_rules! unimplemented_action { } } -pub fn perform_action(player: &mut Player, +pub fn perform_action(ctx: &mut NetContext, entity_id: i64, - level_entity_data: &wicked_waifus_data::LevelEntityConfigData, - template_config: &wicked_waifus_data::TemplateConfigData, + level_entity_data: &wicked_waifus_data::level_entity_config_data::LevelEntityConfigData, + template_config: &wicked_waifus_data::template_config_data::TemplateConfigData, element: Action) { match element { Action::SetBattleState(action) => unimplemented_action! { action }, Action::ExecBattleAction(action) => unimplemented_action! { action }, Action::WaitBattleCondition(action) => unimplemented_action! { action }, Action::PlayFlow(action) => unimplemented_action! { action }, - Action::Collect(_) => collect_action(player, level_entity_data, template_config), + Action::Collect(_) => collect_action(ctx, level_entity_data, template_config), Action::LeisureInteract(action) => unimplemented_action! { action }, - Action::UnlockTeleportTrigger(action) => unlock_teleport_trigger(player, action.params), + Action::UnlockTeleportTrigger(action) => unlock_teleport_trigger(ctx, action.params), Action::EnableTemporaryTeleport(action) => unimplemented_action! { action }, Action::OpenSystemBoard(action) => unimplemented_action! { action }, Action::OpenSystemFunction(action) => unimplemented_action! { action }, - Action::ChangeSelfEntityState(action) => change_self_entity_state(player, entity_id, level_entity_data, template_config, action.params), + Action::ChangeSelfEntityState(action) => change_self_entity_state(ctx, entity_id, level_entity_data, template_config, action.params), Action::SetPlayerOperationRestriction(action) => unimplemented_action! { action }, Action::Wait(action) => unimplemented_action! { action }, Action::ChangeEntityState(action) => unimplemented_action! { action }, @@ -135,6 +136,8 @@ pub fn perform_action(player: &mut Player, Action::RemoveTrialFollowShooter(action) => unimplemented_action! { action }, Action::AddTrialCharacter(action) => unimplemented_action! { action }, Action::RemoveTrialCharacter(action) => unimplemented_action! { action }, + Action::UpdateTrialCharacter(action) => unimplemented_action! { action }, + Action::RestoreTrialCharacter(action) => unimplemented_action! { action }, Action::SetAreaState(action) => unimplemented_action! { action }, Action::SwitchSubLevels(action) => unimplemented_action! { action }, Action::ChangeTeamPosition(action) => unimplemented_action! { action }, @@ -208,12 +211,15 @@ pub fn perform_action(player: &mut Player, Action::StopUiScreenEffect(action) => unimplemented_action! { action }, Action::StopNewMoveWithSpline(action) => unimplemented_action! { action }, Action::RequestSystemFunction(action) => unimplemented_action! { action }, + Action::SetTimeScale(action) => unimplemented_action! { action }, + Action::EndCommonTip(action) => unimplemented_action! { action }, + Action::SetupMoraleSystem(action) => unimplemented_action! { action }, } } -fn collect_action(player: &mut Player, - level_entity_data: &wicked_waifus_data::LevelEntityConfigData, - template_config: &wicked_waifus_data::TemplateConfigData) { +fn collect_action(ctx: &mut NetContext, + level_entity_data: &wicked_waifus_data::level_entity_config_data::LevelEntityConfigData, + template_config: &wicked_waifus_data::template_config_data::TemplateConfigData) { if let Some(reward_component) = level_entity_data.components_data.reward_component .as_ref() .or(template_config.components_data.reward_component.as_ref()) { @@ -227,11 +233,11 @@ fn collect_action(player: &mut Player, let usages = drop.drop_preview.iter() .map(|(&id, &quantity)| ItemUsage { id, quantity }) .collect::>(); - let updated_items = player.inventory.add_items(&usages); - let normal_item_list = player.inventory.to_normal_item_list_filtered( + let updated_items = ctx.player.inventory.add_items(&usages); + let normal_item_list = ctx.player.inventory.to_normal_item_list_filtered( &updated_items.keys().cloned().collect::>() ); - player.notify(NormalItemUpdateNotify { normal_item_list, no_tips: false }); + ctx.player.notify(NormalItemUpdateNotify { normal_item_list, no_tips: false }); // UpdateHandBookActiveStateMapNotify let mut rewards: HashMap = HashMap::new(); rewards.insert(0, WR { @@ -244,7 +250,7 @@ fn collect_action(player: &mut Player, }) .collect::>(), }); - player.notify(ItemRewardNotify { + ctx.player.notify(ItemRewardNotify { drop_id: reward_id, reason: 15000, magnification: 1, @@ -256,21 +262,20 @@ fn collect_action(player: &mut Player, } #[inline(always)] -fn unlock_teleport_trigger(player: &mut Player, action: UnlockTeleportTrigger) { - player.unlock_teleport(action.teleport_id) +fn unlock_teleport_trigger(ctx: &mut NetContext, action: UnlockTeleportTrigger) { + ctx.player.unlock_teleport(action.teleport_id) } -fn change_self_entity_state(player: &mut Player, +fn change_self_entity_state(ctx: &mut NetContext, entity_id: i64, - level_entity_data: &wicked_waifus_data::LevelEntityConfigData, - template_config: &wicked_waifus_data::TemplateConfigData, + level_entity_data: &wicked_waifus_data::level_entity_config_data::LevelEntityConfigData, + template_config: &wicked_waifus_data::template_config_data::TemplateConfigData, action: ChangeSelfEntityState) { let state = tag_utils::get_tag_id_by_name(action.entity_state.as_str()); // TODO: update Tag::CommonEntityTags too?? let old_state = { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); + let world = ctx.world.get_world_entity(); let mut state_tag = query_components!(world, entity_id, StateTag).0.unwrap(); let old_state = state_tag.state_tag_id; tracing::debug!("ChangeSelfEntityState: old state {old_state} -> new state: {state}"); @@ -291,7 +296,7 @@ fn change_self_entity_state(player: &mut Player, if expected == state { if let Some(actions) = state_change_behavior.action { for sub in actions { - perform_action(player, entity_id, level_entity_data, template_config, sub); + perform_action(ctx, entity_id, level_entity_data, template_config, sub); } } } @@ -299,7 +304,7 @@ fn change_self_entity_state(player: &mut Player, } } - player.notify(EntityCommonTagNotify { + ctx.player.notify(EntityCommonTagNotify { id: entity_id, tags: vec![ CommonTagData { tag_id: old_state, remove_tag_ids: false }, // Remove @@ -307,7 +312,7 @@ fn change_self_entity_state(player: &mut Player, ], }); - player.notify(EntityStateReadyNotify { + ctx.player.notify(EntityStateReadyNotify { entity_id, tag_id: state, ready: true, // TODO: Always true? or shall we compare it to something?? diff --git a/wicked-waifus-game-server/src/logic/utils/condition_utils.rs b/wicked-waifus-game-server/src/logic/utils/condition_utils.rs index eb46702..dd7d12c 100644 --- a/wicked-waifus-game-server/src/logic/utils/condition_utils.rs +++ b/wicked-waifus-game-server/src/logic/utils/condition_utils.rs @@ -1,28 +1,30 @@ -use wicked_waifus_data::pb_components::condition::{CheckConditionGroup, CompareEntityState, Condition}; +use wicked_waifus_data::pb_components::condition::{ + CheckConditionGroup, CompareEntityState, Condition, HasBuff, +}; use crate::logic::ecs::component::ComponentContainer; -use crate::logic::player::Player; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::tag_utils; use crate::query_components; macro_rules! unimplemented_condition { - ($condition:ident) => { - { - tracing::warn!("Condition check not implemented for: {:?}", $condition); - true - } - } + ($condition:ident) => {{ + tracing::warn!("Condition check not implemented for: {:?}", $condition); + true + }}; } -pub fn check_condition(player: &Player, - entity_id: i64, - level_entity_data: &wicked_waifus_data::LevelEntityConfigData, - template_config: &wicked_waifus_data::TemplateConfigData, - element: Condition) -> bool { +pub fn check_condition( + ctx: &mut NetContext, + entity_id: i64, + level_entity_data: &wicked_waifus_data::level_entity_config_data::LevelEntityConfigData, + template_config: &wicked_waifus_data::template_config_data::TemplateConfigData, + element: Condition, +) -> bool { match element { Condition::CompareTimePeriod(condition) => unimplemented_condition! { condition }, Condition::CheckChildQuestFinished(condition) => unimplemented_condition! { condition }, - Condition::CompareEntityState(condition) => compare_entity_state(player, entity_id, condition), + Condition::CompareEntityState(condition) => compare_entity_state(ctx, entity_id, condition), Condition::CheckEntityState(condition) => unimplemented_condition! { condition }, Condition::CompareVar(condition) => unimplemented_condition! { condition }, Condition::CompareWeather(condition) => unimplemented_condition! { condition }, @@ -36,13 +38,15 @@ pub fn check_condition(player: &Player, Condition::PreLevelPlay(condition) => unimplemented_condition! { condition }, Condition::CheckLevelPlay(condition) => unimplemented_condition! { condition }, Condition::CheckLevelPlayState(condition) => unimplemented_condition! { condition }, - Condition::CheckLevelPlayCompleteNumber(condition) => unimplemented_condition! { condition }, + Condition::CheckLevelPlayCompleteNumber(condition) => { + unimplemented_condition! { condition } + } Condition::CompareLevelPlayRewardState(condition) => unimplemented_condition! { condition }, Condition::CheckItems(condition) => unimplemented_condition! { condition }, Condition::HandInItems(condition) => unimplemented_condition! { condition }, Condition::GetItem(condition) => unimplemented_condition! { condition }, Condition::UseItem(condition) => unimplemented_condition! { condition }, - Condition::HasBuff(condition) => unimplemented_condition! { condition }, + Condition::HasBuff(condition) => has_buff(ctx, entity_id, condition), Condition::CompareLift(condition) => unimplemented_condition! { condition }, Condition::CheckJigsawInfo(condition) => unimplemented_condition! { condition }, Condition::CheckInCombat(condition) => unimplemented_condition! { condition }, @@ -68,14 +72,20 @@ pub fn check_condition(player: &Player, Condition::CheckEntityLocked(condition) => unimplemented_condition! { condition }, Condition::CheckRogueAbilitySelect(condition) => unimplemented_condition! { condition }, Condition::CompareFishingBoatState(condition) => unimplemented_condition! { condition }, - Condition::CompleteCertainFishingEntrust(condition) => unimplemented_condition! { condition }, + Condition::CompleteCertainFishingEntrust(condition) => { + unimplemented_condition! { condition } + } Condition::CompareFishingPrestigeLevel(condition) => unimplemented_condition! { condition }, - Condition::CheckCertainFishingItemCount(condition) => unimplemented_condition! { condition }, + Condition::CheckCertainFishingItemCount(condition) => { + unimplemented_condition! { condition } + } Condition::CompareFishingTechLevel(condition) => unimplemented_condition! { condition }, Condition::ListenEntitySelfEvent(condition) => unimplemented_condition! { condition }, Condition::CheckHookLockPoint(condition) => unimplemented_condition! { condition }, Condition::CheckEntitesExist(condition) => unimplemented_condition! { condition }, - Condition::CheckEntityHasSceneItemAttributeTag(condition) => unimplemented_condition! { condition }, + Condition::CheckEntityHasSceneItemAttributeTag(condition) => { + unimplemented_condition! { condition } + } Condition::CheckTargetBattleAttribute(condition) => unimplemented_condition! { condition }, Condition::CheckAlertAreaEnabled(condition) => unimplemented_condition! { condition }, Condition::CompareAlertValue(condition) => unimplemented_condition! { condition }, @@ -99,7 +109,13 @@ pub fn check_condition(player: &Player, Condition::ParallaxAlign(condition) => unimplemented_condition! { condition }, Condition::WaitBattleCondition(condition) => unimplemented_condition! { condition }, Condition::CheckDirection(condition) => unimplemented_condition! { condition }, - Condition::CheckConditionGroup(condition) => check_condition_group(player, entity_id, level_entity_data, template_config, condition), + Condition::CheckConditionGroup(condition) => check_condition_group( + ctx, + entity_id, + level_entity_data, + template_config, + condition, + ), Condition::CheckTreasureBeenClaimed(condition) => unimplemented_condition! { condition }, Condition::RangeSphere(condition) => unimplemented_condition! { condition }, Condition::CheckInRange(condition) => unimplemented_condition! { condition }, @@ -119,40 +135,68 @@ pub fn check_condition(player: &Player, Condition::CheckEntityGravityDirection(condition) => unimplemented_condition! { condition }, Condition::CheckTeleControlState(condition) => unimplemented_condition! { condition }, Condition::CheckEntityReward(condition) => unimplemented_condition! { condition }, - Condition::CheckIsGramophonePlayingMusic(condition) => unimplemented_condition! { condition }, + Condition::CheckIsGramophonePlayingMusic(condition) => { + unimplemented_condition! { condition } + } Condition::CheckBVBEvent(condition) => unimplemented_condition! { condition }, Condition::FinishBvbChallenge(condition) => unimplemented_condition! { condition }, Condition::CompareActorVar(condition) => unimplemented_condition! { condition }, - Condition::CheckDangoCultivationProgress(condition) => unimplemented_condition! { condition }, + Condition::CheckDangoCultivationProgress(condition) => { + unimplemented_condition! { condition } + }, + Condition::CheckPlayerMoraleLevelRange(condition) => { + unimplemented_condition! { condition } + }, + Condition::ProgramSpecialProcess(condition) => { + unimplemented_condition! { condition } + } } } -fn compare_entity_state(player: &Player, entity_id: i64, condition: CompareEntityState) -> bool { +fn compare_entity_state(ctx: &NetContext, entity_id: i64, condition: CompareEntityState) -> bool { let actual = { - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); + let world = ctx.world.get_world_entity(); let state_tag = query_components!(world, entity_id, StateTag).0.unwrap(); state_tag.state_tag_id }; let expected = tag_utils::get_tag_id_by_name(condition.state.as_str()); // In theory, we can only check for equal or not equal - tracing::debug!("CompareEntityState: type {:?}, actual: {actual}, expected: {expected}", condition.compare); + tracing::debug!( + "CompareEntityState: type {:?}, actual: {actual}, expected: {expected}", + condition.compare + ); condition.compare.cmp(&expected, &actual) } -fn check_condition_group(player: &Player, - entity_id: i64, - level_entity_data: &wicked_waifus_data::LevelEntityConfigData, - template_config: &wicked_waifus_data::TemplateConfigData, - condition: CheckConditionGroup) -> bool { +fn has_buff(ctx: &NetContext, entity_id: i64, condition: HasBuff) -> bool { + let has_buff = { + let world = ctx.world.get_world_entity(); + let buff = query_components!(world, entity_id, FightBuff).0.unwrap(); + // TODO: use online condition + // TODO: Check if there are other type of Eq + buff.fight_buff_infos + .iter() + .find(|buf| buf.buff_id == condition.buff_id) + .is_some() + }; + tracing::debug!("Entity {entity_id} has buff: {has_buff:?}"); + has_buff +} +fn check_condition_group( + ctx: &mut NetContext, + entity_id: i64, + level_entity_data: &wicked_waifus_data::level_entity_config_data::LevelEntityConfigData, + template_config: &wicked_waifus_data::template_config_data::TemplateConfigData, + condition: CheckConditionGroup, +) -> bool { let mut check = true; // TODO: Investigate if type has a meaning for element in condition.condition.conditions { - check = check_condition(player, entity_id, level_entity_data, template_config, element); + check = check_condition(ctx, entity_id, level_entity_data, template_config, element); if !check { break; } } check -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/src/logic/utils/entity_serializer.rs b/wicked-waifus-game-server/src/logic/utils/entity_serializer.rs index 04dfa92..657c922 100644 --- a/wicked-waifus-game-server/src/logic/utils/entity_serializer.rs +++ b/wicked-waifus-game-server/src/logic/utils/entity_serializer.rs @@ -3,31 +3,27 @@ use wicked_waifus_protocol::{EEntityType, EntityPb, PlayerSceneAoiData}; use std::collections::HashSet; use crate::logic::components::Visibility; -use crate::logic::player::Player; use crate::{modify_component, query_hn_with}; +use crate::logic::thread_mgr::NetContext; -pub fn build_scene_add_on_init_data(player: &Player) -> PlayerSceneAoiData { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - +pub fn build_scene_add_on_init_data(ctx: &mut NetContext) -> PlayerSceneAoiData { + let world = ctx.world.get_mut_world_entity(); let entities = query_hn_with!(world, PlayerOwnedEntityMarker) .into_iter() .map(|(entity_id, _)| { - let res_map: (EEntityType, i32); match EEntityType::try_from( world.get_entity(world.get_config_id(entity_id)).entity_type, ) { Ok(EEntityType::Player) => { - res_map = (EEntityType::Player, entity_id); + (EEntityType::Player, entity_id) } Ok(EEntityType::Monster) => { - res_map = (EEntityType::Monster, entity_id); + (EEntityType::Monster, entity_id) } _ => { - res_map = (EEntityType::default(), -1); + (EEntityType::default(), -1) } } - res_map }) .collect::>(); @@ -44,9 +40,9 @@ pub fn build_scene_add_on_init_data(player: &Player) -> PlayerSceneAoiData { world.get_entity_components(entity_id), Visibility, |vis: &mut Visibility| { - let cur_role_id = player + let cur_role_id = ctx.player .formation_list - .get(&player.cur_formation_id) + .get(&ctx.player.cur_formation_id) .unwrap() .cur_role; (vis.is_visible, vis.is_actor_visible) = if config_id == cur_role_id { diff --git a/wicked-waifus-game-server/src/logic/utils/growth_utils.rs b/wicked-waifus-game-server/src/logic/utils/growth_utils.rs index ccb2edc..143d6c3 100644 --- a/wicked-waifus-game-server/src/logic/utils/growth_utils.rs +++ b/wicked-waifus-game-server/src/logic/utils/growth_utils.rs @@ -1,4 +1,5 @@ -use wicked_waifus_data::{BasePropertyData, base_property_data, monster_property_growth_data, role_property_growth_data}; +use wicked_waifus_data::{base_property_data, monster_property_growth_data, role_property_growth_data}; +use wicked_waifus_data::base_property_data::BasePropertyData; pub fn get_role_props_by_level(id: i32, level: i32, breach: i32) -> BasePropertyData { let mut base_props = get_role_props_or_default(id).clone(); diff --git a/wicked-waifus-game-server/src/logic/utils/load_role_info.rs b/wicked-waifus-game-server/src/logic/utils/load_role_info.rs index 85a110c..50a2d45 100644 --- a/wicked-waifus-game-server/src/logic/utils/load_role_info.rs +++ b/wicked-waifus-game-server/src/logic/utils/load_role_info.rs @@ -1,4 +1,4 @@ -use wicked_waifus_data::BasePropertyData; +use wicked_waifus_data::base_property_data::BasePropertyData; use wicked_waifus_protocol::EAttributeType; use std::collections::HashMap; diff --git a/wicked-waifus-game-server/src/logic/utils/quadrant_util.rs b/wicked-waifus-game-server/src/logic/utils/quadrant_util.rs index 30470de..55d323b 100644 --- a/wicked-waifus-game-server/src/logic/utils/quadrant_util.rs +++ b/wicked-waifus-game-server/src/logic/utils/quadrant_util.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::sync::OnceLock; - -use wicked_waifus_data::LevelEntityConfigData; +use wicked_waifus_data::level_entity_config_data::LevelEntityConfigData; pub(crate) struct StaticConfig { edge_size: f32, diff --git a/wicked-waifus-game-server/src/logic/utils/world_util.rs b/wicked-waifus-game-server/src/logic/utils/world_util.rs index d1f0c17..a9cfa13 100644 --- a/wicked-waifus-game-server/src/logic/utils/world_util.rs +++ b/wicked-waifus-game-server/src/logic/utils/world_util.rs @@ -4,18 +4,16 @@ use wicked_waifus_protocol::{ SceneMode, ScenePlayerInformation, SceneTimeInfo, }; -use wicked_waifus_data::pb_components::ComponentsData; -use wicked_waifus_data::{ - blueprint_config_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData, +use crate::logic::components::{ + Autonomous, Fsm, Interact, MonsterAi, ParaglidingSkin, SoarWingSkin, StateTag, Tag, WeaponSkin, }; - -use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, ParaglidingSkin, SoarWingSkin, StateTag, Tag, WeaponSkin}; use crate::logic::ecs::entity::EntityBuilder; use crate::logic::ecs::world::World; use crate::logic::math::Transform; use crate::logic::player::Player; -use crate::logic::utils::{entity_serializer, tag_utils}; +use crate::logic::thread_mgr::NetContext; use crate::logic::utils::growth_utils::get_monster_props_by_level; +use crate::logic::utils::{entity_serializer, tag_utils}; use crate::logic::{ components::{ Attribute, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer, PlayerOwnedEntityMarker, @@ -24,6 +22,15 @@ use crate::logic::{ ecs::component::ComponentContainer, }; use crate::query_with; +use wicked_waifus_data::blueprint_config_data::{EntityLogic, EntityType}; +use wicked_waifus_data::level_entity_config_data::LevelEntityConfigData; +use wicked_waifus_data::pb_components::ComponentsData; +use wicked_waifus_data::{blueprint_config_data, template_config_data}; + +const COUNT_OVERRIDE: &[(i32, i32)] = &[ + (1105, 3), + (1301, 4) +]; #[macro_export] macro_rules! create_player_entity_pb { @@ -114,16 +121,18 @@ macro_rules! create_player_entity_pb { }}; } -pub fn add_player_entities(player: &Player) { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - - let current_formation = player.formation_list.get(&player.cur_formation_id).unwrap(); +pub fn add_player_entities(ctx: &mut NetContext) { + let world = ctx.world.get_mut_world_entity(); + let current_formation = ctx + .player + .formation_list + .get(&ctx.player.cur_formation_id) + .unwrap(); let role_vec = current_formation .role_ids .iter() - .map(|role_id| player.role_list.get(&role_id).unwrap()) + .map(|role_id| ctx.player.role_list.get(role_id).unwrap()) .collect::>(); let cur_role_id = current_formation.cur_role; @@ -132,7 +141,7 @@ pub fn add_player_entities(player: &Player) { let entity = world.create_entity( role.role_id, EEntityType::Player.into(), - player.basic_info.cur_map_id, + ctx.player.basic_info.cur_map_id, ); // Once per character buffs are implemented, add a mut on role_buffs let fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id as i64); @@ -155,10 +164,10 @@ pub fn add_player_entities(player: &Player) { entity_state: EntityState::Default, })) .with(ComponentContainer::OwnerPlayer(OwnerPlayer( - player.basic_info.id, + ctx.player.basic_info.id, ))) .with(ComponentContainer::Position(Position( - player.location.position.clone(), + ctx.player.location.position.clone(), ))) .with(ComponentContainer::Visibility(Visibility { is_visible: role.role_id == cur_role_id, @@ -178,7 +187,7 @@ pub fn add_player_entities(player: &Player) { weapon_breach_level: 0, // TODO: store this too })) .with(ComponentContainer::VisionSkill(VisionSkill { - skill_id: player.explore_tools.active_explore_skill, + skill_id: ctx.player.explore_tools.active_explore_skill, })) .with(ComponentContainer::RoleSkin(RoleSkin { skin_id: role.skin_id, @@ -204,23 +213,23 @@ pub fn add_player_entities(player: &Player) { } } -pub fn build_scene_information(player: &Player) -> SceneInformation { +pub fn build_scene_information(ctx: &mut NetContext) -> SceneInformation { SceneInformation { scene_id: String::new(), - instance_id: player.location.instance_id, - owner_id: player.basic_info.id, + instance_id: ctx.player.location.instance_id, + owner_id: ctx.player.basic_info.id, dynamic_entity_list: Vec::new(), blackboard_params: Vec::new(), end_time: 0, - aoi_data: Some(entity_serializer::build_scene_add_on_init_data(player)), - player_infos: build_player_info_list(&player.world.borrow_mut()), + aoi_data: Some(entity_serializer::build_scene_add_on_init_data(ctx)), + player_infos: build_player_info_list(ctx.world), mode: SceneMode::Single.into(), time_info: Some(SceneTimeInfo { owner_time_clock_time_span: 0, hour: 8, minute: 0, }), - cur_context_id: player.basic_info.id as i64, + cur_context_id: ctx.player.basic_info.id as i64, ..Default::default() } } @@ -255,7 +264,9 @@ fn build_player_info_list(world: &World) -> Vec { EntityConfig ) .into_iter() - .filter(|(_, _, owner, _)| owner.0 == sp.player_id); + .filter(|(_, e, owner, _)| { + owner.0 == sp.player_id && e.entity_type == EEntityType::Player + }); ScenePlayerInformation { cur_role: cur_role_id, @@ -287,12 +298,14 @@ fn build_player_info_list(world: &World) -> Vec { .collect() } -pub fn remove_entity(player: &Player, entity_id: i64, remove_type: ERemoveEntityType) { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - - if world.remove_entity(entity_id as i32) { - player.notify(EntityRemoveNotify { +pub fn remove_entity(ctx: &mut NetContext, entity_id: i64, remove_type: ERemoveEntityType) { + if ctx + .world + .get_mut_world_entity() + .remove_entity(entity_id as i32) + { + // TODO: For COOP find a way to get players from world + ctx.player.notify(EntityRemoveNotify { remove_infos: vec![EntityRemoveInfo { entity_id, r#type: remove_type.into(), @@ -302,22 +315,19 @@ pub fn remove_entity(player: &Player, entity_id: i64, remove_type: ERemoveEntity } } -pub fn remove_entities(player: &Player, entities: &[&LevelEntityConfigData]) { +pub fn remove_entities(ctx: &mut NetContext, entities: &[&LevelEntityConfigData]) { let mut removed_entities = Vec::with_capacity(entities.len()); - // Enclose to drop borrow mut ASAP - { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - for entity in entities { - let entity_id = entity.entity_id as i32; // TODO: Should be i64 - if world.remove_entity(entity_id) { - removed_entities.push(world.get_entity_id(entity_id)); - } + let world = ctx.world.get_mut_world_entity(); + for entity in entities { + let entity_id = entity.entity_id as i32; // TODO: Should be i64 + if world.remove_entity(entity_id) { + removed_entities.push(world.get_entity_id(entity_id)); } } for entity_id in removed_entities { - player.notify(EntityRemoveNotify { + // TODO: For COOP find a way to get players from world + ctx.player.notify(EntityRemoveNotify { remove_infos: vec![EntityRemoveInfo { entity_id, r#type: 0, @@ -327,128 +337,139 @@ pub fn remove_entities(player: &Player, entities: &[&LevelEntityConfigData]) { } } -pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], external_awake: bool) { +pub fn add_entities( + ctx: &mut NetContext, + entities: &[&LevelEntityConfigData], + external_awake: bool, +) { let mut added_entities = Vec::with_capacity(entities.len()); - // Enclose to drop borrow mut ASAP - { - let mut world_ref = player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - for entity in entities { - // Skip hidden entities - if entity.is_hidden { - tracing::debug!("Hidden entity with config id: {}", entity.entity_id); - continue; - } - if entity.in_sleep && !external_awake { + let world = ctx.world.get_mut_world_entity(); + for entity in entities { + // Skip hidden entities + if entity.is_hidden { + tracing::debug!("Hidden entity with config id: {}", entity.entity_id); + continue; + } + if entity.in_sleep && !external_awake { + tracing::debug!( + "Sleep entity with config id not spawned: {}", + entity.entity_id + ); + continue; + } + + let blueprint_config = blueprint_config_data::get(&entity.blueprint_type); + let template_config = template_config_data::get(&entity.blueprint_type); + if blueprint_config.is_none() || template_config.is_none() { + continue; + } + + let entity_logic: EntityLogic = blueprint_config.unwrap().entity_logic; + let (config_type, entity_type, mut entity_state) = match entity_logic { + EntityLogic::Item => ( + EntityConfigType::Level, + EEntityType::SceneItem, + EntityState::Default, + ), + EntityLogic::Animal => ( + EntityConfigType::Level, + EEntityType::Animal, + EntityState::Default, + ), + EntityLogic::Monster => ( + EntityConfigType::Level, + EEntityType::Monster, + EntityState::Born, + ), + EntityLogic::Vehicle => ( + EntityConfigType::Level, + EEntityType::Vehicle, + EntityState::Default, + ), + EntityLogic::Npc => ( + EntityConfigType::Level, + EEntityType::Npc, + EntityState::Default, + ), + EntityLogic::Vision => ( + EntityConfigType::Level, + EEntityType::Vision, + EntityState::Default, + ), + EntityLogic::ClientOnly => ( + EntityConfigType::Level, + EEntityType::ClientOnly, + EntityState::Default, + ), + EntityLogic::ServerOnly => { tracing::debug!( - "Sleep entity with config id not spawned: {}", + "Unhandled entity to be added of logic: {:?} with blueprint_type {} and id: {}", + entity_logic, + entity.blueprint_type, entity.entity_id ); continue; } + EntityLogic::Custom => ( + EntityConfigType::Level, + EEntityType::Custom, + EntityState::Default, + ), + }; - let blueprint_config = blueprint_config_data::get(&entity.blueprint_type); - let template_config = template_config_data::get(&entity.blueprint_type); - if blueprint_config.is_none() || template_config.is_none() { - continue; - } - - let entity_logic: EntityLogic = blueprint_config.unwrap().entity_logic; - let (config_type, entity_type, mut entity_state) = match entity_logic { - EntityLogic::Item => ( - EntityConfigType::Level, - EEntityType::SceneItem, - EntityState::Default, - ), - EntityLogic::Animal => ( - EntityConfigType::Level, - EEntityType::Animal, - EntityState::Default, - ), - EntityLogic::Monster => ( - EntityConfigType::Level, - EEntityType::Monster, - EntityState::Born, - ), - EntityLogic::Vehicle => ( - EntityConfigType::Level, - EEntityType::Vehicle, - EntityState::Default, - ), - EntityLogic::Npc => ( - EntityConfigType::Level, - EEntityType::Npc, - EntityState::Default, - ), - EntityLogic::Vision => ( - EntityConfigType::Level, - EEntityType::Vision, - EntityState::Default, - ), - EntityLogic::ClientOnly => ( - EntityConfigType::Level, - EEntityType::ClientOnly, - EntityState::Default, - ), - EntityLogic::ServerOnly => { - tracing::debug!("Unhandled entity to be added of logic: {:?} with blueprint_type {} and id: {}", entity_logic, entity.blueprint_type, entity.entity_id); - continue; - } - EntityLogic::Custom => ( - EntityConfigType::Level, - EEntityType::Custom, - EntityState::Default, - ), - }; - - if entity.in_sleep { - entity_state = EntityState::Sleep; - } - - let config_id = entity.entity_id as i32; // TODO: i64???? - let map_id = entity.map_id; - let components: ComponentsData = entity - .components_data - .merge_with_template(&template_config.unwrap().components_data); - let tmp_entity = world.create_entity(config_id, config_type.into(), map_id); - let mut builder = world.create_builder(tmp_entity); - builder - .with(ComponentContainer::EntityConfig(EntityConfig { - camp: components - .base_info_component - .as_ref() - .and_then(|b| b.camp) - .unwrap_or(0), - config_id, - config_type, - entity_type, - entity_state, - })) - .with(ComponentContainer::Position(Position(Transform::from( - &entity.transform[..], - )))) - .with(ComponentContainer::Visibility(Visibility { - is_visible: true, - is_actor_visible: true, - })) - // Some entities may not actually have movement, but it's okay since we won't - // receive move package push for them - .with(ComponentContainer::Movement(Movement::default())); - - build_autonomous_component(&mut builder, player.basic_info.id, entity_logic); - build_interact_component(&mut builder, &components); - build_tags_components(&mut builder, &components, player, blueprint_config.unwrap().entity_type, config_id as i64); - build_attribute_component(&mut builder, &components, player.location.instance_id); - build_ai_components(&mut builder, &components); - added_entities.push(builder.build()); + if entity.in_sleep { + entity_state = EntityState::Sleep; } + + let config_id = entity.entity_id as i32; // TODO: i64???? + let map_id = entity.map_id; + let components: ComponentsData = entity + .components_data + .merge_with_template(&template_config.unwrap().components_data); + let tmp_entity = world.create_entity(config_id, config_type.into(), map_id); + let mut builder = world.create_builder(tmp_entity); + builder + .with(ComponentContainer::EntityConfig(EntityConfig { + camp: components + .base_info_component + .as_ref() + .and_then(|b| b.camp) + .unwrap_or(0), + config_id, + config_type, + entity_type, + entity_state, + })) + .with(ComponentContainer::Position(Position(Transform::from( + &entity.transform[..], + )))) + .with(ComponentContainer::Visibility(Visibility { + is_visible: true, + is_actor_visible: true, + })) + // Some entities may not actually have movement, but it's okay since we won't + // receive move package push for them + .with(ComponentContainer::Movement(Movement::default())); + + build_autonomous_component(&mut builder, ctx.player.basic_info.id, entity_logic); + build_interact_component(&mut builder, &components); + build_tags_components( + &mut builder, + &components, + ctx.player, + blueprint_config.unwrap().entity_type, + config_id as i64, + ); + build_attribute_component(&mut builder, &components, ctx.player.location.instance_id); + build_ai_components(&mut builder, &components); + added_entities.push(builder.build()); } - let world_ref = player.world.borrow(); - let world = world_ref.get_world_entity(); + let world = ctx.world.get_world_entity(); // Since kuro has issues, we can only send one for entity in added_entities { + // TODO: For COOP find a way to get players from world let mut pb = EntityPb { id: entity.entity_id as i64, // TODO: Should be i64 ..Default::default() @@ -459,7 +480,7 @@ pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], extern .into_iter() .for_each(|comp| comp.set_pb_data(&mut pb)); - player.notify(EntityAddNotify { + ctx.player.notify(EntityAddNotify { entity_pbs: vec![pb], remove_tag_ids: true, }); @@ -504,7 +525,10 @@ fn build_tags_components( if let Some(entity_state_component) = &components.entity_state_component { let state = match entity_type { EntityType::Teleporter | EntityType::TemporaryTeleporter => { - let result = player.teleports.teleports_data.iter() + let result = player + .teleports + .teleports_data + .iter() .find(|teleporter| teleporter.entity_config_id == config_id); match result.is_some() { true => tag_utils::get_tag_id_by_name("关卡.Common.状态.激活"), diff --git a/wicked-waifus-http/src/lib.rs b/wicked-waifus-http/src/lib.rs index 2b880bf..4be9bd8 100644 --- a/wicked-waifus-http/src/lib.rs +++ b/wicked-waifus-http/src/lib.rs @@ -59,7 +59,10 @@ impl Application { } pub fn serve_dir(mut self, path: &str, dir: &str) -> Self { - self.router = self.router.nest_service(path, ServeDir::new(dir)); + self.router = match path { + "" | "/" => self.router.fallback_service(ServeDir::new(dir)), + _ => self.router.nest_service(path, ServeDir::new(dir)) + }; self } diff --git a/wicked-waifus-protocol-internal/proto/data.proto b/wicked-waifus-protocol-internal/proto/data.proto index 4e1a2b8..4873732 100644 --- a/wicked-waifus-protocol-internal/proto/data.proto +++ b/wicked-waifus-protocol-internal/proto/data.proto @@ -148,9 +148,33 @@ message PlayerInventoryWeaponData { int32 role_id = 7; } +message PhantomPropInfo { + int32 prop_id = 1; + int32 value = 2; +} + +message PlayerInventoryPhantomData { + int32 id = 1; + int32 func_value = 2; + int32 level = 3; + int32 exp = 4; + repeated PhantomPropInfo main_prop = 5; // TODO: repeated vs map + repeated PhantomPropInfo sub_prop = 6; // TODO: repeated vs map + int32 fetter_group_id = 7; + int32 skin_id = 8; + int32 role_id = 9; +} + +message PlayerInventoryPhantomLoadoutData { + int32 name = 1; + map incr_id = 2; // Key is position (0,1,2,3,4), value is incr_id +} + message PlayerInventoryData { map items = 1; - map weapons = 2; + map weapons = 2; // Key is incr_id + map echoes = 3; // Key is incr_id + map echo_presets = 4; // Key is loadout number } message PlayerTeleportData { @@ -201,6 +225,7 @@ message PlayerUnlockedSkinsData { repeated int32 weapon_skins = 2; repeated int32 fly_skins = 3; repeated int32 wing_skins = 4; + repeated int32 echo_skins = 5; } message PlayerSaveData {