313 lines
9.9 KiB
Rust
313 lines
9.9 KiB
Rust
use common::structs::MultiPathAvatar;
|
|
use proto::chat_data::ExtendType;
|
|
use std::path::Path;
|
|
use tokio::fs;
|
|
|
|
use crate::{
|
|
net::PlayerSession,
|
|
util::{self, cur_timestamp_ms},
|
|
};
|
|
|
|
use super::*;
|
|
|
|
const SERVER_UID: u32 = 727;
|
|
const SERVER_HEAD_ICON: u32 = 201402;
|
|
const SERVER_CHAT_BUBBLE_ID: u32 = 220005;
|
|
const SERVER_CHAT_HISTORY: [&str; 6] = [
|
|
"'lua {path_to_lua_script}' execute lua script",
|
|
"'sync' to synchronize stats between json and in-game view",
|
|
"'mc {mc_id}' mc_id can be set from 8001 to 8008",
|
|
"'march {march_id}' march_id can be set 1001 or 1224",
|
|
"available commands:",
|
|
"visit srtools.neonteam.dev to configure the PS! (you configure relics, equipment, monsters from there)",
|
|
];
|
|
|
|
pub async fn on_get_friend_login_info_cs_req(
|
|
_session: &mut PlayerSession,
|
|
_req: &GetFriendLoginInfoCsReq,
|
|
res: &mut GetFriendLoginInfoScRsp,
|
|
) {
|
|
res.kcgceppmokm = vec![SERVER_UID];
|
|
res.omfombgfhpa = vec![SERVER_UID];
|
|
}
|
|
|
|
pub async fn on_get_friend_list_info_cs_req(
|
|
_session: &mut PlayerSession,
|
|
_req: &GetFriendListInfoCsReq,
|
|
res: &mut GetFriendListInfoScRsp,
|
|
) {
|
|
res.friend_list = vec![FriendSimpleInfo {
|
|
remark_name: String::from("RobinSR"),
|
|
player_info: Some(PlayerSimpleInfo {
|
|
uid: SERVER_UID,
|
|
platform: PlatformType::Pc.into(),
|
|
online_status: FriendOnlineStatus::Online.into(),
|
|
head_icon: SERVER_HEAD_ICON,
|
|
chat_bubble_id: SERVER_CHAT_BUBBLE_ID,
|
|
level: 70,
|
|
nickname: String::from("Server"),
|
|
signature: String::from("omg"),
|
|
..Default::default()
|
|
}),
|
|
is_marked: true,
|
|
create_time: 0,
|
|
..Default::default()
|
|
}];
|
|
}
|
|
|
|
pub async fn on_get_private_chat_history_cs_req(
|
|
_session: &mut PlayerSession,
|
|
req: &GetPrivateChatHistoryCsReq,
|
|
res: &mut GetPrivateChatHistoryScRsp,
|
|
) {
|
|
let cur_time = cur_timestamp_ms();
|
|
res.chat_message_list = SERVER_CHAT_HISTORY
|
|
.iter()
|
|
.map(|text| ChatMessageData {
|
|
create_time: cur_time,
|
|
ckhpffenobe: Some(Eknabklpeel {
|
|
kpobmnlklok: 1,
|
|
role_id: SERVER_UID,
|
|
}),
|
|
bkoalkhdlob: Some(Eknabklpeel {
|
|
kpobmnlklok: 1,
|
|
role_id: SERVER_UID,
|
|
}),
|
|
message_datas: vec![MessageChatData {
|
|
message_type: 1,
|
|
chat_data: Some(ChatData {
|
|
extend_type: Some(ExtendType::MessageText(text.to_string())),
|
|
}),
|
|
}],
|
|
..Default::default()
|
|
})
|
|
.collect();
|
|
res.target_side = req.target_side;
|
|
res.contact_side = SERVER_UID;
|
|
}
|
|
|
|
pub async fn on_send_msg_cs_req(
|
|
session: &mut PlayerSession,
|
|
body: &SendMsgCsReq,
|
|
_res: &mut SendMsgScRsp,
|
|
) {
|
|
let Some(json) = session.json_data.get_mut() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
let msg = body
|
|
.message_datas
|
|
.as_ref()
|
|
.and_then(|x| x.chat_data.as_ref())
|
|
.and_then(|x| x.extend_type.as_ref())
|
|
.and_then(|x| match x {
|
|
ExtendType::MessageText(s) => Some(s.as_str()),
|
|
_ => None,
|
|
})
|
|
.unwrap_or("");
|
|
|
|
if let Some((cmd, args)) = parse_command(msg) {
|
|
match cmd {
|
|
"sync" => {
|
|
let _ = session.sync_player().await;
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
String::from("Inventory Synced"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
"mc" => {
|
|
let mc = MultiPathAvatar::from(
|
|
args.first()
|
|
.unwrap_or(&"")
|
|
.parse::<u32>()
|
|
.unwrap_or(json.main_character as u32),
|
|
);
|
|
|
|
json.main_character = mc;
|
|
json.save_persistent().await;
|
|
|
|
session
|
|
.send(AvatarPathChangedNotify {
|
|
base_avatar_id: 8001,
|
|
cur_multi_path_avatar_type: mc as i32,
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
let _ = session.sync_player().await;
|
|
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
format!("Success change mc to {mc:#?}"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
"march" => {
|
|
let mut march_type = MultiPathAvatar::from(
|
|
args.first()
|
|
.unwrap_or(&"")
|
|
.parse::<u32>()
|
|
.unwrap_or(json.march_type as u32),
|
|
);
|
|
|
|
if march_type != MultiPathAvatar::MarchPreservation
|
|
&& march_type != MultiPathAvatar::MarchHunt
|
|
{
|
|
march_type = MultiPathAvatar::MarchHunt
|
|
}
|
|
|
|
json.march_type = march_type;
|
|
json.save_persistent().await;
|
|
|
|
session
|
|
.send(AvatarPathChangedNotify {
|
|
base_avatar_id: 1001,
|
|
cur_multi_path_avatar_type: march_type as i32,
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
format!("Success change march to {march_type:#?}"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
"lua" => {
|
|
let path = Path::new(args.first().unwrap_or(&""));
|
|
|
|
if !path.is_file() {
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
format!("File {path:?} does not exist!"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
let data = match fs::read(&path).await {
|
|
Ok(file) => file,
|
|
Err(err) => {
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
format!("Failed to read file: {err:?}"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
|
|
return;
|
|
}
|
|
};
|
|
|
|
session
|
|
.send(ClientDownloadDataScNotify {
|
|
download_data: Some(ClientDownloadData {
|
|
version: 51,
|
|
time: util::cur_timestamp_ms() as i64,
|
|
data,
|
|
..Default::default()
|
|
}),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
session
|
|
.send(create_send_message(
|
|
25,
|
|
SERVER_UID,
|
|
body.message_datas
|
|
.as_ref()
|
|
.map(|v| v.message_type)
|
|
.unwrap_or_default(),
|
|
body.chat_type,
|
|
format!("Executed {path:?}"),
|
|
))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn parse_command(command: &str) -> Option<(&str, Vec<&str>)> {
|
|
let parts: Vec<&str> = command.split_whitespace().collect();
|
|
|
|
if parts.is_empty() {
|
|
return Option::None;
|
|
}
|
|
|
|
Some((parts[0], parts[1..].to_vec()))
|
|
}
|
|
|
|
fn create_send_message(
|
|
to: u32,
|
|
from: u32,
|
|
message_type: i32,
|
|
chat_type: i32,
|
|
msg: String,
|
|
) -> RevcMsgScNotify {
|
|
RevcMsgScNotify {
|
|
chat_type,
|
|
dkdlooaaake: to,
|
|
recv_message_data: Some(ChatMessageData {
|
|
create_time: cur_timestamp_ms(),
|
|
ckhpffenobe: Some(Eknabklpeel {
|
|
kpobmnlklok: 1,
|
|
role_id: from,
|
|
}),
|
|
bkoalkhdlob: Some(Eknabklpeel {
|
|
kpobmnlklok: 1,
|
|
role_id: from,
|
|
}),
|
|
message_datas: vec![MessageChatData {
|
|
message_type,
|
|
chat_data: Some(ChatData {
|
|
extend_type: Some(chat_data::ExtendType::MessageText(msg)),
|
|
}),
|
|
}],
|
|
..Default::default()
|
|
}),
|
|
}
|
|
}
|