mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-19 22:36:49 +00:00
Send the welcome server message in the onBeginLogin Lua function
I finally got a proof-of-concept working, and am somewhat happy with how I can start building this API now.
This commit is contained in:
parent
a99b0e7c17
commit
652beadaa4
8 changed files with 117 additions and 46 deletions
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -199,7 +199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -266,6 +266,7 @@ dependencies = [
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -549,7 +550,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -560,6 +561,7 @@ checksum = "d3f763c1041eff92ffb5d7169968a327e1ed2ebfe425dac0ee5a35f29082534b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"either",
|
"either",
|
||||||
|
"futures-util",
|
||||||
"mlua-sys",
|
"mlua-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
@ -599,9 +601,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.1"
|
version = "1.21.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
checksum = "c2806eaa3524762875e21c3dcd057bc4b7bfa01ce4da8d46be1cd43649e1cc6b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
|
@ -635,7 +637,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "physis"
|
name = "physis"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "git+https://github.com/redstrate/physis#020480e82c5537bdcd15ab3b9826f409d9e77e1a"
|
source = "git+https://github.com/redstrate/physis#eee7d5867fb7424592ff1249f28c90dbe1daec13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"binrw",
|
"binrw",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
|
@ -770,7 +772,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -873,6 +875,15 @@ version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
|
@ -886,7 +897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -940,7 +951,7 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1065,6 +1076,15 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.59.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
|
|
|
@ -86,4 +86,4 @@ rusqlite = { version = "0.34", features = ["bundled"], default-features = false
|
||||||
bitflags = { version = "1.3", default-features = false }
|
bitflags = { version = "1.3", default-features = false }
|
||||||
|
|
||||||
# For server-side scripting
|
# For server-side scripting
|
||||||
mlua = { version = "0.10", features = ["lua51", "vendored", "send"] }
|
mlua = { version = "0.10", features = ["lua51", "vendored", "send", "async"] }
|
||||||
|
|
2
build.rs
2
build.rs
|
@ -11,6 +11,8 @@ fn main() {
|
||||||
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
d.push("resources/opcodes.json");
|
d.push("resources/opcodes.json");
|
||||||
|
|
||||||
|
println!("cargo::rerun-if-changed={}", d.to_str().unwrap());
|
||||||
|
|
||||||
let mut output_str = "use binrw::binrw;\n".to_string();
|
let mut output_str = "use binrw::binrw;\n".to_string();
|
||||||
|
|
||||||
let opcodes_buffer = std::fs::read_to_string(d).unwrap();
|
let opcodes_buffer = std::fs::read_to_string(d).unwrap();
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ServerChatMessage",
|
"name": "ServerChatMessage",
|
||||||
"opcode": 406,
|
"opcode": 837,
|
||||||
"size": 776
|
"size": 776
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
function onBeginLogin(player)
|
function onBeginLogin(player)
|
||||||
print("Player " .. player.content_id .. " is connecting!")
|
-- send a welcome message
|
||||||
|
player:send_message("Welcome to Kawari!")
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,8 +23,8 @@ use kawari::world::{
|
||||||
SocialList,
|
SocialList,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use kawari::world::{PlayerData, WorldDatabase};
|
use kawari::world::{LuaPlayer, PlayerData, WorldDatabase};
|
||||||
use mlua::{Function, Lua};
|
use mlua::{AnyUserData, Function, Lua};
|
||||||
use physis::common::{Language, Platform};
|
use physis::common::{Language, Platform};
|
||||||
use physis::gamedata::GameData;
|
use physis::gamedata::GameData;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
|
@ -47,12 +47,11 @@ async fn main() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let lua = lua.lock().unwrap();
|
let lua = lua.lock().unwrap();
|
||||||
lua.load(
|
let file_name = format!("{}/test.lua", &config.world.scripts_location);
|
||||||
std::fs::read(format!("{}/test.lua", &config.world.scripts_location))
|
lua.load(std::fs::read(&file_name).expect("Failed to locate scripts directory!"))
|
||||||
.expect("Failed to locate scripts directory!"),
|
.set_name("@".to_string() + &file_name)
|
||||||
)
|
.exec()
|
||||||
.exec()
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -79,6 +78,8 @@ async fn main() {
|
||||||
inventory: Inventory::new(),
|
inventory: Inventory::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut lua_player = LuaPlayer::default();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buf = [0; 2056];
|
let mut buf = [0; 2056];
|
||||||
loop {
|
loop {
|
||||||
|
@ -98,6 +99,7 @@ async fn main() {
|
||||||
// collect actor data
|
// collect actor data
|
||||||
connection.player_data =
|
connection.player_data =
|
||||||
database.find_player_data(actor_id.parse::<u32>().unwrap());
|
database.find_player_data(actor_id.parse::<u32>().unwrap());
|
||||||
|
lua_player.player_data = connection.player_data;
|
||||||
|
|
||||||
// We have send THEM a keep alive
|
// We have send THEM a keep alive
|
||||||
{
|
{
|
||||||
|
@ -309,37 +311,16 @@ async fn main() {
|
||||||
|
|
||||||
connection.change_zone(zone_id).await;
|
connection.change_zone(zone_id).await;
|
||||||
|
|
||||||
// send welcome message
|
|
||||||
{
|
|
||||||
let ipc = ServerZoneIpcSegment {
|
|
||||||
op_code: ServerZoneIpcType::ServerChatMessage,
|
|
||||||
timestamp: timestamp_secs(),
|
|
||||||
data: ServerZoneIpcData::ServerChatMessage {
|
|
||||||
message: "Welcome to Kawari!".to_string(),
|
|
||||||
unk: 0,
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
connection
|
|
||||||
.send_segment(PacketSegment {
|
|
||||||
source_actor: connection.player_data.actor_id,
|
|
||||||
target_actor: connection.player_data.actor_id,
|
|
||||||
segment_type: SegmentType::Ipc { data: ipc },
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lua = lua.lock().unwrap();
|
let lua = lua.lock().unwrap();
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
let player_data = scope
|
let connection_data = scope
|
||||||
.create_userdata_ref(&connection.player_data)
|
.create_userdata_ref_mut(&mut lua_player)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let func: Function =
|
let func: Function =
|
||||||
lua.globals().get("onBeginLogin").unwrap();
|
lua.globals().get("onBeginLogin").unwrap();
|
||||||
|
|
||||||
func.call::<()>(player_data).unwrap();
|
func.call::<()>(connection_data).unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -976,6 +957,8 @@ async fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection.process_lua_player(&mut lua_player).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use mlua::{UserData, UserDataFields};
|
use mlua::{UserData, UserDataFields, UserDataMethods};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -18,7 +18,7 @@ use super::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub struct PlayerData {
|
pub struct PlayerData {
|
||||||
pub actor_id: u32,
|
pub actor_id: u32,
|
||||||
pub content_id: u64,
|
pub content_id: u64,
|
||||||
|
@ -243,4 +243,69 @@ impl ZoneConnection {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_message(&mut self, message: &str) {
|
||||||
|
let ipc = ServerZoneIpcSegment {
|
||||||
|
op_code: ServerZoneIpcType::ServerChatMessage,
|
||||||
|
timestamp: timestamp_secs(),
|
||||||
|
data: ServerZoneIpcData::ServerChatMessage {
|
||||||
|
message: message.to_string(),
|
||||||
|
unk: 0,
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
self.send_segment(PacketSegment {
|
||||||
|
source_actor: self.player_data.actor_id,
|
||||||
|
target_actor: self.player_data.actor_id,
|
||||||
|
segment_type: SegmentType::Ipc { data: ipc },
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn process_lua_player(&mut self, player: &mut LuaPlayer) {
|
||||||
|
for segment in &player.queued_segments {
|
||||||
|
self.send_segment(segment.clone()).await;
|
||||||
|
}
|
||||||
|
player.queued_segments.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct LuaPlayer {
|
||||||
|
pub player_data: PlayerData,
|
||||||
|
queued_segments: Vec<PacketSegment<ServerZoneIpcSegment>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPlayer {
|
||||||
|
fn queue_segment(&mut self, segment: PacketSegment<ServerZoneIpcSegment>) {
|
||||||
|
self.queued_segments.push(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_message(&mut self, message: &str) {
|
||||||
|
let ipc = ServerZoneIpcSegment {
|
||||||
|
op_code: ServerZoneIpcType::ServerChatMessage,
|
||||||
|
timestamp: timestamp_secs(),
|
||||||
|
data: ServerZoneIpcData::ServerChatMessage {
|
||||||
|
message: message.to_string(),
|
||||||
|
unk: 0,
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
self.queue_segment(PacketSegment {
|
||||||
|
source_actor: self.player_data.actor_id,
|
||||||
|
target_actor: self.player_data.actor_id,
|
||||||
|
segment_type: SegmentType::Ipc { data: ipc },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for LuaPlayer {
|
||||||
|
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||||
|
methods.add_method_mut("send_message", |_, this, message: String| {
|
||||||
|
this.send_message(&message);
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod chat_handler;
|
||||||
pub use chat_handler::ChatHandler;
|
pub use chat_handler::ChatHandler;
|
||||||
|
|
||||||
mod connection;
|
mod connection;
|
||||||
pub use connection::{PlayerData, ZoneConnection};
|
pub use connection::{LuaPlayer, PlayerData, ZoneConnection};
|
||||||
|
|
||||||
mod database;
|
mod database;
|
||||||
pub use database::{CharacterData, WorldDatabase};
|
pub use database::{CharacterData, WorldDatabase};
|
||||||
|
|
Loading…
Add table
Reference in a new issue