Support for Nested combat messages and JSPatch Notify from files (#2)
Reviewed-on: Shorekeeper/Shorekeeper#2 Co-authored-by: xavo95 <xavo95@xeondev.com> Co-committed-by: xavo95 <xavo95@xeondev.com>
This commit is contained in:
parent
e5892ed9e5
commit
96d1994fe2
31 changed files with 159 additions and 60 deletions
|
@ -1,4 +1,4 @@
|
||||||
FROM alpine:3.20 as release
|
FROM alpine:3.20
|
||||||
ARG MICROSERVICE
|
ARG MICROSERVICE
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub trait TomlConfig: DeserializeOwned {
|
||||||
const DEFAULT_TOML: &str;
|
const DEFAULT_TOML: &str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_or_create<'a, C>(path: &str) -> C
|
pub fn load_or_create<C>(path: &str) -> C
|
||||||
where
|
where
|
||||||
C: DeserializeOwned + TomlConfig,
|
C: DeserializeOwned + TomlConfig,
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub fn unix_timestamp() -> u64 {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_secs() as u64
|
.as_secs()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unix_timestamp_ms() -> u64 {
|
pub fn unix_timestamp_ms() -> u64 {
|
||||||
|
|
|
@ -26,10 +26,7 @@ macro_rules! impl_from_data {
|
||||||
|
|
||||||
impl Component for Attribute {
|
impl Component for Attribute {
|
||||||
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
||||||
pb.living_status = self
|
pb.living_status = (if self.is_alive() { LivingStatus::Alive } else { LivingStatus::Dead })
|
||||||
.is_alive()
|
|
||||||
.then_some(LivingStatus::Alive)
|
|
||||||
.unwrap_or(LivingStatus::Dead)
|
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
pb.component_pbs.push(EntityComponentPb {
|
pb.component_pbs.push(EntityComponentPb {
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod owner_player;
|
||||||
mod player_entity_marker;
|
mod player_entity_marker;
|
||||||
mod position;
|
mod position;
|
||||||
mod visibility;
|
mod visibility;
|
||||||
|
mod weapon;
|
||||||
|
|
||||||
pub use attribute::Attribute;
|
pub use attribute::Attribute;
|
||||||
pub use entity_config::EntityConfig;
|
pub use entity_config::EntityConfig;
|
||||||
|
@ -13,3 +14,4 @@ pub use owner_player::OwnerPlayer;
|
||||||
pub use player_entity_marker::PlayerEntityMarker;
|
pub use player_entity_marker::PlayerEntityMarker;
|
||||||
pub use position::Position;
|
pub use position::Position;
|
||||||
pub use visibility::Visibility;
|
pub use visibility::Visibility;
|
||||||
|
pub use weapon::Weapon;
|
||||||
|
|
19
game-server/src/logic/components/weapon.rs
Normal file
19
game-server/src/logic/components/weapon.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
use shorekeeper_protocol::{EntityComponentPb, EquipComponentPb};
|
||||||
|
use shorekeeper_protocol::entity_component_pb::ComponentPb;
|
||||||
|
use crate::logic::ecs::component::Component;
|
||||||
|
|
||||||
|
pub struct Weapon {
|
||||||
|
pub weapon_id: i32,
|
||||||
|
pub weapon_breach_level: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for Weapon {
|
||||||
|
fn set_pb_data(&self, pb: &mut shorekeeper_protocol::EntityPb) {
|
||||||
|
pb.component_pbs.push(EntityComponentPb {
|
||||||
|
component_pb: Some(ComponentPb::EquipComponent(EquipComponentPb {
|
||||||
|
weapon_id: self.weapon_id,
|
||||||
|
weapon_breach_level: self.weapon_breach_level,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ impl_component_container! {
|
||||||
Attribute;
|
Attribute;
|
||||||
PlayerEntityMarker;
|
PlayerEntityMarker;
|
||||||
Movement;
|
Movement;
|
||||||
|
Weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Component {
|
pub trait Component {
|
||||||
|
|
|
@ -59,6 +59,6 @@ macro_rules! query_components {
|
||||||
}),
|
}),
|
||||||
)*)
|
)*)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| ($( crate::ident_as_none!($comp), )*))
|
.unwrap_or_else(|| ($( $crate::ident_as_none!($comp), )*))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl World {
|
||||||
|
|
||||||
pub fn create_entity(&mut self) -> EntityBuilder {
|
pub fn create_entity(&mut self) -> EntityBuilder {
|
||||||
let entity = self.entity_manager.create();
|
let entity = self.entity_manager.create();
|
||||||
EntityBuilder::builder(entity, self.components.entry(entity).or_insert(Vec::new()))
|
EntityBuilder::builder(entity, self.components.entry(entity).or_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_world(&self, entity_id: i64) -> bool {
|
pub fn is_in_world(&self, entity_id: i64) -> bool {
|
||||||
|
|
|
@ -4,23 +4,23 @@ pub use scene::*;
|
||||||
use shorekeeper_protocol::message::Message;
|
use shorekeeper_protocol::message::Message;
|
||||||
|
|
||||||
macro_rules! handle_request {
|
macro_rules! handle_request {
|
||||||
($($name:ident;)*) => {
|
($($name:ident $(, $inner_package:ident)?;)*) => {
|
||||||
fn handle_request(player: &mut super::player::Player, mut msg: Message) {
|
fn handle_request(player: &mut super::player::Player, mut msg: Message) {
|
||||||
use ::shorekeeper_protocol::{MessageID, Protobuf};
|
use ::shorekeeper_protocol::{MessageID, Protobuf};
|
||||||
|
|
||||||
::paste::paste! {
|
::paste::paste! {
|
||||||
match msg.get_message_id() {
|
match msg.get_message_id() {
|
||||||
$(
|
$(
|
||||||
::shorekeeper_protocol::[<$name Request>]::MESSAGE_ID => {
|
::shorekeeper_protocol::$($inner_package::)?[<$name Request>]::MESSAGE_ID => {
|
||||||
let Ok(request) = ::shorekeeper_protocol::[<$name Request>]::decode(&*msg.remove_payload()) else {
|
let Ok(request) = ::shorekeeper_protocol::$($inner_package::)?[<$name Request>]::decode(&*msg.remove_payload()) else {
|
||||||
tracing::debug!("failed to decode {}, player_id: {}", stringify!([<$name Request>]), player.basic_info.id);
|
tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Request>]), player.basic_info.id);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::debug!("logic: processing request {}", stringify!([<$name Request>]));
|
tracing::debug!("logic: processing request {}", stringify!($($inner_package::)?[<$name Request>]));
|
||||||
|
|
||||||
let mut response = ::shorekeeper_protocol::[<$name Response>]::default();
|
let mut response = ::shorekeeper_protocol::$($inner_package::)?[<$name Response>]::default();
|
||||||
[<on_ $name:snake _request>](player, request, &mut response);
|
[<on_ $($inner_package:snake _)? $name:snake _request>](player, request, &mut response);
|
||||||
|
|
||||||
player.respond(response, msg.get_rpc_id());
|
player.respond(response, msg.get_rpc_id());
|
||||||
},
|
},
|
||||||
|
@ -33,20 +33,22 @@ macro_rules! handle_request {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! handle_push {
|
macro_rules! handle_push {
|
||||||
($($name:ident;)*) => {
|
($($name:ident $(, $inner_package:ident)?;)*) => {
|
||||||
fn handle_push(player: &mut super::player::Player, mut msg: Message) {
|
fn handle_push(player: &mut super::player::Player, mut msg: Message) {
|
||||||
use ::shorekeeper_protocol::{MessageID, Protobuf};
|
use ::shorekeeper_protocol::{MessageID, Protobuf};
|
||||||
|
|
||||||
::paste::paste! {
|
::paste::paste! {
|
||||||
match msg.get_message_id() {
|
match msg.get_message_id() {
|
||||||
$(
|
$(
|
||||||
::shorekeeper_protocol::[<$name Push>]::MESSAGE_ID => {
|
::shorekeeper_protocol::$($inner_package::)?[<$name Push>]::MESSAGE_ID => {
|
||||||
let Ok(push) = ::shorekeeper_protocol::[<$name Push>]::decode(&*msg.remove_payload()) else {
|
let Ok(push) = ::shorekeeper_protocol::$($inner_package::)?[<$name Push>]::decode(&*msg.remove_payload()) else {
|
||||||
tracing::debug!("failed to decode {}, player_id: {}", stringify!([<$name Push>]), player.basic_info.id);
|
tracing::debug!("failed to decode {}, player_id: {}", stringify!($($inner_package::)?[<$name Push>]), player.basic_info.id);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
[<on_ $name:snake _push>](player, push);
|
tracing::debug!("logic: processing push {}", stringify!($($inner_package::)?[<$name Push>]));
|
||||||
|
|
||||||
|
[<on_ $($inner_package:snake _)? $name:snake _push>](player, push);
|
||||||
},
|
},
|
||||||
)*
|
)*
|
||||||
unhandled => ::tracing::warn!("can't find handler for push with message_id={unhandled}")
|
unhandled => ::tracing::warn!("can't find handler for push with message_id={unhandled}")
|
||||||
|
@ -60,6 +62,7 @@ handle_request! {
|
||||||
UpdateSceneDate;
|
UpdateSceneDate;
|
||||||
EntityActive;
|
EntityActive;
|
||||||
EntityOnLanded;
|
EntityOnLanded;
|
||||||
|
CombatSendPack, combat_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_push! {
|
handle_push! {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use shorekeeper_protocol::{
|
||||||
EntityActiveRequest, EntityActiveResponse, EntityOnLandedRequest, EntityOnLandedResponse,
|
EntityActiveRequest, EntityActiveResponse, EntityOnLandedRequest, EntityOnLandedResponse,
|
||||||
ErrorCode, MovePackagePush, UpdateSceneDateRequest, UpdateSceneDateResponse,
|
ErrorCode, MovePackagePush, UpdateSceneDateRequest, UpdateSceneDateResponse,
|
||||||
};
|
};
|
||||||
|
use shorekeeper_protocol::combat_message::{CombatSendPackRequest, CombatSendPackResponse};
|
||||||
|
|
||||||
use crate::{logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
use crate::{logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
||||||
|
|
||||||
|
@ -13,6 +14,14 @@ pub fn on_update_scene_date_request(
|
||||||
response.error_code = ErrorCode::Success.into();
|
response.error_code = ErrorCode::Success.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_combat_message_combat_send_pack_request(
|
||||||
|
_player: &Player,
|
||||||
|
_request: CombatSendPackRequest,
|
||||||
|
response: &mut CombatSendPackResponse,
|
||||||
|
) {
|
||||||
|
response.error_code = ErrorCode::Success.into();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_entity_active_request(
|
pub fn on_entity_active_request(
|
||||||
player: &Player,
|
player: &Player,
|
||||||
request: EntityActiveRequest,
|
request: EntityActiveRequest,
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl Player {
|
||||||
// we need shorekeeper
|
// we need shorekeeper
|
||||||
// TODO: remove this part after implementing team switch
|
// TODO: remove this part after implementing team switch
|
||||||
if !self.role_list.iter().any(|r| r.role_id == 1505) {
|
if !self.role_list.iter().any(|r| r.role_id == 1505) {
|
||||||
self.role_list.push(Role::new(1505));
|
self.role_list.push(Role::new(1505, Some(21050036)));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.formation_list.clear();
|
self.formation_list.clear();
|
||||||
|
@ -126,8 +126,7 @@ impl Player {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.role_id_set
|
.role_id_set
|
||||||
.iter()
|
.iter()
|
||||||
.map(|id| self.role_list.iter().find(|r| r.role_id == *id))
|
.flat_map(|id| self.role_list.iter().find(|r| r.role_id == *id))
|
||||||
.flatten()
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +216,8 @@ impl Player {
|
||||||
|
|
||||||
fn create_main_character_role(name: String, sex: i32) -> Role {
|
fn create_main_character_role(name: String, sex: i32) -> Role {
|
||||||
let mut role = match sex {
|
let mut role = match sex {
|
||||||
0 => Role::new(Role::MAIN_CHARACTER_FEMALE_ID),
|
0 => Role::new(Role::MAIN_CHARACTER_FEMALE_ID, None),
|
||||||
1 => Role::new(Role::MAIN_CHARACTER_MALE_ID),
|
1 => Role::new(Role::MAIN_CHARACTER_MALE_ID, None),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use common::time_util;
|
use common::time_util;
|
||||||
|
pub use formation::RoleFormation;
|
||||||
use shorekeeper_data::role_info_data;
|
use shorekeeper_data::role_info_data;
|
||||||
use shorekeeper_protocol::{ArrayIntInt, RoleData, RoleInfo};
|
use shorekeeper_protocol::{ArrayIntInt, RoleData, RoleInfo};
|
||||||
|
|
||||||
mod formation;
|
mod formation;
|
||||||
pub use formation::RoleFormation;
|
|
||||||
|
|
||||||
pub struct Role {
|
pub struct Role {
|
||||||
pub role_id: i32,
|
pub role_id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -17,14 +16,19 @@ pub struct Role {
|
||||||
pub star: i32,
|
pub star: i32,
|
||||||
pub favor: i32,
|
pub favor: i32,
|
||||||
pub create_time: u32,
|
pub create_time: u32,
|
||||||
|
pub equip_weapon: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Role {
|
impl Role {
|
||||||
pub const MAIN_CHARACTER_MALE_ID: i32 = 1501;
|
pub const MAIN_CHARACTER_MALE_ID: i32 = 1501;
|
||||||
pub const MAIN_CHARACTER_FEMALE_ID: i32 = 1502;
|
pub const MAIN_CHARACTER_FEMALE_ID: i32 = 1502;
|
||||||
|
|
||||||
pub fn new(role_id: i32) -> Self {
|
pub fn new(role_id: i32, weapon_id: Option<i32>) -> Self {
|
||||||
let data = role_info_data::iter().find(|d| d.id == role_id).unwrap();
|
let data = role_info_data::iter().find(|d| d.id == role_id).unwrap();
|
||||||
|
let equip_weapon = match weapon_id {
|
||||||
|
None => data.init_weapon_item_id,
|
||||||
|
Some(x) => x,
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
role_id,
|
role_id,
|
||||||
|
@ -36,6 +40,7 @@ impl Role {
|
||||||
star: 0,
|
star: 0,
|
||||||
favor: 0,
|
favor: 0,
|
||||||
create_time: time_util::unix_timestamp() as u32,
|
create_time: time_util::unix_timestamp() as u32,
|
||||||
|
equip_weapon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +74,7 @@ impl Role {
|
||||||
star: data.star,
|
star: data.star,
|
||||||
favor: data.favor,
|
favor: data.favor,
|
||||||
create_time: data.create_time,
|
create_time: data.create_time,
|
||||||
|
equip_weapon: data.equip_weapon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +89,7 @@ impl Role {
|
||||||
star: self.star,
|
star: self.star,
|
||||||
favor: self.favor,
|
favor: self.favor,
|
||||||
create_time: self.create_time,
|
create_time: self.create_time,
|
||||||
|
equip_weapon: self.equip_weapon,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,9 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use common::time_util;
|
use common::time_util;
|
||||||
use shorekeeper_protocol::{message::Message, JoinSceneNotify, TransitionOptionPb};
|
use shorekeeper_protocol::{message::Message, JoinSceneNotify, TransitionOptionPb,
|
||||||
use shorekeeper_protocol::{AfterJoinSceneNotify, EnterGameResponse, PlayerSaveData};
|
AfterJoinSceneNotify, EnterGameResponse, JsPatchNotify};
|
||||||
|
use shorekeeper_protocol::{PlayerSaveData};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
player_save_task::{self, PlayerSaveReason},
|
player_save_task::{self, PlayerSaveReason},
|
||||||
|
@ -21,6 +22,9 @@ use crate::{
|
||||||
|
|
||||||
use super::{ecs::world::World, player::Player, utils::world_util};
|
use super::{ecs::world::World, player::Player, utils::world_util};
|
||||||
|
|
||||||
|
const WATER_MASK: &str = include_str!("../../watermask.js");
|
||||||
|
const UID_FIX: &str = include_str!("../../uidfix.js");
|
||||||
|
|
||||||
pub enum LogicInput {
|
pub enum LogicInput {
|
||||||
AddPlayer {
|
AddPlayer {
|
||||||
player_id: i32,
|
player_id: i32,
|
||||||
|
@ -105,8 +109,7 @@ fn logic_thread_func(receiver: mpsc::Receiver<LogicInput>, load: Arc<AtomicUsize
|
||||||
let mut world = world.borrow_mut();
|
let mut world = world.borrow_mut();
|
||||||
let mut players = world
|
let mut players = world
|
||||||
.player_ids()
|
.player_ids()
|
||||||
.map(|id| state.players.get(id).map(|pl| pl.borrow_mut()))
|
.flat_map(|id| state.players.get(id).map(|pl| pl.borrow_mut()))
|
||||||
.flatten()
|
|
||||||
.collect::<Box<_>>();
|
.collect::<Box<_>>();
|
||||||
|
|
||||||
super::systems::tick_systems(&mut world, &mut players);
|
super::systems::tick_systems(&mut world, &mut players);
|
||||||
|
@ -164,6 +167,14 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
scene_info: Some(scene_info),
|
scene_info: Some(scene_info),
|
||||||
transition_option: Some(TransitionOptionPb::default()),
|
transition_option: Some(TransitionOptionPb::default()),
|
||||||
});
|
});
|
||||||
|
player.notify(JsPatchNotify {
|
||||||
|
content: WATER_MASK.to_string(),
|
||||||
|
});
|
||||||
|
player.notify(JsPatchNotify {
|
||||||
|
content: UID_FIX
|
||||||
|
.replace("{PLAYER_USERNAME}", &player.basic_info.name)
|
||||||
|
.replace("{SELECTED_COLOR}", "50FC71"),
|
||||||
|
});
|
||||||
|
|
||||||
player.respond(EnterGameResponse::default(), enter_rpc_id);
|
player.respond(EnterGameResponse::default(), enter_rpc_id);
|
||||||
player.notify(AfterJoinSceneNotify::default());
|
player.notify(AfterJoinSceneNotify::default());
|
||||||
|
|
|
@ -11,8 +11,7 @@ pub fn build_scene_add_on_init_data(world: &World) -> PlayerSceneAoiData {
|
||||||
|
|
||||||
let mut aoi_data = PlayerSceneAoiData::default();
|
let mut aoi_data = PlayerSceneAoiData::default();
|
||||||
for entity in entities {
|
for entity in entities {
|
||||||
let mut pb = EntityPb::default();
|
let mut pb = EntityPb { id: entity.into(), ..Default::default() };
|
||||||
pb.id = entity.into();
|
|
||||||
|
|
||||||
world
|
world
|
||||||
.get_entity_components(entity)
|
.get_entity_components(entity)
|
||||||
|
|
|
@ -8,14 +8,13 @@ use crate::{
|
||||||
logic::{
|
logic::{
|
||||||
components::{
|
components::{
|
||||||
Attribute, EntityConfig, Movement, OwnerPlayer, PlayerEntityMarker, Position,
|
Attribute, EntityConfig, Movement, OwnerPlayer, PlayerEntityMarker, Position,
|
||||||
Visibility,
|
Visibility, Weapon
|
||||||
},
|
},
|
||||||
ecs::{component::ComponentContainer, world::World},
|
ecs::{component::ComponentContainer, world::World},
|
||||||
player::Player,
|
player::Player,
|
||||||
},
|
},
|
||||||
query_with,
|
query_with,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::entity_serializer;
|
use super::entity_serializer;
|
||||||
|
|
||||||
pub fn add_player_entities(world: &mut World, player: &Player) {
|
pub fn add_player_entities(world: &mut World, player: &Player) {
|
||||||
|
@ -44,6 +43,10 @@ pub fn add_player_entities(world: &mut World, player: &Player) {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)))
|
)))
|
||||||
.with(ComponentContainer::Movement(Movement::default()))
|
.with(ComponentContainer::Movement(Movement::default()))
|
||||||
|
.with(ComponentContainer::Weapon(Weapon {
|
||||||
|
weapon_id: role.equip_weapon,
|
||||||
|
weapon_breach_level: 0, // TODO: store this too
|
||||||
|
}))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
|
|
9
game-server/uidfix.js
Normal file
9
game-server/uidfix.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
setTimeout(() => {
|
||||||
|
const UiManager_1 = require("../Ui/UiManager");
|
||||||
|
const UE = require("ue");
|
||||||
|
const ControllerManagerBase_1 = require("../../Core/Framework/ControllerManagerBase");
|
||||||
|
|
||||||
|
const UiText = UiManager_1.UiManager.GetViewByName("UidView").GetText(0);
|
||||||
|
UiText.SetText("{PLAYER_USERNAME} - Reversed Rooms");
|
||||||
|
UiText.SetColor(UE. Color.FromHex("{SELECTED_COLOR}"));
|
||||||
|
}, 10000);
|
38
game-server/watermask.js
Normal file
38
game-server/watermask.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
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.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 = "discord.gg/reversedrooms";
|
||||||
|
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();
|
|
@ -867,7 +867,7 @@ impl<Output> Kcp<Output> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ts_flush = self.ts_flush;
|
let mut ts_flush = self.ts_flush;
|
||||||
let mut tm_packet = u32::max_value();
|
let mut tm_packet = u32::MAX;
|
||||||
|
|
||||||
if timediff(current, ts_flush) >= 10000 || timediff(current, ts_flush) < -10000 {
|
if timediff(current, ts_flush) >= 10000 || timediff(current, ts_flush) < -10000 {
|
||||||
ts_flush = current;
|
ts_flush = current;
|
||||||
|
@ -1142,7 +1142,7 @@ impl<Output: Write> Kcp<Output> {
|
||||||
let resent = if self.fastresend > 0 {
|
let resent = if self.fastresend > 0 {
|
||||||
self.fastresend
|
self.fastresend
|
||||||
} else {
|
} else {
|
||||||
u32::max_value()
|
u32::MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
let rtomin = if !self.nodelay { self.rx_rto >> 3 } else { 0 };
|
let rtomin = if !self.nodelay { self.rx_rto >> 3 } else { 0 };
|
||||||
|
@ -1381,7 +1381,7 @@ impl<Output: AsyncWrite + Unpin + Send> Kcp<Output> {
|
||||||
let resent = if self.fastresend > 0 {
|
let resent = if self.fastresend > 0 {
|
||||||
self.fastresend
|
self.fastresend
|
||||||
} else {
|
} else {
|
||||||
u32::max_value()
|
u32::MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
let rtomin = if !self.nodelay { self.rx_rto >> 3 } else { 0 };
|
let rtomin = if !self.nodelay { self.rx_rto >> 3 } else { 0 };
|
||||||
|
|
|
@ -140,7 +140,7 @@ async fn on_login_request(
|
||||||
|
|
||||||
session.player_id = Some(player_id);
|
session.player_id = Some(player_id);
|
||||||
response.code = ErrorCode::Success.into();
|
response.code = ErrorCode::Success.into();
|
||||||
response.timestamp = time_util::unix_timestamp() as i64;
|
response.timestamp = time_util::unix_timestamp_ms() as i64;
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"login success, user_id: {}, player_id: {}",
|
"login success, user_id: {}, player_id: {}",
|
||||||
|
|
|
@ -155,11 +155,11 @@ impl Session {
|
||||||
|
|
||||||
fn next_message(&mut self) -> Option<Message> {
|
fn next_message(&mut self) -> Option<Message> {
|
||||||
self.decoder.pop_with(|buf| {
|
self.decoder.pop_with(|buf| {
|
||||||
Message::decode(&buf)
|
Message::decode(buf)
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
"failed to decode a message, err: {err}, buf: {}",
|
"failed to decode a message, err: {err}, buf: {}",
|
||||||
hex::encode(&buf)
|
hex::encode(buf)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
|
|
|
@ -15,8 +15,7 @@ impl LengthFieldBasedDecoder {
|
||||||
|
|
||||||
pub fn input(&mut self, data: &[u8]) {
|
pub fn input(&mut self, data: &[u8]) {
|
||||||
self.ensure_capacity(data.len());
|
self.ensure_capacity(data.len());
|
||||||
|
self.buffer[self.cur_index..self.cur_index + data.len()].copy_from_slice(data);
|
||||||
(&mut self.buffer[self.cur_index..self.cur_index + data.len()]).copy_from_slice(data);
|
|
||||||
self.cur_index += data.len();
|
self.cur_index += data.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl UdpServer {
|
||||||
conv_id,
|
conv_id,
|
||||||
addr,
|
addr,
|
||||||
self.socket.clone(),
|
self.socket.clone(),
|
||||||
&self.protokey_helper,
|
self.protokey_helper,
|
||||||
self.db.clone(),
|
self.db.clone(),
|
||||||
);
|
);
|
||||||
self.session_mgr.add(conv_id, session);
|
self.session_mgr.add(conv_id, session);
|
||||||
|
|
|
@ -11,13 +11,10 @@ pub async fn handle_login_api_call(
|
||||||
tracing::debug!("login requested");
|
tracing::debug!("login requested");
|
||||||
|
|
||||||
let user_data = parameters.user_data;
|
let user_data = parameters.user_data;
|
||||||
let result = match login(&state, parameters).await {
|
let result = login(&state, parameters).await.unwrap_or_else(|err| {
|
||||||
Ok(result) => result,
|
|
||||||
Err(err) => {
|
|
||||||
tracing::warn!("login: internal error occurred {err:?}");
|
tracing::warn!("login: internal error occurred {err:?}");
|
||||||
schema::LoginResult::error(-1, String::from("Internal server error"))
|
schema::LoginResult::error(-1, String::from("Internal server error"))
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
Json(result.with_user_data(user_data))
|
Json(result.with_user_data(user_data))
|
||||||
}
|
}
|
||||||
|
@ -32,7 +29,7 @@ async fn login(state: &ServiceState, params: schema::LoginParameters) -> Result<
|
||||||
Some(account) => {
|
Some(account) => {
|
||||||
if let Some(ban_time_stamp) = account.ban_time_stamp {
|
if let Some(ban_time_stamp) = account.ban_time_stamp {
|
||||||
if time_util::unix_timestamp() < ban_time_stamp as u64 {
|
if time_util::unix_timestamp() < ban_time_stamp as u64 {
|
||||||
return Ok(schema::LoginResult::banned(String::from("You're banned MF"), ban_time_stamp as i64));
|
return Ok(schema::LoginResult::banned(String::from("You're banned MF"), ban_time_stamp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,12 @@ pub struct Application<S> {
|
||||||
|
|
||||||
impl Application<()> {
|
impl Application<()> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Application<()> {
|
||||||
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
router: Router::new(),
|
router: Router::new(),
|
||||||
state: (),
|
state: (),
|
||||||
|
|
|
@ -15,7 +15,7 @@ impl ServiceMessage {
|
||||||
w.write_u16::<LE>(self.rpc_id)?;
|
w.write_u16::<LE>(self.rpc_id)?;
|
||||||
w.write_u16::<LE>(self.message_id)?;
|
w.write_u16::<LE>(self.message_id)?;
|
||||||
w.write_u32::<LE>(self.data.len() as u32)?;
|
w.write_u32::<LE>(self.data.len() as u32)?;
|
||||||
w.write(&self.data)?;
|
w.write_all(&self.data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@ impl ServiceListener {
|
||||||
for message in data
|
for message in data
|
||||||
.into_vec()
|
.into_vec()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|b| ServiceMessage::decode(b.as_ref()))
|
.flat_map(|b| ServiceMessage::decode(b.as_ref()))
|
||||||
.flatten()
|
|
||||||
{
|
{
|
||||||
let _ = sender.send(message).await;
|
let _ = sender.send(message).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn main() {
|
||||||
let config_path = Path::new("proto/config.csv");
|
let config_path = Path::new("proto/config.csv");
|
||||||
if config_path.exists() {
|
if config_path.exists() {
|
||||||
println!("cargo:rerun-if-changed={config_file}");
|
println!("cargo:rerun-if-changed={config_file}");
|
||||||
impl_proto_config(config_path, &Path::new("generated/proto_config.rs")).unwrap();
|
impl_proto_config(config_path, Path::new("generated/proto_config.rs")).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let proto_file = "proto/shorekeeper.proto";
|
let proto_file = "proto/shorekeeper.proto";
|
||||||
|
|
|
@ -43,6 +43,7 @@ message RoleData {
|
||||||
repeated int32 models = 12;
|
repeated int32 models = 12;
|
||||||
repeated RoleSkillNodeData skill_node_state = 13;
|
repeated RoleSkillNodeData skill_node_state = 13;
|
||||||
int32 resonant_chain_group_index = 14;
|
int32 resonant_chain_group_index = 14;
|
||||||
|
int32 equip_weapon = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RoleFormationData {
|
message RoleFormationData {
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl Message {
|
||||||
let recv_crc = r.read_u32::<LE>()?;
|
let recv_crc = r.read_u32::<LE>()?;
|
||||||
|
|
||||||
let mut payload = vec![0u8; src.len() - r.position() as usize].into_boxed_slice();
|
let mut payload = vec![0u8; src.len() - r.position() as usize].into_boxed_slice();
|
||||||
r.read(&mut payload)?;
|
let _ = r.read(&mut payload)?;
|
||||||
|
|
||||||
let calc_crc = crc32fast::hash(&payload);
|
let calc_crc = crc32fast::hash(&payload);
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,6 @@ fn encrypt_aes256_ecb_pkcs7(
|
||||||
) -> Result<Box<[u8]>, InvalidLength> {
|
) -> Result<Box<[u8]>, InvalidLength> {
|
||||||
let cipher = Aes256::new_from_slice(session_key)?;
|
let cipher = Aes256::new_from_slice(session_key)?;
|
||||||
Ok(cipher
|
Ok(cipher
|
||||||
.encrypt_padded_vec::<Pkcs7>(&data[..])
|
.encrypt_padded_vec::<Pkcs7>(data)
|
||||||
.into_boxed_slice())
|
.into_boxed_slice())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue