Compare commits
No commits in common. "90179f1001cba53dd710f5a50448f6054f443622" and "44e7ec15279e44c53de5e2340076f174f1cbd30d" have entirely different histories.
90179f1001
...
44e7ec1527
32 changed files with 126 additions and 2681861 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -402,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
|
@ -416,7 +416,7 @@ checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
|
@ -724,19 +724,13 @@ dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.14.5",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -896,12 +890,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.6.0"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.15.0",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1933,7 +1927,7 @@ dependencies = [
|
||||||
"futures-intrusive",
|
"futures-intrusive",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"hex",
|
"hex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM rust:1.82-alpine3.20
|
FROM rust:1.81-alpine3.20
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
|
@ -2,5 +2,5 @@ FROM alpine:3.20
|
||||||
ARG MICROSERVICE
|
ARG MICROSERVICE
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=wicked-waifus-builder:1.4.0-SNAPSHOT /app/target/release/$MICROSERVICE ./service
|
COPY --from=camellya-builder:1.3.0-SNAPSHOT /app/target/release/$MICROSERVICE ./service
|
||||||
CMD ["./service"]
|
CMD ["./service"]
|
File diff suppressed because it is too large
Load diff
16
builder.bat
16
builder.bat
|
@ -1,12 +1,12 @@
|
||||||
docker build -t wicked-waifus-builder:1.4.0-SNAPSHOT -f Dockerfile-builder .
|
docker build -t camellya-builder:1.3.0-SNAPSHOT -f Dockerfile-builder .
|
||||||
|
|
||||||
docker build -t wicked-waifus-config-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
|
docker build -t camellya-config-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
|
docker build -t camellya-hotpatch-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-login-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
|
docker build -t camellya-login-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-gateway-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
|
docker build -t camellya-gateway-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-game-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
|
docker build -t camellya-game-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
|
||||||
|
|
||||||
docker rmi wicked-waifus-builder:1.4.0-SNAPSHOT
|
docker rmi camellya-builder:1.3.0-SNAPSHOT
|
||||||
|
|
||||||
: Persistence for the application
|
: Persistence for the application
|
||||||
: docker volume create wicked-waifus-postgres-vol
|
docker volume create camellya-postgres-vol
|
16
builder.sh
16
builder.sh
|
@ -1,12 +1,12 @@
|
||||||
docker build -t wicked-waifus-builder:1.4.0-SNAPSHOT -f Dockerfile-builder .
|
docker build -t camellya-builder:1.3.0-SNAPSHOT -f Dockerfile-builder .
|
||||||
|
|
||||||
docker build -t wicked-waifus-config-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
|
docker build -t camellya-config-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
|
docker build -t camellya-hotpatch-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-login-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
|
docker build -t camellya-login-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-gateway-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
|
docker build -t camellya-gateway-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
|
||||||
docker build -t wicked-waifus-game-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
|
docker build -t camellya-game-server:1.3.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
|
||||||
|
|
||||||
docker rmi wicked-waifus-builder:1.4.0-SNAPSHOT
|
docker rmi camellya-builder:1.3.0-SNAPSHOT
|
||||||
|
|
||||||
# Persistence for the application
|
# Persistence for the application
|
||||||
# docker volume create wicked-waifus-postgres-vol
|
docker volume create camellya-postgres-vol
|
|
@ -1,10 +1,10 @@
|
||||||
name: wicked-waifus-ps
|
name: camellya-ps
|
||||||
|
|
||||||
services:
|
services:
|
||||||
wicked-waifus-hotpatch-server:
|
camellya-hotpatch-server:
|
||||||
image: wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT
|
image: camellya-hotpatch-server:1.3.0-SNAPSHOT
|
||||||
depends_on:
|
depends_on:
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- '10002:10002'
|
- '10002:10002'
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
name: wicked-waifus-ps
|
name: camellya-ps
|
||||||
|
|
||||||
services:
|
services:
|
||||||
wicked-waifus-config-server:
|
camellya-config-server:
|
||||||
image: wicked-waifus-config-server:1.4.0-SNAPSHOT
|
image: camellya-config-server:1.3.0-SNAPSHOT
|
||||||
depends_on:
|
depends_on:
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- '10001:10001'
|
- '10001:10001'
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker/configserver.toml:/app/configserver.toml"
|
- "./docker/configserver.toml:/app/configserver.toml"
|
||||||
- "./assets/config:/app/assets/config"
|
- "./assets/config:/app/assets/config"
|
||||||
wicked-waifus-login-server:
|
camellya-login-server:
|
||||||
image: wicked-waifus-login-server:1.4.0-SNAPSHOT
|
image: camellya-login-server:1.3.0-SNAPSHOT
|
||||||
depends_on:
|
depends_on:
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- '5500:5500'
|
- '5500:5500'
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker/loginserver.toml:/app/loginserver.toml"
|
- "./docker/loginserver.toml:/app/loginserver.toml"
|
||||||
wicked-waifus-gateway-server:
|
camellya-gateway-server:
|
||||||
image: wicked-waifus-gateway-server:1.4.0-SNAPSHOT
|
image: camellya-gateway-server:1.3.0-SNAPSHOT
|
||||||
depends_on:
|
depends_on:
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
# Uncomment this if you want to have manual access
|
# Uncomment this if you want to have manual access
|
||||||
|
@ -31,10 +31,10 @@ services:
|
||||||
- '7777:7777/udp'
|
- '7777:7777/udp'
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker/gateway.toml:/app/gateway.toml"
|
- "./docker/gateway.toml:/app/gateway.toml"
|
||||||
wicked-waifus-game-server:
|
camellya-game-server:
|
||||||
image: wicked-waifus-game-server:1.4.0-SNAPSHOT
|
image: camellya-game-server:1.3.0-SNAPSHOT
|
||||||
depends_on:
|
depends_on:
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
# Uncomment this if you want to have manual access
|
# Uncomment this if you want to have manual access
|
||||||
# ports:
|
# ports:
|
||||||
|
@ -42,7 +42,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker/gameserver.toml:/app/gameserver.toml"
|
- "./docker/gameserver.toml:/app/gameserver.toml"
|
||||||
- "./assets/logic:/app/assets/logic"
|
- "./assets/logic:/app/assets/logic"
|
||||||
wicked-waifus-postgres:
|
camellya-postgres:
|
||||||
image: postgres:16.4-alpine3.20
|
image: postgres:16.4-alpine3.20
|
||||||
user: postgres
|
user: postgres
|
||||||
# Uncomment this if you want to have manual access
|
# Uncomment this if you want to have manual access
|
||||||
|
@ -57,7 +57,7 @@ services:
|
||||||
- "POSTGRES_PASSWORD=toor"
|
- "POSTGRES_PASSWORD=toor"
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker/postgres/scripts:/docker-entrypoint-initdb.d"
|
- "./docker/postgres/scripts:/docker-entrypoint-initdb.d"
|
||||||
- wicked-waifus-postgres-vol:/var/lib/postgresql/data
|
- camellya-postgres-vol:/var/lib/postgresql/data
|
||||||
volumes:
|
volumes:
|
||||||
wicked-waifus-postgres-vol:
|
camellya-postgres-vol:
|
||||||
external: true
|
external: true
|
|
@ -1,13 +1,13 @@
|
||||||
service_id = 2
|
service_id = 2
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
host = "wicked-waifus-postgres:5432"
|
host = "shorekeeper-postgres:5432"
|
||||||
user_name = "wicked_waifus_user"
|
user_name = "shorekeeper_user"
|
||||||
password = "wicked_waifus_pass"
|
password = "shorekeeper_pass"
|
||||||
db_name = "wicked_waifus_db"
|
db_name = "shorekeeper_db"
|
||||||
|
|
||||||
[service_end_point]
|
[service_end_point]
|
||||||
addr = "tcp://0.0.0.0:10004"
|
addr = "tcp://0.0.0.0:10004"
|
||||||
|
|
||||||
[gateway_end_point]
|
[gateway_end_point]
|
||||||
addr = "tcp://wicked-waifus-gateway-server:10003"
|
addr = "tcp://shorekeeper-gateway-server:10003"
|
||||||
|
|
|
@ -11,10 +11,10 @@ use_client_key = true
|
||||||
addr = "tcp://0.0.0.0:10003"
|
addr = "tcp://0.0.0.0:10003"
|
||||||
|
|
||||||
[game_server_end_point]
|
[game_server_end_point]
|
||||||
addr = "tcp://wicked-waifus-game-server:10004"
|
addr = "tcp://shorekeeper-game-server:10004"
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
host = "wicked-waifus-postgres:5432"
|
host = "shorekeeper-postgres:5432"
|
||||||
user_name = "wicked_waifus_user"
|
user_name = "shorekeeper_user"
|
||||||
password = "wicked_waifus_pass"
|
password = "shorekeeper_pass"
|
||||||
db_name = "wicked_waifus_db"
|
db_name = "shorekeeper_db"
|
||||||
|
|
|
@ -6,7 +6,7 @@ host = "host.docker.internal"
|
||||||
port = 7777
|
port = 7777
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
host = "wicked-waifus-postgres:5432"
|
host = "shorekeeper-postgres:5432"
|
||||||
user_name = "wicked_waifus_user"
|
user_name = "shorekeeper_user"
|
||||||
password = "wicked_waifus_pass"
|
password = "shorekeeper_pass"
|
||||||
db_name = "wicked_waifus_db"
|
db_name = "shorekeeper_db"
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
CREATE DATABASE wicked_waifus_db;
|
CREATE DATABASE camellya_db;
|
||||||
CREATE USER wicked_waifus_user WITH encrypted password 'wicked_waifus_pass';
|
CREATE USER camellya_user WITH encrypted password 'camellya_pass';
|
||||||
GRANT ALL PRIVILEGES ON DATABASE wicked_waifus_db to wicked_waifus_user;
|
GRANT ALL PRIVILEGES ON DATABASE camellya_db to camellya_user;
|
|
@ -1,2 +1,2 @@
|
||||||
\c wicked_waifus_db;
|
\c camellya_db;
|
||||||
GRANT ALL ON SCHEMA public TO wicked_waifus_user;
|
GRANT ALL ON SCHEMA public TO camellya_user;
|
|
@ -1,19 +1,15 @@
|
||||||
use shorekeeper_protocol::{EEntityType, EntityConfigType, EntityState};
|
use shorekeeper_protocol::EntityConfigType;
|
||||||
|
|
||||||
use crate::logic::ecs::component::Component;
|
use crate::logic::ecs::component::Component;
|
||||||
|
|
||||||
pub struct EntityConfig {
|
pub struct EntityConfig {
|
||||||
pub config_id: i32,
|
pub config_id: i32,
|
||||||
pub config_type: EntityConfigType,
|
pub config_type: EntityConfigType,
|
||||||
pub entity_type: EEntityType,
|
|
||||||
pub entity_state: EntityState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for EntityConfig {
|
impl Component for EntityConfig {
|
||||||
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
||||||
pb.config_id = self.config_id;
|
pb.config_id = self.config_id;
|
||||||
pb.config_type = self.config_type.into();
|
pb.config_type = self.config_type.into();
|
||||||
pb.entity_type = self.entity_type.into();
|
|
||||||
pb.entity_state = self.entity_state.into();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
use crate::logic::ecs::component::Component;
|
|
||||||
use shorekeeper_protocol::entity_component_pb::ComponentPb;
|
|
||||||
use shorekeeper_protocol::{DFsm, DFsmBlackBoard, EntityComponentPb, EntityFsmComponentPb, FsmCustomBlackboardDatas};
|
|
||||||
|
|
||||||
pub struct Fsm {
|
|
||||||
pub fsms: Vec<DFsm>,
|
|
||||||
pub hash_code: i32,
|
|
||||||
pub common_hash_code: i32,
|
|
||||||
pub black_board: Vec<DFsmBlackBoard>,
|
|
||||||
pub fsm_custom_blackboard_datas: Option<FsmCustomBlackboardDatas>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for Fsm {
|
|
||||||
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
|
||||||
pb.component_pbs.push(EntityComponentPb {
|
|
||||||
component_pb: Some(ComponentPb::EntityFsmComponentPb(EntityFsmComponentPb {
|
|
||||||
fsms: self.fsms.clone(),
|
|
||||||
hash_code: self.hash_code,
|
|
||||||
common_hash_code: self.common_hash_code,
|
|
||||||
black_board: self.black_board.clone(),
|
|
||||||
fsm_custom_blackboard_datas: self.fsm_custom_blackboard_datas.clone(),
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,8 +7,6 @@ mod player_entity_marker;
|
||||||
mod position;
|
mod position;
|
||||||
mod visibility;
|
mod visibility;
|
||||||
mod vision_skill;
|
mod vision_skill;
|
||||||
mod monster_ai;
|
|
||||||
mod fsm;
|
|
||||||
|
|
||||||
pub use attribute::Attribute;
|
pub use attribute::Attribute;
|
||||||
pub use entity_config::EntityConfig;
|
pub use entity_config::EntityConfig;
|
||||||
|
@ -19,5 +17,3 @@ pub use player_entity_marker::PlayerEntityMarker;
|
||||||
pub use position::Position;
|
pub use position::Position;
|
||||||
pub use visibility::Visibility;
|
pub use visibility::Visibility;
|
||||||
pub use vision_skill::VisionSkill;
|
pub use vision_skill::VisionSkill;
|
||||||
pub use monster_ai::MonsterAi;
|
|
||||||
pub use fsm::Fsm;
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
use crate::logic::ecs::component::Component;
|
|
||||||
use shorekeeper_protocol::entity_component_pb::ComponentPb;
|
|
||||||
use shorekeeper_protocol::{EntityComponentPb, MonsterAiComponentPb};
|
|
||||||
|
|
||||||
pub struct MonsterAi {
|
|
||||||
pub weapon_id: i32,
|
|
||||||
pub hatred_group_id: i64,
|
|
||||||
pub ai_team_init_id: i32,
|
|
||||||
pub combat_message_id: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for MonsterAi {
|
|
||||||
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
|
||||||
pb.component_pbs.push(EntityComponentPb {
|
|
||||||
component_pb: Some(ComponentPb::MonsterAiComponentPb(MonsterAiComponentPb {
|
|
||||||
weapon_id: self.weapon_id,
|
|
||||||
hatred_group_id: self.hatred_group_id,
|
|
||||||
ai_team_init_id: self.ai_team_init_id,
|
|
||||||
combat_message_id: self.combat_message_id,
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,8 +32,6 @@ impl_component_container! {
|
||||||
Movement;
|
Movement;
|
||||||
Equip;
|
Equip;
|
||||||
VisionSkill;
|
VisionSkill;
|
||||||
MonsterAi;
|
|
||||||
Fsm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Component {
|
pub trait Component {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use shorekeeper_protocol::{EntityActiveRequest, EntityActiveResponse, EntityLoadCompleteRequest,
|
use crate::{logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
||||||
EntityLoadCompleteResponse, EntityOnLandedRequest,
|
use shorekeeper_protocol::entity_component_pb::ComponentPb;
|
||||||
EntityOnLandedResponse, EntityPb, EntityPositionRequest,
|
use shorekeeper_protocol::{
|
||||||
EntityPositionResponse, ErrorCode, MovePackagePush};
|
EntityActiveRequest, EntityActiveResponse, EntityComponentPb, EntityLoadCompleteRequest,
|
||||||
|
EntityLoadCompleteResponse, EntityOnLandedRequest, EntityOnLandedResponse,
|
||||||
use crate::{logic, logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
EntityPositionRequest, EntityPositionResponse, ErrorCode, MovePackagePush,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn on_entity_active_request(
|
pub fn on_entity_active_request(
|
||||||
player: &Player,
|
player: &Player,
|
||||||
|
@ -22,27 +23,18 @@ pub fn on_entity_active_request(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let component_pbs = {
|
if let (Some(position), Some(attribute)) =
|
||||||
let mut pb = EntityPb {
|
|
||||||
id: request.entity_id,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
query_components!(world, request.entity_id, Position, Attribute)
|
||||||
{
|
{
|
||||||
response.is_visible = true;
|
response.is_visible = true;
|
||||||
response.pos = Some(position.0.get_position_protobuf());
|
response.pos = Some(position.0.get_position_protobuf());
|
||||||
response.rot = Some(position.0.get_rotation_protobuf());
|
response.rot = Some(position.0.get_rotation_protobuf());
|
||||||
|
|
||||||
response.component_pbs.extend_from_slice(&component_pbs);
|
response.component_pbs.push(EntityComponentPb {
|
||||||
|
component_pb: Some(ComponentPb::AttributeComponent(
|
||||||
|
attribute.build_entity_attribute(),
|
||||||
|
)),
|
||||||
|
});
|
||||||
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
response.error_code = ErrorCode::Success.into();
|
||||||
} else {
|
} else {
|
||||||
|
@ -93,47 +85,29 @@ pub fn on_entity_load_complete_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_move_package_push(player: &mut Player, push: MovePackagePush) {
|
pub fn on_move_package_push(player: &mut Player, push: MovePackagePush) {
|
||||||
for moving_entity in push.moving_entities {
|
let world_ref = player.world.borrow();
|
||||||
// Query components borrows world component so lets wrap it
|
let world = world_ref.get_world_entity();
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
|
|
||||||
if !world.is_in_all_world_map(moving_entity.entity_id as i32) {
|
for moving_entity in push.moving_entities {
|
||||||
tracing::debug!(
|
if !world.is_in_all_world_map(moving_entity.entity_id as i32) {
|
||||||
|
tracing::debug!(
|
||||||
"MovePackage: entity with id {} doesn't exist",
|
"MovePackage: entity with id {} doesn't exist",
|
||||||
moving_entity.entity_id
|
moving_entity.entity_id
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(mut movement) = query_components!(world, moving_entity.entity_id, Movement).0
|
let Some(mut movement) = query_components!(world, moving_entity.entity_id, Movement).0
|
||||||
else {
|
else {
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
"MovePackage: entity {} doesn't have movement component",
|
"MovePackage: entity {} doesn't have movement component",
|
||||||
moving_entity.entity_id
|
moving_entity.entity_id
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
movement
|
movement
|
||||||
.pending_movement_vec
|
.pending_movement_vec
|
||||||
.extend(moving_entity.move_infos);
|
.extend(moving_entity.move_infos);
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: review instance id vs map id in world
|
|
||||||
let map = logic::utils::quadrant_util::get_map(player.location.instance_id);
|
|
||||||
let quadrant_id = map.get_quadrant_id(
|
|
||||||
player.location.position.position.x * 100.0,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use shorekeeper_data::RawVectorData;
|
|
||||||
use shorekeeper_protocol::{Rotator, TransformData};
|
use shorekeeper_protocol::{Rotator, TransformData};
|
||||||
|
|
||||||
use super::Vector3f;
|
use super::Vector3f;
|
||||||
|
@ -48,12 +47,3 @@ impl Transform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&[RawVectorData]> for Transform {
|
|
||||||
fn from(transform: &[RawVectorData]) -> Self {
|
|
||||||
Self {
|
|
||||||
position: Vector3f::from(&transform[0]),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
use shorekeeper_data::RawVectorData;
|
|
||||||
use shorekeeper_protocol::{Vector, VectorData};
|
use shorekeeper_protocol::{Vector, VectorData};
|
||||||
|
|
||||||
#[derive(Default, Clone, PartialEq, Debug)]
|
#[derive(Default, Clone, PartialEq, Debug)]
|
||||||
|
@ -41,13 +40,3 @@ impl Vector3f {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&RawVectorData> for Vector3f {
|
|
||||||
fn from(transform: &RawVectorData) -> Self {
|
|
||||||
Self {
|
|
||||||
x: transform.x / 100.0,
|
|
||||||
y: transform.y / 100.0,
|
|
||||||
z: transform.z / 100.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
use common::time_util;
|
use common::time_util;
|
||||||
use shorekeeper_protocol::{
|
use shorekeeper_protocol::{
|
||||||
EEntityType, EntityState, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo,
|
EEntityType, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo,
|
||||||
EntityRemoveNotify, FightFormationNotifyInfo, FightRoleInfo, FightRoleInfos, FormationRoleInfo,
|
EntityRemoveNotify, FightFormationNotifyInfo, FightRoleInfo, FightRoleInfos, FormationRoleInfo,
|
||||||
GroupFormation, ItemPkgOpenNotify, LivingStatus, PbGetRoleListNotify, PlayerBasicData,
|
GroupFormation, ItemPkgOpenNotify, LivingStatus, PbGetRoleListNotify, PlayerBasicData,
|
||||||
PlayerFightFormations, PlayerRoleData, PlayerSaveData, ProtocolUnit, UpdateFormationNotify,
|
PlayerFightFormations, PlayerRoleData, PlayerSaveData, ProtocolUnit, UpdateFormationNotify,
|
||||||
|
@ -55,7 +55,6 @@ pub struct Player {
|
||||||
// Runtime
|
// Runtime
|
||||||
pub world: Rc<RefCell<World>>,
|
pub world: Rc<RefCell<World>>,
|
||||||
pub last_save_time: u64,
|
pub last_save_time: u64,
|
||||||
pub quadrant_id: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
|
@ -313,7 +312,6 @@ impl Player {
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
world: Rc::new(RefCell::new(World::new())),
|
world: Rc::new(RefCell::new(World::new())),
|
||||||
last_save_time: time_util::unix_timestamp(),
|
last_save_time: time_util::unix_timestamp(),
|
||||||
quadrant_id: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,10 @@ use std::{
|
||||||
|
|
||||||
use super::{ecs::world::World, player::Player, utils::world_util};
|
use super::{ecs::world::World, player::Player, utils::world_util};
|
||||||
use crate::logic::ecs::world::WorldEntity;
|
use crate::logic::ecs::world::WorldEntity;
|
||||||
use crate::{logic, player_save_task::{self, PlayerSaveReason}, session::Session};
|
use crate::{
|
||||||
|
player_save_task::{self, PlayerSaveReason},
|
||||||
|
session::Session,
|
||||||
|
};
|
||||||
|
|
||||||
const WATER_MASK: &str = include_str!("../../watermask-rr.js");
|
const WATER_MASK: &str = include_str!("../../watermask-rr.js");
|
||||||
const UID_FIX: &str = include_str!("../../uidfix.js");
|
const UID_FIX: &str = include_str!("../../uidfix.js");
|
||||||
|
@ -197,16 +200,6 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
content: CENSORSHIP_FIX.to_string(),
|
content: CENSORSHIP_FIX.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let map = logic::utils::quadrant_util::get_map(player.location.instance_id);
|
|
||||||
let quadrant_id = map.get_quadrant_id(
|
|
||||||
player.location.position.position.x * 100.0,
|
|
||||||
player.location.position.position.y * 100.0,
|
|
||||||
);
|
|
||||||
player.quadrant_id = quadrant_id;
|
|
||||||
|
|
||||||
let entities = map.get_initial_entities(quadrant_id);
|
|
||||||
world_util::add_entities(&player, &entities);
|
|
||||||
|
|
||||||
drop(player);
|
drop(player);
|
||||||
|
|
||||||
state
|
state
|
||||||
|
@ -231,7 +224,6 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
|
|
||||||
let _ = state.worlds.remove(&player_id);
|
let _ = state.worlds.remove(&player_id);
|
||||||
// TODO: kick co-op players from removed world
|
// TODO: kick co-op players from removed world
|
||||||
// TODO: Remove all entitie
|
|
||||||
|
|
||||||
player_save_task::push(
|
player_save_task::push(
|
||||||
player_id,
|
player_id,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub mod entity_serializer;
|
pub mod entity_serializer;
|
||||||
pub mod load_role_info;
|
pub mod load_role_info;
|
||||||
pub mod world_util;
|
pub mod world_util;
|
||||||
pub mod quadrant_util;
|
|
||||||
|
|
|
@ -1,230 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
use shorekeeper_data::LevelEntityConfigData;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct MapBounds {
|
|
||||||
x_max: f32,
|
|
||||||
x_min: f32,
|
|
||||||
x_translate: f32,
|
|
||||||
y_max: f32,
|
|
||||||
y_min: f32,
|
|
||||||
y_translate: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct Quadrant {
|
|
||||||
entities: HashMap<i64, &'static LevelEntityConfigData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Map {
|
|
||||||
bounds: MapBounds,
|
|
||||||
width: u64,
|
|
||||||
height: u64,
|
|
||||||
quadrants: HashMap<u64, Quadrant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Make it configurable?
|
|
||||||
const EDGE_SIZE: f32 = 1000000f32;
|
|
||||||
const EDGE_CHECK: f32 = EDGE_SIZE * 3.0f32;
|
|
||||||
|
|
||||||
pub(crate) static MAP_TABLE: OnceLock<HashMap<i32, Map>> = OnceLock::new();
|
|
||||||
|
|
||||||
impl MapBounds {
|
|
||||||
fn find_max_min(slice: &[&LevelEntityConfigData]) -> (Self, bool) {
|
|
||||||
let mut x_max = 0f32;
|
|
||||||
let mut x_min = 0f32;
|
|
||||||
|
|
||||||
let mut y_max = 0f32;
|
|
||||||
let mut y_min = 0f32;
|
|
||||||
|
|
||||||
// Find max and min coordinates
|
|
||||||
for entity in slice.iter() {
|
|
||||||
if entity.transform[0].x < x_min { x_min = entity.transform[0].x }
|
|
||||||
if entity.transform[0].x > x_max { x_max = entity.transform[0].x }
|
|
||||||
|
|
||||||
if entity.transform[0].y < y_min { y_min = entity.transform[0].y }
|
|
||||||
if entity.transform[0].y > y_max { y_max = entity.transform[0].y }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f32::abs(x_max - x_min) < EDGE_CHECK) || (f32::abs(y_max - y_min) < EDGE_CHECK) {
|
|
||||||
// TODO: Handle this special case, since all entities fit, no need for quadrant
|
|
||||||
|
|
||||||
// Move everything to positive coordinates to prevent corner cases
|
|
||||||
let (x_max, x_min, x_translate) = recenter_map(x_max, x_min);
|
|
||||||
let (y_max, y_min, y_translate) = recenter_map(y_max, y_min);
|
|
||||||
|
|
||||||
(MapBounds { x_max, x_min, x_translate, y_max, y_min, y_translate }, false)
|
|
||||||
} else {
|
|
||||||
// Round to edge
|
|
||||||
x_max = round_max_coordinate(x_max, EDGE_SIZE);
|
|
||||||
x_min = round_min_coordinate(x_min, EDGE_SIZE);
|
|
||||||
y_max = round_max_coordinate(y_max, EDGE_SIZE);
|
|
||||||
y_min = round_min_coordinate(y_min, EDGE_SIZE);
|
|
||||||
|
|
||||||
// Adding bounds to prevent OOB when moving
|
|
||||||
x_max += EDGE_SIZE;
|
|
||||||
x_min -= EDGE_SIZE;
|
|
||||||
y_max += EDGE_SIZE;
|
|
||||||
y_min -= EDGE_SIZE;
|
|
||||||
|
|
||||||
// Move everything to positive coordinates to prevent corner cases
|
|
||||||
let (x_max, x_min, x_translate) = recenter_map(x_max, x_min);
|
|
||||||
let (y_max, y_min, y_translate) = recenter_map(y_max, y_min);
|
|
||||||
|
|
||||||
(MapBounds { x_max, x_min, x_translate, y_max, y_min, y_translate }, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Quadrant {
|
|
||||||
fn insert_entity(&mut self, entity_id: i64, entity: &'static LevelEntityConfigData) {
|
|
||||||
self.entities.insert(entity_id, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_entities(&self) -> Vec<&LevelEntityConfigData> {
|
|
||||||
self.entities
|
|
||||||
.iter()
|
|
||||||
.map(|(_, v)| *v)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Map {
|
|
||||||
fn insert_entity(&mut self, entity: &'static LevelEntityConfigData) {
|
|
||||||
let index = self.get_quadrant_id(entity.transform[0].x, entity.transform[0].y);
|
|
||||||
self.quadrants.entry(index).or_default().insert_entity(entity.entity_id, entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_neighbour_cells(&self, quadrant_id: u64) -> [u64; 9] {
|
|
||||||
let x = quadrant_id % self.width;
|
|
||||||
let y = (quadrant_id - x) / self.width;
|
|
||||||
return [
|
|
||||||
(self.width * (y - 1)) + (x - 1),
|
|
||||||
(self.width * (y - 1)) + (x),
|
|
||||||
(self.width * (y - 1)) + (x + 1),
|
|
||||||
(self.width * (y)) + (x - 1),
|
|
||||||
(self.width * (y)) + (x),
|
|
||||||
(self.width * (y)) + (x + 1),
|
|
||||||
(self.width * (y + 1)) + (x - 1),
|
|
||||||
(self.width * (y + 1)) + (x),
|
|
||||||
(self.width * (y + 1)) + (x + 1),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_quadrant_differences(&self, discriminant: [u64; 9], discriminator: [u64; 9]) -> Vec<&LevelEntityConfigData> {
|
|
||||||
let mut output = Vec::new();
|
|
||||||
for quadrant in discriminant {
|
|
||||||
if !discriminator.contains(&quadrant) {
|
|
||||||
if let Some(quadrant) = &self.quadrants.get(&quadrant) {
|
|
||||||
output.extend_from_slice(&quadrant.get_entities())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_quadrant_id(&self, x: f32, y: f32) -> u64 {
|
|
||||||
let width: u64 = unsafe {
|
|
||||||
f32::to_int_unchecked(
|
|
||||||
f32::trunc(
|
|
||||||
(self.bounds.x_max + self.bounds.x_translate - x) / EDGE_SIZE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let height: u64 = unsafe {
|
|
||||||
f32::to_int_unchecked(
|
|
||||||
f32::trunc(
|
|
||||||
(self.bounds.y_max + self.bounds.y_translate - y) / EDGE_SIZE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
};
|
|
||||||
(self.width * height) + width
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_initial_entities(&self, quadrant_id: u64) -> Vec<&LevelEntityConfigData> {
|
|
||||||
let quadrants = self.get_neighbour_cells(quadrant_id);
|
|
||||||
let mut output = Vec::new();
|
|
||||||
for quadrant in quadrants {
|
|
||||||
if let Some(quadrant) = &self.quadrants.get(&quadrant) {
|
|
||||||
output.extend_from_slice(&quadrant.get_entities())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_update_entities(&self, old_quadrant_id: u64, new_quadrant_id: u64) -> (Vec<&LevelEntityConfigData>, Vec<&LevelEntityConfigData>) {
|
|
||||||
let old_quadrants = self.get_neighbour_cells(old_quadrant_id);
|
|
||||||
let new_quadrants = self.get_neighbour_cells(new_quadrant_id);
|
|
||||||
|
|
||||||
let entities_to_remove = self.collect_quadrant_differences(old_quadrants, new_quadrants);
|
|
||||||
let entities_to_add = self.collect_quadrant_differences(new_quadrants, old_quadrants);
|
|
||||||
|
|
||||||
(entities_to_remove, entities_to_add)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn maps_iter() -> std::collections::hash_map::Iter<'static, i32, Map> {
|
|
||||||
MAP_TABLE.get().unwrap().iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initialize_quadrant_system() {
|
|
||||||
let mut map_grouped_entities: HashMap<i32, Vec<&LevelEntityConfigData>> = HashMap::new();
|
|
||||||
for (_, entity) in shorekeeper_data::level_entity_config_data::iter() {
|
|
||||||
map_grouped_entities.entry(entity.map_id).or_default().push(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut maps: HashMap<i32, Map> = HashMap::new();
|
|
||||||
for (map_id, entities) in map_grouped_entities {
|
|
||||||
let (bounds, _quadrant_enabled) = MapBounds::find_max_min(&entities[..]);
|
|
||||||
let width = unsafe { f32::to_int_unchecked((bounds.x_max - bounds.x_min) / EDGE_SIZE) };
|
|
||||||
let height = unsafe { f32::to_int_unchecked((bounds.y_max - bounds.y_min) / EDGE_SIZE) };
|
|
||||||
let map = maps.entry(map_id).or_insert(
|
|
||||||
Map {
|
|
||||||
bounds: bounds.clone(),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
quadrants: HashMap::new(),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
for entity in entities {
|
|
||||||
map.insert_entity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = MAP_TABLE.set(maps);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_map(map_id: i32) -> &'static Map {
|
|
||||||
// TODO: Error check for map id
|
|
||||||
MAP_TABLE.get().unwrap().get(&map_id).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recenter_map(max: f32, min: f32) -> (f32, f32, f32) {
|
|
||||||
match min < 0.0 {
|
|
||||||
true => (max + f32::abs(min), 0.0, min),
|
|
||||||
false => (max, min, 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn round_max_coordinate(coordinate: f32, round: f32) -> f32 {
|
|
||||||
let rounded = f32::round(coordinate);
|
|
||||||
let remainder = rounded % round;
|
|
||||||
if remainder != 0f32 {
|
|
||||||
rounded + (if rounded > 0.0 { round } else { 0.0 } - remainder)
|
|
||||||
} else {
|
|
||||||
rounded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn round_min_coordinate(coordinate: f32, round: f32) -> f32 {
|
|
||||||
let rounded = f32::round(coordinate);
|
|
||||||
let remainder = rounded % round;
|
|
||||||
if remainder != 0f32 {
|
|
||||||
rounded + (remainder.signum() * (if rounded > 0.0 { 0.0 } else { round } - f32::abs(remainder)))
|
|
||||||
} else {
|
|
||||||
rounded
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,6 @@
|
||||||
use std::cell::{BorrowMutError, RefMut};
|
use crate::logic::ecs::world::World;
|
||||||
|
use crate::logic::player::Player;
|
||||||
use shorekeeper_data::{base_property_data, LevelEntityConfigData};
|
use crate::logic::utils::entity_serializer;
|
||||||
use shorekeeper_protocol::{DFsm, EEntityType, EntityAddNotify, EntityConfigType, EntityPb,
|
|
||||||
EntityRemoveInfo, EntityRemoveNotify, EntityState, FightRoleInfo,
|
|
||||||
FightRoleInfos, LivingStatus, SceneInformation, SceneMode,
|
|
||||||
ScenePlayerInformation, SceneTimeInfo};
|
|
||||||
|
|
||||||
use crate::logic::{
|
use crate::logic::{
|
||||||
components::{
|
components::{
|
||||||
Attribute, EntityConfig, Equip, Movement, OwnerPlayer, PlayerEntityMarker, Position,
|
Attribute, EntityConfig, Equip, Movement, OwnerPlayer, PlayerEntityMarker, Position,
|
||||||
|
@ -13,13 +8,12 @@ use crate::logic::{
|
||||||
},
|
},
|
||||||
ecs::component::ComponentContainer,
|
ecs::component::ComponentContainer,
|
||||||
};
|
};
|
||||||
use crate::logic::components::{Fsm, MonsterAi};
|
|
||||||
use crate::logic::ecs::entity::Entity;
|
|
||||||
use crate::logic::ecs::world::{World, WorldEntity};
|
|
||||||
use crate::logic::math::Transform;
|
|
||||||
use crate::logic::player::Player;
|
|
||||||
use crate::logic::utils::entity_serializer;
|
|
||||||
use crate::query_with;
|
use crate::query_with;
|
||||||
|
use shorekeeper_data::base_property_data;
|
||||||
|
use shorekeeper_protocol::{
|
||||||
|
EEntityType, EntityConfigType, FightRoleInfo, FightRoleInfos, LivingStatus, SceneInformation,
|
||||||
|
SceneMode, ScenePlayerInformation, SceneTimeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! create_player_entity_pb {
|
macro_rules! create_player_entity_pb {
|
||||||
|
@ -38,8 +32,6 @@ macro_rules! create_player_entity_pb {
|
||||||
.with(ComponentContainer::EntityConfig(EntityConfig {
|
.with(ComponentContainer::EntityConfig(EntityConfig {
|
||||||
config_id: role_id,
|
config_id: role_id,
|
||||||
config_type: EntityConfigType::Character,
|
config_type: EntityConfigType::Character,
|
||||||
entity_type: EEntityType::Player.into(),
|
|
||||||
entity_state: EntityState::Default
|
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::OwnerPlayer(OwnerPlayer($player_id)))
|
.with(ComponentContainer::OwnerPlayer(OwnerPlayer($player_id)))
|
||||||
.with(ComponentContainer::Position(Position($position)))
|
.with(ComponentContainer::Position(Position($position)))
|
||||||
|
@ -103,8 +95,6 @@ pub fn add_player_entities(player: &Player) {
|
||||||
.with(ComponentContainer::EntityConfig(EntityConfig {
|
.with(ComponentContainer::EntityConfig(EntityConfig {
|
||||||
config_id: role.role_id,
|
config_id: role.role_id,
|
||||||
config_type: EntityConfigType::Character,
|
config_type: EntityConfigType::Character,
|
||||||
entity_type: EEntityType::Player.into(),
|
|
||||||
entity_state: EntityState::Default,
|
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::OwnerPlayer(OwnerPlayer(
|
.with(ComponentContainer::OwnerPlayer(OwnerPlayer(
|
||||||
player.basic_info.id,
|
player.basic_info.id,
|
||||||
|
@ -173,15 +163,15 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
||||||
Position,
|
Position,
|
||||||
Equip
|
Equip
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find_map(|(_, _, owner, visibility, conf, pos, equip)| {
|
.find_map(|(_, _, owner, visibility, conf, pos, equip)| {
|
||||||
(sp.player_id == owner.0 && visibility.0).then_some((
|
(sp.player_id == owner.0 && visibility.0).then_some((
|
||||||
conf.config_id,
|
conf.config_id,
|
||||||
pos.0.clone(),
|
pos.0.clone(),
|
||||||
equip.weapon_id,
|
equip.weapon_id,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let active_characters = query_with!(
|
let active_characters = query_with!(
|
||||||
world.get_world_entity(),
|
world.get_world_entity(),
|
||||||
|
@ -189,8 +179,8 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
||||||
OwnerPlayer,
|
OwnerPlayer,
|
||||||
EntityConfig
|
EntityConfig
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(_, _, owner, _)| owner.0 == sp.player_id);
|
.filter(|(_, _, owner, _)| owner.0 == sp.player_id);
|
||||||
|
|
||||||
ScenePlayerInformation {
|
ScenePlayerInformation {
|
||||||
cur_role: cur_role_id,
|
cur_role: cur_role_id,
|
||||||
|
@ -219,118 +209,3 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_monster_entity(world: &mut WorldEntity, config_id: i32, map_id: i32, transform: Transform) -> Entity {
|
|
||||||
// TODO: Check for more components, AI and so
|
|
||||||
world.create_entity(config_id, EEntityType::Monster.into(), map_id)
|
|
||||||
.with(ComponentContainer::EntityConfig(EntityConfig {
|
|
||||||
config_id,
|
|
||||||
config_type: EntityConfigType::Level,
|
|
||||||
entity_type: EEntityType::Monster.into(),
|
|
||||||
entity_state: EntityState::Born,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::Position(Position(transform)))
|
|
||||||
.with(ComponentContainer::Visibility(Visibility(true)))
|
|
||||||
.with(ComponentContainer::Attribute(Attribute::from_data(
|
|
||||||
base_property_data::iter()
|
|
||||||
.find(|d| d.id == 600000100) // TODO: Implement monster stats
|
|
||||||
.unwrap(),
|
|
||||||
)))
|
|
||||||
.with(ComponentContainer::MonsterAi(MonsterAi {
|
|
||||||
weapon_id: 0,
|
|
||||||
hatred_group_id: 0,
|
|
||||||
ai_team_init_id: 100,
|
|
||||||
combat_message_id: 0,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::Fsm(Fsm {
|
|
||||||
fsms: vec![
|
|
||||||
DFsm {
|
|
||||||
fsm_id: 10007,
|
|
||||||
current_state: 10013,
|
|
||||||
flag: 0,
|
|
||||||
k_ts: 0,
|
|
||||||
},
|
|
||||||
DFsm {
|
|
||||||
fsm_id: 10007,
|
|
||||||
current_state: 10015,
|
|
||||||
flag: 0,
|
|
||||||
k_ts: 0,
|
|
||||||
},
|
|
||||||
DFsm {
|
|
||||||
fsm_id: 10007,
|
|
||||||
current_state: 10012,
|
|
||||||
flag: 0,
|
|
||||||
k_ts: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
hash_code: 0,
|
|
||||||
common_hash_code: 0,
|
|
||||||
black_board: vec![],
|
|
||||||
fsm_custom_blackboard_datas: None,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::Movement(Movement::default()))
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_entities(player: &Player, 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for entity_id in removed_entities {
|
|
||||||
player.notify(EntityRemoveNotify {
|
|
||||||
remove_infos: vec![EntityRemoveInfo { entity_id, r#type: 0 }],
|
|
||||||
is_remove: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData]) {
|
|
||||||
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 {
|
|
||||||
// TODO: review other types
|
|
||||||
tracing::debug!("Entity to be added of type: {}", entity.blueprint_type);
|
|
||||||
if entity.blueprint_type.contains("Monster") {
|
|
||||||
added_entities.push(build_monster_entity(
|
|
||||||
world,
|
|
||||||
entity.entity_id as i32, // TODO: Should be i64
|
|
||||||
entity.map_id,
|
|
||||||
Transform::from(&entity.transform[..]),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
// Since kuro has issues, we can only send one
|
|
||||||
for entity in added_entities {
|
|
||||||
let mut pb = EntityPb {
|
|
||||||
id: entity.entity_id as i64, // TODO: Should be i64
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
world.get_entity_components(entity.entity_id)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|comp| comp.set_pb_data(&mut pb));
|
|
||||||
|
|
||||||
player.notify(EntityAddNotify {
|
|
||||||
entity_pbs: vec![pb],
|
|
||||||
is_add: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,8 +20,7 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
::common::splash::print_splash();
|
::common::splash::print_splash();
|
||||||
::common::logging::init(::tracing::Level::DEBUG);
|
::common::logging::init(::tracing::Level::DEBUG);
|
||||||
shorekeeper_data::load_all_json_data("assets/logic/BinData")?;
|
shorekeeper_data::load_json_data("assets/logic/BinData")?;
|
||||||
logic::utils::quadrant_util::initialize_quadrant_system();
|
|
||||||
|
|
||||||
let database = Arc::new(shorekeeper_database::connect_to(&CONFIG.database).await?);
|
let database = Arc::new(shorekeeper_database::connect_to(&CONFIG.database).await?);
|
||||||
shorekeeper_database::run_migrations(database.as_ref()).await?;
|
shorekeeper_database::run_migrations(database.as_ref()).await?;
|
||||||
|
|
|
@ -26,12 +26,11 @@ async fn main() -> Result<()> {
|
||||||
LazyLock::new(|| config_util::load_or_create("hotpatch.toml"));
|
LazyLock::new(|| config_util::load_or_create("hotpatch.toml"));
|
||||||
|
|
||||||
::common::splash::print_splash();
|
::common::splash::print_splash();
|
||||||
::common::logging::init_axum(::tracing::Level::DEBUG);
|
::common::logging::init(::tracing::Level::DEBUG);
|
||||||
|
|
||||||
Application::new()
|
Application::new()
|
||||||
.get("/:env/client/:hash/:platform/config.json", get_config)
|
.get("/:env/client/:hash/:platform/config.json", get_config)
|
||||||
.with_encryption(&CONFIG.encryption)
|
.with_encryption(&CONFIG.encryption)
|
||||||
.with_logger()
|
|
||||||
.serve(&CONFIG.network)
|
.serve(&CONFIG.network)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{process, sync::LazyLock};
|
use std::{process, sync::LazyLock};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use config::{GatewayConfig, ServerConfig};
|
use config::{GatewayConfig, ServerConfig};
|
||||||
use shorekeeper_database::PgPool;
|
use shorekeeper_database::PgPool;
|
||||||
use shorekeeper_http::{Application, StatusCode};
|
use shorekeeper_http::{Application, StatusCode};
|
||||||
|
@ -22,7 +21,7 @@ async fn main() -> Result<()> {
|
||||||
LazyLock::new(|| ::common::config_util::load_or_create("loginserver.toml"));
|
LazyLock::new(|| ::common::config_util::load_or_create("loginserver.toml"));
|
||||||
|
|
||||||
::common::splash::print_splash();
|
::common::splash::print_splash();
|
||||||
::common::logging::init_axum(::tracing::Level::DEBUG);
|
::common::logging::init(::tracing::Level::DEBUG);
|
||||||
|
|
||||||
let Ok(pool) = shorekeeper_database::connect_to(&CONFIG.database).await else {
|
let Ok(pool) = shorekeeper_database::connect_to(&CONFIG.database).await else {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
|
@ -38,11 +37,10 @@ async fn main() -> Result<()> {
|
||||||
pool,
|
pool,
|
||||||
gateway: &CONFIG.gateway,
|
gateway: &CONFIG.gateway,
|
||||||
})
|
})
|
||||||
.get("/health", || async { StatusCode::OK })
|
.get("/health", || async { StatusCode::OK })
|
||||||
.get("/api/login", handler::handle_login_api_call)
|
.get("/api/login", handler::handle_login_api_call)
|
||||||
.with_logger()
|
.serve(&CONFIG.network)
|
||||||
.serve(&CONFIG.network)
|
.await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
use serde::Deserialize;
|
|
||||||
use crate::RawVectorData;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct LevelEntityConfigData {
|
|
||||||
pub id: i32,
|
|
||||||
pub map_id: i32,
|
|
||||||
pub entity_id: i64,
|
|
||||||
pub blueprint_type: String,
|
|
||||||
pub name: String,
|
|
||||||
pub in_sleep: bool,
|
|
||||||
pub is_hidden: bool,
|
|
||||||
pub area_id: i32,
|
|
||||||
pub transform: Vec<RawVectorData>,
|
|
||||||
// Schemaless property, any suggestions @xeondev??
|
|
||||||
pub components_data: serde_json::Value,
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
|
mod misc_data;
|
||||||
pub use misc_data::*;
|
pub use misc_data::*;
|
||||||
|
|
||||||
mod misc_data;
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum LoadDataError {
|
pub enum LoadDataError {
|
||||||
#[error("I/O error: {0}")]
|
#[error("I/O error: {0}")]
|
||||||
|
@ -30,7 +30,7 @@ macro_rules! json_data {
|
||||||
}
|
}
|
||||||
})*
|
})*
|
||||||
|
|
||||||
fn load_json_data(base_path: &str) -> Result<(), LoadDataError> {
|
pub fn load_json_data(base_path: &str) -> Result<(), LoadDataError> {
|
||||||
$(paste! {
|
$(paste! {
|
||||||
let json_content = std::fs::read_to_string(&format!("{}/{}.json", base_path, stringify!($table_type)))?;
|
let json_content = std::fs::read_to_string(&format!("{}/{}.json", base_path, stringify!($table_type)))?;
|
||||||
let _ = [<$table_type:snake _data>]::TABLE.set(serde_json::from_str(&json_content)?);
|
let _ = [<$table_type:snake _data>]::TABLE.set(serde_json::from_str(&json_content)?);
|
||||||
|
@ -41,50 +41,6 @@ macro_rules! json_data {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! json_hash_table_data {
|
|
||||||
($($table_type:ident, $key_param:expr;)*) => {
|
|
||||||
$(paste! {
|
|
||||||
mod [<$table_type:snake>];
|
|
||||||
pub use [<$table_type:snake>]::[<$table_type Data>];
|
|
||||||
})*
|
|
||||||
|
|
||||||
$(paste! {
|
|
||||||
pub mod [<$table_type:snake _data>] {
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
pub(crate) type Data = super::[<$table_type Data>];
|
|
||||||
pub(crate) static TABLE: OnceLock<HashMap<i64, Data>> = OnceLock::new();
|
|
||||||
|
|
||||||
pub fn iter() -> std::collections::hash_map::Iter<'static, i64, Data> {
|
|
||||||
TABLE.get().unwrap().iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})*
|
|
||||||
|
|
||||||
fn load_json_hash_table_data(base_path: &str) -> Result<(), LoadDataError> {
|
|
||||||
$(paste! {
|
|
||||||
let json_content = std::fs::read_to_string(&format!("{}/{}.json", base_path, stringify!($table_type)))?;
|
|
||||||
let _ = [<$table_type:snake _data>]::TABLE.set(
|
|
||||||
serde_json::from_str::<Vec<[<$table_type:snake _data>]::Data>>(&json_content)?
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|element| (element.$key_param, element))
|
|
||||||
.collect::<std::collections::HashMap<_, _>>()
|
|
||||||
);
|
|
||||||
})*
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_all_json_data(base_path: &str) -> Result<(), LoadDataError> {
|
|
||||||
load_json_data(base_path)?;
|
|
||||||
load_json_hash_table_data(base_path)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
json_data! {
|
json_data! {
|
||||||
RoleInfo;
|
RoleInfo;
|
||||||
WeaponConf;
|
WeaponConf;
|
||||||
|
@ -92,9 +48,4 @@ json_data! {
|
||||||
InstanceDungeon;
|
InstanceDungeon;
|
||||||
FunctionCondition;
|
FunctionCondition;
|
||||||
ExploreTools;
|
ExploreTools;
|
||||||
LordGym;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_hash_table_data! {
|
|
||||||
LevelEntityConfig, entity_id;
|
|
||||||
}
|
}
|
|
@ -26,28 +26,6 @@ impl VectorData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct RawVectorData {
|
|
||||||
pub x: f32,
|
|
||||||
pub y: f32,
|
|
||||||
pub z: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RawVectorData {
|
|
||||||
pub fn get_x(&self) -> f32 {
|
|
||||||
self.x
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_y(&self) -> f32 {
|
|
||||||
self.y
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_z(&self) -> f32 {
|
|
||||||
self.z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "PascalCase")]
|
#[serde(rename_all = "PascalCase")]
|
||||||
pub struct EntranceEntityData {
|
pub struct EntranceEntityData {
|
||||||
|
|
Loading…
Reference in a new issue