mirror of
https://github.com/redstrate/Kawari.git
synced 2025-06-21 07:27:45 +00:00
Make !spawnmonster put the NPC at your location again
Also included some refactoring that will help networking these better.
This commit is contained in:
parent
1b6fdab000
commit
3757f4e0db
6 changed files with 83 additions and 27 deletions
|
@ -104,7 +104,9 @@ async fn main() {
|
||||||
serde_json::from_str(&body).ok();
|
serde_json::from_str(&body).ok();
|
||||||
if let Some(service_accounts) = service_accounts {
|
if let Some(service_accounts) = service_accounts {
|
||||||
if service_accounts.is_empty() {
|
if service_accounts.is_empty() {
|
||||||
tracing::warn!("This account has no service accounts attached, how did this happen?");
|
tracing::warn!(
|
||||||
|
"This account has no service accounts attached, how did this happen?"
|
||||||
|
);
|
||||||
|
|
||||||
// request an update, wrong error message lol
|
// request an update, wrong error message lol
|
||||||
connection.send_error(*sequence, 1012, 13101).await;
|
connection.send_error(*sequence, 1012, 13101).await;
|
||||||
|
@ -114,7 +116,9 @@ async fn main() {
|
||||||
connection.send_account_list().await;
|
connection.send_account_list().await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tracing::warn!("Failed to parse service accounts from the login server!");
|
tracing::warn!(
|
||||||
|
"Failed to parse service accounts from the login server!"
|
||||||
|
);
|
||||||
|
|
||||||
// request an update, wrong error message lol
|
// request an update, wrong error message lol
|
||||||
connection.send_error(*sequence, 1012, 13101).await;
|
connection.send_error(*sequence, 1012, 13101).await;
|
||||||
|
|
|
@ -896,7 +896,7 @@ async fn client_loop(
|
||||||
msg = internal_recv.recv() => match msg {
|
msg = internal_recv.recv() => match msg {
|
||||||
Some(msg) => match msg {
|
Some(msg) => match msg {
|
||||||
FromServer::Message(msg) => connection.send_message(&msg).await,
|
FromServer::Message(msg) => connection.send_message(&msg).await,
|
||||||
FromServer::ActorSpawn(actor, common) => connection.spawn_actor(actor, common).await,
|
FromServer::ActorSpawn(actor, spawn) => connection.spawn_actor(actor, spawn).await,
|
||||||
FromServer::ActorMove(actor_id, position, rotation) => connection.set_actor_position(actor_id, position, rotation).await,
|
FromServer::ActorMove(actor_id, position, rotation) => connection.set_actor_position(actor_id, position, rotation).await,
|
||||||
FromServer::ActorDespawn(actor_id) => connection.remove_actor(actor_id).await,
|
FromServer::ActorDespawn(actor_id) => connection.remove_actor(actor_id).await,
|
||||||
FromServer::ActorControl(actor_id, actor_control) => connection.actor_control(actor_id, actor_control).await,
|
FromServer::ActorControl(actor_id, actor_control) => connection.actor_control(actor_id, actor_control).await,
|
||||||
|
|
|
@ -106,7 +106,10 @@ impl ChatHandler {
|
||||||
"!spawnmonster" => {
|
"!spawnmonster" => {
|
||||||
connection
|
connection
|
||||||
.handle
|
.handle
|
||||||
.send(ToServer::DebugNewNpc(connection.id))
|
.send(ToServer::DebugNewNpc(
|
||||||
|
connection.id,
|
||||||
|
connection.player_data.actor_id,
|
||||||
|
))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
"!playscene" => {
|
"!playscene" => {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub enum FromServer {
|
||||||
/// A chat message.
|
/// A chat message.
|
||||||
Message(String),
|
Message(String),
|
||||||
/// An actor has been spawned.
|
/// An actor has been spawned.
|
||||||
ActorSpawn(Actor, CommonSpawn),
|
ActorSpawn(Actor, NpcSpawn),
|
||||||
/// An actor moved to a new position.
|
/// An actor moved to a new position.
|
||||||
ActorMove(u32, Position, f32),
|
ActorMove(u32, Position, f32),
|
||||||
// An actor has despawned.
|
// An actor has despawned.
|
||||||
|
@ -88,7 +88,7 @@ pub enum ToServer {
|
||||||
Disconnected(ClientId),
|
Disconnected(ClientId),
|
||||||
/// A fatal error occured.
|
/// A fatal error occured.
|
||||||
FatalError(std::io::Error),
|
FatalError(std::io::Error),
|
||||||
DebugNewNpc(ClientId),
|
DebugNewNpc(ClientId, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -214,20 +214,17 @@ impl ZoneConnection {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn spawn_actor(&mut self, mut actor: Actor, mut common: CommonSpawn) {
|
pub async fn spawn_actor(&mut self, mut actor: Actor, mut spawn: NpcSpawn) {
|
||||||
// There is no reason for us to spawn our own player again. It's probably a bug!'
|
// There is no reason for us to spawn our own player again. It's probably a bug!'
|
||||||
assert!(actor.id.0 != self.player_data.actor_id);
|
assert!(actor.id.0 != self.player_data.actor_id);
|
||||||
|
|
||||||
actor.spawn_index = self.get_free_spawn_index() as u32;
|
actor.spawn_index = self.get_free_spawn_index() as u32;
|
||||||
common.spawn_index = actor.spawn_index as u8;
|
spawn.common.spawn_index = actor.spawn_index as u8;
|
||||||
|
|
||||||
let ipc = ServerZoneIpcSegment {
|
let ipc = ServerZoneIpcSegment {
|
||||||
op_code: ServerZoneIpcType::NpcSpawn,
|
op_code: ServerZoneIpcType::NpcSpawn,
|
||||||
timestamp: timestamp_secs(),
|
timestamp: timestamp_secs(),
|
||||||
data: ServerZoneIpcData::NpcSpawn(NpcSpawn {
|
data: ServerZoneIpcData::NpcSpawn(spawn),
|
||||||
common,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{ObjectId, Position},
|
common::ObjectId,
|
||||||
ipc::zone::{
|
ipc::zone::{
|
||||||
ActorControl, ActorControlCategory, ActorControlSelf, ActorControlTarget, BattleNpcSubKind,
|
ActorControl, ActorControlCategory, ActorControlSelf, ActorControlTarget, BattleNpcSubKind,
|
||||||
ClientTriggerCommand, CommonSpawn, NpcSpawn, ObjectKind,
|
ClientTriggerCommand, CommonSpawn, NpcSpawn, ObjectKind,
|
||||||
|
@ -11,10 +11,26 @@ use crate::{
|
||||||
|
|
||||||
use super::{Actor, ClientHandle, ClientId, FromServer, ToServer};
|
use super::{Actor, ClientHandle, ClientId, FromServer, ToServer};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum NetworkedActor {
|
||||||
|
Player(NpcSpawn),
|
||||||
|
NPC(NpcSpawn),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
struct Instance {
|
struct Instance {
|
||||||
// structure temporary, of course
|
// structure temporary, of course
|
||||||
actors: HashMap<ObjectId, CommonSpawn>,
|
actors: HashMap<ObjectId, NetworkedActor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instance {
|
||||||
|
fn find_actor(&self, id: ObjectId) -> Option<&NetworkedActor> {
|
||||||
|
self.actors.get(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_npc(&mut self, id: ObjectId, spawn: NpcSpawn) {
|
||||||
|
self.actors.insert(id, NetworkedActor::NPC(spawn));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
|
@ -81,14 +97,20 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
state.zone_id = zone_id;
|
state.zone_id = zone_id;
|
||||||
|
|
||||||
// send existing player data
|
// send existing player data
|
||||||
for (id, common) in &instance.actors {
|
for (id, spawn) in &instance.actors {
|
||||||
|
let npc_spawn = match spawn {
|
||||||
|
NetworkedActor::Player(npc_spawn) => npc_spawn,
|
||||||
|
NetworkedActor::NPC(npc_spawn) => npc_spawn,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note that we currently only support spawning via the NPC packet, hence why we don't need to differentiate here
|
||||||
let msg = FromServer::ActorSpawn(
|
let msg = FromServer::ActorSpawn(
|
||||||
Actor {
|
Actor {
|
||||||
id: *id,
|
id: *id,
|
||||||
hp: 100,
|
hp: 100,
|
||||||
spawn_index: 0,
|
spawn_index: 0,
|
||||||
},
|
},
|
||||||
common.clone(),
|
npc_spawn.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
handle.send(msg).unwrap();
|
handle.send(msg).unwrap();
|
||||||
|
@ -104,9 +126,13 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
// add the connection's actor to the table
|
// add the connection's actor to the table
|
||||||
{
|
{
|
||||||
let instance = data.find_instance_mut(zone_id);
|
let instance = data.find_instance_mut(zone_id);
|
||||||
instance
|
instance.actors.insert(
|
||||||
.actors
|
ObjectId(client.actor_id),
|
||||||
.insert(ObjectId(client.actor_id), client.common.clone());
|
NetworkedActor::Player(NpcSpawn {
|
||||||
|
common: client.common.clone(),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then tell any clients in the zone that we spawned
|
// Then tell any clients in the zone that we spawned
|
||||||
|
@ -129,7 +155,10 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
hp: 0,
|
hp: 0,
|
||||||
spawn_index: 0,
|
spawn_index: 0,
|
||||||
},
|
},
|
||||||
client.common.clone(),
|
NpcSpawn {
|
||||||
|
common: client.common.clone(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if handle.send(msg).is_err() {
|
if handle.send(msg).is_err() {
|
||||||
|
@ -180,11 +209,15 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
}
|
}
|
||||||
ToServer::ActorMoved(from_id, actor_id, position, rotation) => {
|
ToServer::ActorMoved(from_id, actor_id, position, rotation) => {
|
||||||
if let Some(instance) = data.find_actor_instance_mut(actor_id) {
|
if let Some(instance) = data.find_actor_instance_mut(actor_id) {
|
||||||
if let Some((_, common)) = instance
|
if let Some((_, spawn)) = instance
|
||||||
.actors
|
.actors
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|actor| *actor.0 == ObjectId(actor_id))
|
.find(|actor| *actor.0 == ObjectId(actor_id))
|
||||||
{
|
{
|
||||||
|
let common = match spawn {
|
||||||
|
NetworkedActor::Player(npc_spawn) => &mut npc_spawn.common,
|
||||||
|
NetworkedActor::NPC(npc_spawn) => &mut npc_spawn.common,
|
||||||
|
};
|
||||||
common.pos = position;
|
common.pos = position;
|
||||||
common.rotation = rotation;
|
common.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
@ -279,11 +312,22 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ToServer::DebugNewNpc(_from_id) => {
|
ToServer::DebugNewNpc(_from_id, from_actor_id) => {
|
||||||
for (id, (handle, _)) in &mut data.clients {
|
let spawn;
|
||||||
let id = *id;
|
{
|
||||||
|
let Some(instance) = data.find_actor_instance_mut(from_actor_id) else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
let msg = FromServer::SpawnNPC(NpcSpawn {
|
let Some(actor) = instance.find_actor(ObjectId(from_actor_id)) else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
let NetworkedActor::Player(player) = actor else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
spawn = NpcSpawn {
|
||||||
aggression_mode: 1,
|
aggression_mode: 1,
|
||||||
common: CommonSpawn {
|
common: CommonSpawn {
|
||||||
hp_curr: 91,
|
hp_curr: 91,
|
||||||
|
@ -297,11 +341,19 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
level: 1,
|
level: 1,
|
||||||
battalion: 4,
|
battalion: 4,
|
||||||
model_chara: 297,
|
model_chara: 297,
|
||||||
pos: Position::default(),
|
pos: player.common.pos,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
|
instance.insert_npc(ObjectId(1), spawn.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (id, (handle, _)) in &mut data.clients {
|
||||||
|
let id = *id;
|
||||||
|
|
||||||
|
let msg = FromServer::SpawnNPC(spawn.clone());
|
||||||
|
|
||||||
if handle.send(msg).is_err() {
|
if handle.send(msg).is_err() {
|
||||||
to_remove.push(id);
|
to_remove.push(id);
|
||||||
|
|
Loading…
Add table
Reference in a new issue