mirror of
https://github.com/redstrate/Kawari.git
synced 2025-06-30 11:47:45 +00:00
parent
ad4edf801d
commit
9a3652fb42
4 changed files with 83 additions and 31 deletions
|
@ -11,7 +11,7 @@ use kawari::ipc::zone::{
|
|||
ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSpawn, PlayerStatus, SocialList,
|
||||
};
|
||||
use kawari::ipc::zone::{
|
||||
ClientTriggerCommand, ClientZoneIpcData, CommonSpawn, EventStart, GameMasterRank, OnlineStatus,
|
||||
ClientTriggerCommand, ClientZoneIpcData, EventStart, GameMasterRank, OnlineStatus,
|
||||
ServerZoneIpcData, ServerZoneIpcSegment, SocialListRequestType,
|
||||
};
|
||||
use kawari::opcodes::{ServerChatIpcType, ServerZoneIpcType};
|
||||
|
@ -79,7 +79,6 @@ pub fn spawn_client(connection: ZoneConnection) {
|
|||
ip: *ip,
|
||||
channel: send,
|
||||
actor_id: 0,
|
||||
common: CommonSpawn::default(),
|
||||
};
|
||||
let _ = my_send.send(handle);
|
||||
}
|
||||
|
@ -170,7 +169,6 @@ async fn client_loop(
|
|||
|
||||
let mut client_handle = client_handle.clone();
|
||||
client_handle.actor_id = actor_id;
|
||||
client_handle.common = connection.get_player_common_spawn(connection.exit_position, connection.exit_rotation);
|
||||
|
||||
// tell the server we exist, now that we confirmed we are a legitimate connection
|
||||
connection.handle.send(ToServer::NewClient(client_handle)).await;
|
||||
|
@ -326,11 +324,11 @@ async fn client_loop(
|
|||
.unwrap();
|
||||
}
|
||||
ClientZoneIpcData::FinishLoading { .. } => {
|
||||
// tell the server we loaded into the zone, so it can start sending us acors
|
||||
connection.handle.send(ToServer::ZoneLoaded(connection.id, connection.zone.as_ref().unwrap().id)).await;
|
||||
|
||||
let common = connection.get_player_common_spawn(connection.exit_position, connection.exit_rotation);
|
||||
|
||||
// tell the server we loaded into the zone, so it can start sending us acors
|
||||
connection.handle.send(ToServer::ZoneLoaded(connection.id, connection.zone.as_ref().unwrap().id, common.clone())).await;
|
||||
|
||||
let chara_details = database.find_chara_make(connection.player_data.content_id);
|
||||
|
||||
connection.send_inventory(false).await;
|
||||
|
@ -941,6 +939,7 @@ async fn client_loop(
|
|||
FromServer::ActionComplete(request) => connection.execute_action(request, &mut lua_player).await,
|
||||
FromServer::ActionCancelled() => connection.cancel_action().await,
|
||||
FromServer::UpdateConfig(actor_id, config) => connection.update_config(actor_id, config).await,
|
||||
FromServer::ActorEquip(actor_id, main_weapon_id, model_ids) => connection.update_equip(actor_id, main_weapon_id, model_ids).await,
|
||||
},
|
||||
None => break,
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ pub enum FromServer {
|
|||
ActionCancelled(),
|
||||
/// Update an actor's equip display flags.
|
||||
UpdateConfig(u32, Config),
|
||||
/// Update an actor's model IDs.
|
||||
ActorEquip(u32, u64, [u32; 10]),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -50,7 +52,6 @@ pub struct ClientHandle {
|
|||
pub ip: SocketAddr,
|
||||
pub channel: Sender<FromServer>,
|
||||
pub actor_id: u32,
|
||||
pub common: CommonSpawn,
|
||||
}
|
||||
|
||||
impl ClientHandle {
|
||||
|
@ -86,7 +87,7 @@ pub enum ToServer {
|
|||
ClientTrigger(ClientId, u32, ClientTrigger),
|
||||
/// The connection loaded into a zone.
|
||||
// TODO: the connection should not be in charge and telling the global server what zone they just loaded in! but this will work for now
|
||||
ZoneLoaded(ClientId, u16),
|
||||
ZoneLoaded(ClientId, u16, CommonSpawn),
|
||||
/// The connection left a zone.
|
||||
LeftZone(ClientId, u32, u16),
|
||||
/// The connection disconnected.
|
||||
|
@ -103,6 +104,8 @@ pub enum ToServer {
|
|||
ActionRequest(ClientId, u32, ActionRequest),
|
||||
/// We want to update our own equip display flags.
|
||||
Config(ClientId, u32, Config),
|
||||
/// Tell the server what models IDs we have equipped.
|
||||
Equip(ClientId, u32, u64, [u32; 10]),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -585,34 +585,47 @@ impl ZoneConnection {
|
|||
|
||||
// send them an appearance update
|
||||
if send_appearance_update {
|
||||
let ipc;
|
||||
let main_weapon_id;
|
||||
let model_ids;
|
||||
{
|
||||
let mut game_data = self.gamedata.lock().unwrap();
|
||||
let inventory = &self.player_data.inventory;
|
||||
|
||||
ipc = ServerZoneIpcSegment {
|
||||
main_weapon_id = inventory.get_main_weapon_id(&mut game_data);
|
||||
model_ids = inventory.get_model_ids(&mut game_data);
|
||||
}
|
||||
|
||||
self.handle
|
||||
.send(ToServer::Equip(
|
||||
self.id,
|
||||
self.player_data.actor_id,
|
||||
main_weapon_id,
|
||||
model_ids,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_equip(&mut self, actor_id: u32, main_weapon_id: u64, model_ids: [u32; 10]) {
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
op_code: ServerZoneIpcType::Equip,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::Equip(Equip {
|
||||
main_weapon_id: inventory.get_main_weapon_id(&mut game_data),
|
||||
sub_weapon_id: 0,
|
||||
crest_enable: 0,
|
||||
pattern_invalid: 0,
|
||||
model_ids: inventory.get_model_ids(&mut game_data),
|
||||
main_weapon_id,
|
||||
model_ids,
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
|
||||
self.send_segment(PacketSegment {
|
||||
source_actor: self.player_data.actor_id,
|
||||
source_actor: actor_id,
|
||||
target_actor: self.player_data.actor_id,
|
||||
segment_type: SegmentType::Ipc,
|
||||
data: SegmentData::Ipc { data: ipc },
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_message(&mut self, message: &str) {
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
|
|
|
@ -62,6 +62,10 @@ impl Instance {
|
|||
self.actors.get(&id)
|
||||
}
|
||||
|
||||
fn find_actor_mut(&mut self, id: ObjectId) -> Option<&mut NetworkedActor> {
|
||||
self.actors.get_mut(&id)
|
||||
}
|
||||
|
||||
fn insert_npc(&mut self, id: ObjectId, spawn: NpcSpawn) {
|
||||
self.actors.insert(id, NetworkedActor::Npc(spawn));
|
||||
}
|
||||
|
@ -132,7 +136,7 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
|||
data.clients
|
||||
.insert(handle.id, (handle, ClientState::default()));
|
||||
}
|
||||
ToServer::ZoneLoaded(from_id, zone_id) => {
|
||||
ToServer::ZoneLoaded(from_id, zone_id, common_spawn) => {
|
||||
let mut data = data.lock().unwrap();
|
||||
|
||||
// create a new instance if necessary
|
||||
|
@ -181,7 +185,7 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
|||
instance.actors.insert(
|
||||
ObjectId(client.actor_id),
|
||||
NetworkedActor::Player(NpcSpawn {
|
||||
common: client.common.clone(),
|
||||
common: common_spawn.clone(),
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
|
@ -208,7 +212,7 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
|||
spawn_index: 0,
|
||||
},
|
||||
NpcSpawn {
|
||||
common: client.common.clone(),
|
||||
common: common_spawn.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
@ -601,6 +605,39 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
|||
}
|
||||
}
|
||||
}
|
||||
ToServer::Equip(_from_id, from_actor_id, main_weapon_id, model_ids) => {
|
||||
// update their stored state so it's correctly sent on new spawns
|
||||
{
|
||||
let mut data = data.lock().unwrap();
|
||||
|
||||
let Some(instance) = data.find_actor_instance_mut(from_actor_id) else {
|
||||
break;
|
||||
};
|
||||
|
||||
let Some(actor) = instance.find_actor_mut(ObjectId(from_actor_id)) else {
|
||||
break;
|
||||
};
|
||||
|
||||
let NetworkedActor::Player(player) = actor else {
|
||||
break;
|
||||
};
|
||||
|
||||
player.common.main_weapon_model = main_weapon_id;
|
||||
player.common.models = model_ids.clone();
|
||||
}
|
||||
|
||||
// Inform all clients about their new equipped model ids
|
||||
let mut data = data.lock().unwrap();
|
||||
for (id, (handle, _)) in &mut data.clients {
|
||||
let id = *id;
|
||||
|
||||
let msg = FromServer::ActorEquip(from_actor_id, main_weapon_id, model_ids);
|
||||
|
||||
if handle.send(msg).is_err() {
|
||||
to_remove.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
ToServer::Disconnected(from_id) => {
|
||||
let mut data = data.lock().unwrap();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue