From 9d3d6d4195e58c51166811d8357a331d53c4cdd4 Mon Sep 17 00:00:00 2001 From: "1992414357@qq.com" <1992414357@qq.com> Date: Thu, 29 May 2025 07:55:41 +0800 Subject: 正在编写 C# 绑定部分 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core_c/src/data_c/connection_callback_message_c.rs | 30 +++--- core_c/src/data_c/connection_message_c.rs | 20 ++-- core_c/src/data_c/control_message_c.rs | 28 +++--- core_c/src/data_c/game_message_c.rs | 18 ++-- core_c/src/data_c/game_profile_c.rs | 101 ++++++++++++++++----- core_c/src/data_c/player_info_c.rs | 96 ++++++++++++++++---- core_c/src/data_c/player_info_list_c.rs | 4 +- core_c/src/lib.rs | 4 +- core_c/src/service_c/padclient.rs | 99 +++++++++++++++----- core_c/src/service_c/padserver.rs | 65 +++++++------ 10 files changed, 321 insertions(+), 144 deletions(-) (limited to 'core_c/src') diff --git a/core_c/src/data_c/connection_callback_message_c.rs b/core_c/src/data_c/connection_callback_message_c.rs index bb96a0d..e23b6f6 100644 --- a/core_c/src/data_c/connection_callback_message_c.rs +++ b/core_c/src/data_c/connection_callback_message_c.rs @@ -1,12 +1,12 @@ +use crate::data_c::game_profile_c::GameProfileC; +use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::{ConnectionCallbackMessage, ConnectionErrorType}; use std::ffi::c_void; use std::mem::ManuallyDrop; use std::ptr::null_mut; -use nogamepads_lib_rs::pad_data::game_profile::game_profile::GameProfile; -use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::{ConnectionCallbackMessage, ConnectionErrorType}; #[repr(C)] #[allow(unused_imports)] -pub struct ConnCallbackMsgC { +pub struct ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag, data: ConnCallbackMsgCUnion, } @@ -21,7 +21,7 @@ pub enum ConnCallbackMsgCTag { #[allow(unused_imports)] pub union ConnCallbackMsgCUnion { nul: *mut c_void, - profile: ManuallyDrop, + profile: ManuallyDrop, conn_err: ConnErrTypeC } @@ -56,12 +56,12 @@ impl From for ConnErrTypeC { } } -impl From for ConnectionCallbackMessage { - fn from(mut value: ConnCallbackMsgC) -> Self { +impl From for ConnectionCallbackMessage { + fn from(mut value: ConnectionCallbackMessageC) -> Self { match value.tag { ConnCallbackMsgCTag::Profile => unsafe { let profile = ManuallyDrop::take(&mut value.data.profile); - ConnectionCallbackMessage::Profile(profile) + ConnectionCallbackMessage::Profile(profile.into()) } ConnCallbackMsgCTag::Deny => unsafe { ConnectionCallbackMessage::Deny(value.data.conn_err.into()) @@ -83,43 +83,43 @@ impl From for ConnectionCallbackMessage { } } -impl From for ConnCallbackMsgC { +impl From for ConnectionCallbackMessageC { fn from(value: ConnectionCallbackMessage) -> Self { match value { ConnectionCallbackMessage::Profile(profile) => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Profile, data: ConnCallbackMsgCUnion { - profile: ManuallyDrop::new(profile) + profile: ManuallyDrop::new(profile.into()) } } } ConnectionCallbackMessage::Deny(conn_err) => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Deny, data: ConnCallbackMsgCUnion { conn_err: conn_err.into() } } } ConnectionCallbackMessage::Fail(conn_err) => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Fail, data: ConnCallbackMsgCUnion { conn_err: conn_err.into() } } } ConnectionCallbackMessage::Ok => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Ok, data: ConnCallbackMsgCUnion { nul: null_mut() } } } ConnectionCallbackMessage::Welcome => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Welcome, data: ConnCallbackMsgCUnion { nul: null_mut() } } } ConnectionCallbackMessage::Err => { - ConnCallbackMsgC { + ConnectionCallbackMessageC { tag: ConnCallbackMsgCTag::Err, data: ConnCallbackMsgCUnion { nul: null_mut() } } diff --git a/core_c/src/data_c/connection_message_c.rs b/core_c/src/data_c/connection_message_c.rs index 14a49ac..418342d 100644 --- a/core_c/src/data_c/connection_message_c.rs +++ b/core_c/src/data_c/connection_message_c.rs @@ -7,7 +7,7 @@ use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::Player #[repr(C)] #[allow(unused_imports)] -pub struct ConnMsgC { +pub struct ConnectionMessageC { tag: ConnMsgCTag, data: ConnMsgCUnion } @@ -25,8 +25,8 @@ pub union ConnMsgCUnion { info: ManuallyDrop } -impl From for ConnectionMessage { - fn from(mut value: ConnMsgC) -> Self { +impl From for ConnectionMessage { + fn from(mut value: ConnectionMessageC) -> Self { match value.tag { Connection => unsafe { let info = ManuallyDrop::take(&mut value.data.info); @@ -51,41 +51,41 @@ impl From for ConnectionMessage { } } -impl From for ConnMsgC { +impl From for ConnectionMessageC { fn from(value: ConnectionMessage) -> Self { match value { ConnectionMessage::Connection(info) => { - ConnMsgC { + ConnectionMessageC { tag: Connection, data: ConnMsgCUnion { info: ManuallyDrop::new(info) } } } ConnectionMessage::RequestProfile => { - ConnMsgC { + ConnectionMessageC { tag: RequestProfile, data: ConnMsgCUnion { nul: null_mut() } } } ConnectionMessage::RequestLayoutConfigure => { - ConnMsgC { + ConnectionMessageC { tag: RequestLayoutConfigure, data: ConnMsgCUnion { nul: null_mut() } } } ConnectionMessage::RequestSkinPackage => { - ConnMsgC { + ConnectionMessageC { tag: RequestSkinPackage, data: ConnMsgCUnion { nul: null_mut() } } } ConnectionMessage::Ready => { - ConnMsgC { + ConnectionMessageC { tag: Ready, data: ConnMsgCUnion { nul: null_mut() } } } ConnectionMessage::Err => { - ConnMsgC { + ConnectionMessageC { tag: ConnMsgCTag::Err, data: ConnMsgCUnion { nul: null_mut() } } diff --git a/core_c/src/data_c/control_message_c.rs b/core_c/src/data_c/control_message_c.rs index 41a3e09..84f2288 100644 --- a/core_c/src/data_c/control_message_c.rs +++ b/core_c/src/data_c/control_message_c.rs @@ -1,12 +1,12 @@ use crate::data_c::common::KeyData; -use crate::{c_char_to_string_safe, string_to_c_char_safe}; +use crate::{str_c_to_rs, str_rs_to_c}; use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::ControlMessage; use std::ffi::{c_char, c_void}; use std::ptr::null_mut; #[repr(C)] #[allow(unused_imports)] -pub struct CtrlMsgC { +pub struct ControlMessageC { tag: CtrlMsgCTag, data: CtrlMsgCUnion } @@ -51,11 +51,11 @@ pub struct StrData { str: *const c_char } -impl From for ControlMessage { - fn from(msg_c: CtrlMsgC) -> Self { +impl From for ControlMessage { + fn from(msg_c: ControlMessageC) -> Self { match msg_c.tag { CtrlMsgCTag::Msg => unsafe { - let str = c_char_to_string_safe(msg_c.data.str.str); + let str = str_c_to_rs(msg_c.data.str.str); if str.is_some() { ControlMessage::Msg(str.unwrap()) } else { @@ -86,19 +86,19 @@ impl From for ControlMessage { } } -impl From for CtrlMsgC { +impl From for ControlMessageC { fn from(msg_rs: ControlMessage) -> Self { match msg_rs { ControlMessage::Msg(str_msg) => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Msg, data: CtrlMsgCUnion { - str: StrData { str: string_to_c_char_safe(str_msg).1 }, + str: StrData { str: str_rs_to_c(str_msg).1 }, } } } ControlMessage::Pressed(key) => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Pressed, data: CtrlMsgCUnion { key: KeyData { key }, @@ -106,7 +106,7 @@ impl From for CtrlMsgC { } } ControlMessage::Released(key) => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Released, data: CtrlMsgCUnion { key: KeyData { key }, @@ -114,7 +114,7 @@ impl From for CtrlMsgC { } } ControlMessage::Axis(key, ax) => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Axis, data: CtrlMsgCUnion { axis: AxisData { key, ax } @@ -122,7 +122,7 @@ impl From for CtrlMsgC { } } ControlMessage::Dir(key, (x, y)) => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Dir, data: CtrlMsgCUnion { dir: DirData { key, x, y } @@ -130,7 +130,7 @@ impl From for CtrlMsgC { } } ControlMessage::Exit => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Exit, data: CtrlMsgCUnion { nul: null_mut(), @@ -138,7 +138,7 @@ impl From for CtrlMsgC { } } ControlMessage::Err => { - CtrlMsgC { + ControlMessageC { tag: CtrlMsgCTag::Err, data: CtrlMsgCUnion { nul: null_mut(), diff --git a/core_c/src/data_c/game_message_c.rs b/core_c/src/data_c/game_message_c.rs index 8b275ff..b6a2b89 100644 --- a/core_c/src/data_c/game_message_c.rs +++ b/core_c/src/data_c/game_message_c.rs @@ -5,7 +5,7 @@ use crate::data_c::common::KeyData; #[repr(C)] #[allow(unused_imports)] -pub struct GameMsgC { +pub struct GameMessageC { tag: GameMsgCTag, data: GameMsgCUnion } @@ -54,8 +54,8 @@ impl From for LeaveReasonData { } } -impl From for GameMessage { - fn from(msg: GameMsgC) -> Self { +impl From for GameMessage { + fn from(msg: GameMessageC) -> Self { match msg.tag { GameMsgCTag::SkinEventTrigger => unsafe { GameMessage::SkinEventTrigger(msg.data.key.key) @@ -76,35 +76,35 @@ impl From for GameMessage { } } -impl From for GameMsgC { +impl From for GameMessageC { fn from(msg: GameMessage) -> Self { match msg { GameMessage::SkinEventTrigger(key) => { - GameMsgC { + GameMessageC { tag: GameMsgCTag::SkinEventTrigger, data: GameMsgCUnion { key: KeyData { key } } } } GameMessage::DisableKey(key) => { - GameMsgC { + GameMessageC { tag: GameMsgCTag::DisableKey, data: GameMsgCUnion { key: KeyData { key } } } } GameMessage::EnableKey(key) => { - GameMsgC { + GameMessageC { tag: GameMsgCTag::EnableKey, data: GameMsgCUnion { key: KeyData { key } } } } GameMessage::Leave(reason) => { - GameMsgC { + GameMessageC { tag: GameMsgCTag::Leave, data: GameMsgCUnion { reason: reason.into() } } } GameMessage::Err => { - GameMsgC { + GameMessageC { tag: GameMsgCTag::Err, data: GameMsgCUnion { nul: null_mut() } } diff --git a/core_c/src/data_c/game_profile_c.rs b/core_c/src/data_c/game_profile_c.rs index 199329a..d0072c8 100644 --- a/core_c/src/data_c/game_profile_c.rs +++ b/core_c/src/data_c/game_profile_c.rs @@ -1,44 +1,101 @@ -use std::ffi::c_char; -use crate::{box_into_raw, c_char_to_string_safe}; +use crate::{str_c_to_rs, str_rs_to_c}; use nogamepads_lib_rs::pad_data::game_profile::game_profile::GameProfile; +use std::ffi::c_char; + +#[repr(C)] +#[derive(Copy, Clone)] +#[allow(unused_imports)] +pub struct GameProfileC { + game_name: *const c_char, + game_description: *const c_char, + organization: *const c_char, + version: *const c_char, + website: *const c_char, + email: *const c_char +} + +impl From for GameProfile { + fn from(value: GameProfileC) -> Self { + let unknown = "".to_string(); + GameProfile { + game_name: str_c_to_rs(value.game_name).unwrap_or(unknown.clone()), + game_description: str_c_to_rs(value.game_description).unwrap_or(unknown.clone()), + organization: str_c_to_rs(value.organization).unwrap_or(unknown.clone()), + version: str_c_to_rs(value.version).unwrap_or(unknown.clone()), + website: str_c_to_rs(value.website).unwrap_or(unknown.clone()), + email: str_c_to_rs(value.email).unwrap_or(unknown.clone()) + } + } +} + +impl From for GameProfileC { + fn from(value: GameProfile) -> Self { + GameProfileC { + game_name: str_rs_to_c(value.game_name).1, + game_description: str_rs_to_c(value.game_description).1, + organization: str_rs_to_c(value.organization).1, + version: str_rs_to_c(value.version).1, + website: str_rs_to_c(value.website).1, + email: str_rs_to_c(value.email).1 + } + } +} + +impl From<&GameProfileC> for &GameProfile { + fn from(value: &GameProfileC) -> Self { + value.into() + } +} + +impl From<&GameProfile> for &GameProfileC { + fn from(value: &GameProfile) -> Self { + value.into() + } +} #[unsafe(no_mangle)] -pub extern "C" fn init_game_profile() -> *mut GameProfile { - box_into_raw!(GameProfile::default()) +pub extern "C" fn init_game_profile() -> GameProfileC { + GameProfile::default().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_name(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.game_name(value.as_str()); +pub extern "C" fn set_game_profile_name(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.game_name(value.as_str()).to_owned().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_description(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.game_description(value.as_str()); +pub extern "C" fn set_game_profile_description(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.game_description(value.as_str()).to_owned().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_organization(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.organization(value.as_str()); +pub extern "C" fn set_game_profile_organization(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.organization(value.as_str()).to_owned().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_version(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.version(value.as_str()); +pub extern "C" fn set_game_profile_version(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.version(value.as_str()).to_owned().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_website(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.website(value.as_str()); +pub extern "C" fn set_game_profile_website(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.website(value.as_str()).to_owned().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_game_profile_email(game_profile: &mut GameProfile, value: *const c_char) { - let value = c_char_to_string_safe(value).unwrap_or_default(); - game_profile.email(value.as_str()); +pub extern "C" fn set_game_profile_email(game_profile: GameProfileC, value: *const c_char) -> GameProfileC { + let value = str_c_to_rs(value).unwrap_or_default(); + let mut raw = GameProfile::from(game_profile); + raw.email(value.as_str()).to_owned().into() } \ No newline at end of file diff --git a/core_c/src/data_c/player_info_c.rs b/core_c/src/data_c/player_info_c.rs index 4252b49..f51a9f9 100644 --- a/core_c/src/data_c/player_info_c.rs +++ b/core_c/src/data_c/player_info_c.rs @@ -1,33 +1,95 @@ +use crate::{str_c_to_rs, str_rs_to_c}; +use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::{PlayerAccountInfo, PlayerCustomizeInfo, PlayerInfo}; use std::ffi::c_char; -use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; -use crate::{box_into_raw, c_char_to_string_safe}; + +#[repr(C)] +#[derive(Copy, Clone)] +#[allow(unused_imports)] +pub struct PlayerInfoC { + account_id: *const c_char, + account_hash: *const c_char, + + customize_nickname: *const c_char, + customize_color_hue: i32, + customize_color_saturation: f64, + customize_color_value: f64, +} + +impl From for PlayerInfo { + fn from(value: PlayerInfoC) -> Self { + let unknown = "unknown".to_string(); + PlayerInfo { + account : PlayerAccountInfo { + id: str_c_to_rs(value.account_id).unwrap_or(unknown.clone()), + player_hash: str_c_to_rs(value.account_hash).unwrap_or(unknown.clone()), + }, + customize: PlayerCustomizeInfo { + nickname: str_c_to_rs(value.customize_nickname).unwrap_or(unknown.clone()), + color_hue: value.customize_color_hue, + color_saturation: value.customize_color_saturation, + color_value: value.customize_color_value, + } + } + } +} + +impl From for PlayerInfoC { + fn from(value: PlayerInfo) -> Self { + PlayerInfoC { + account_id: str_rs_to_c(value.account.id).1, + account_hash: str_rs_to_c(value.account.player_hash).1, + customize_nickname: str_rs_to_c(value.customize.nickname).1, + customize_color_hue: value.customize.color_hue, + customize_color_saturation: value.customize.color_saturation, + customize_color_value: value.customize.color_value, + } + } +} + +impl From<&PlayerInfoC> for &PlayerInfo { + fn from(value: &PlayerInfoC) -> Self { + value.into() + } +} + +impl From<&PlayerInfo> for &PlayerInfoC { + fn from(value: &PlayerInfo) -> Self { + value.into() + } +} #[unsafe(no_mangle)] -pub extern "C" fn init_player_info() -> *mut PlayerInfo { - box_into_raw!(PlayerInfo::new()) +pub extern "C" fn init_player_info() -> PlayerInfoC { + PlayerInfo::new().into() } #[unsafe(no_mangle)] pub extern "C" fn set_player_info_account( - info: &mut PlayerInfo, - id: *const c_char, - password: *const c_char) { - let id = c_char_to_string_safe(id).unwrap_or("".to_string()); - let password = c_char_to_string_safe(password).unwrap_or("".to_string()); - info.setup_account_info(id.as_str(), password.as_str()); + info: PlayerInfoC, id: *const c_char, password: *const c_char) -> PlayerInfoC { + + let id = str_c_to_rs(id).unwrap_or("".to_string()); + let password = str_c_to_rs(password).unwrap_or("".to_string()); + + let mut raw_info = PlayerInfo::from(info); + raw_info.setup_account_info(id.as_str(), password.as_str()); + raw_info.into() } #[unsafe(no_mangle)] pub extern "C" fn set_player_info_color( - info: &mut PlayerInfo, - h: i32, s: f64, v: f64) { - info.set_customize_color_hsv(h, s, v); + info: PlayerInfoC, h: i32, s: f64, v: f64) -> PlayerInfoC { + + let mut raw_info = PlayerInfo::from(info); + raw_info.set_customize_color_hsv(h, s, v); + raw_info.into() } #[unsafe(no_mangle)] pub extern "C" fn set_player_info_nickname( - info: &mut PlayerInfo, - nickname: *const c_char) { - let nickname = c_char_to_string_safe(nickname).unwrap_or("".to_string()); - info.set_nickname(nickname.as_str()); + info: PlayerInfoC, nickname: *const c_char) -> PlayerInfoC { + let nickname = str_c_to_rs(nickname).unwrap_or("".to_string()); + + let mut raw_info = PlayerInfo::from(info); + raw_info.set_nickname(nickname.as_str()); + raw_info.into() } \ No newline at end of file diff --git a/core_c/src/data_c/player_info_list_c.rs b/core_c/src/data_c/player_info_list_c.rs index 9ad8918..99d5c35 100644 --- a/core_c/src/data_c/player_info_list_c.rs +++ b/core_c/src/data_c/player_info_list_c.rs @@ -1,8 +1,8 @@ -use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; +use crate::data_c::player_info_c::PlayerInfoC; #[repr(C)] pub struct PlayerList { - pub(crate) players: *mut PlayerInfo, + pub(crate) players: *mut PlayerInfoC, pub(crate) len: usize, pub(crate) capacity: usize, } \ No newline at end of file diff --git a/core_c/src/lib.rs b/core_c/src/lib.rs index bdeb7ef..6efd0e9 100644 --- a/core_c/src/lib.rs +++ b/core_c/src/lib.rs @@ -3,13 +3,13 @@ use std::ffi::{c_char, CStr, CString}; pub mod data_c; pub mod service_c; -pub fn string_to_c_char_safe(s: String) -> (CString, *const c_char) { +pub fn str_rs_to_c(s: String) -> (CString, *const c_char) { let c_string = CString::new(s).expect(""); let ptr = c_string.as_ptr(); (c_string, ptr) } -pub fn c_char_to_string_safe(ptr: *const c_char) -> Option { +pub fn str_c_to_rs(ptr: *const c_char) -> Option { if ptr.is_null() { return None; } diff --git a/core_c/src/service_c/padclient.rs b/core_c/src/service_c/padclient.rs index 77e7d87..60120ab 100644 --- a/core_c/src/service_c/padclient.rs +++ b/core_c/src/service_c/padclient.rs @@ -1,51 +1,104 @@ +use crate::data_c::control_message_c::ControlMessageC; +use crate::data_c::game_message_c::GameMessageC; +use crate::data_c::player_info_c::PlayerInfoC; +use crate::{box_into_raw, str_c_to_rs, str_rs_to_c}; +use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::GameMessage; +use nogamepads_lib_rs::pad_service::client::nogamepads_client::PadClient; +use nogamepads_lib_rs::DEFAULT_PORT; use std::ffi::c_char; use std::net::{IpAddr, Ipv4Addr}; use std::str::FromStr; -use nogamepads_lib_rs::DEFAULT_PORT; -use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::GameMessage; -use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; -use nogamepads_lib_rs::pad_service::client::nogamepads_client::PadClient; -use crate::{box_into_raw, c_char_to_string_safe}; -use crate::data_c::control_message_c::CtrlMsgC; -use crate::data_c::game_message_c::GameMsgC; + +#[repr(C)] +#[derive(Copy, Clone)] +#[allow(unused_imports)] +pub struct PadClientC { + target_address: *const c_char, + target_port: u16, + bind_player: PlayerInfoC, + enable_console: bool, + quiet: bool +} + +impl From for PadClient { + fn from(value: PadClientC) -> Self { + let address = IpAddr::from_str(str_c_to_rs(value.target_address).unwrap_or("".to_string()).as_str()).unwrap_or( + IpAddr::from(Ipv4Addr::new(127, 0, 0, 1)) + ); + let port = value.target_port; + let mut client = PadClient::bind_addr_with_port(address, port); + client.bind_player(value.bind_player.into()); + if value.enable_console { client.enable_console(); } + if value.quiet { client.quiet(); } + client + } +} + +impl From for PadClientC { + fn from(mut value: PadClient) -> Self { + let (addr, port) = value.clone_addr(); + + PadClientC { + target_address: str_rs_to_c(addr.to_string()).1, + target_port: port, + bind_player: value.unbind_player().into(), + enable_console: value.is_enable_console(), + quiet: value.is_quiet(), + } + } +} +impl From<&mut PadClient> for PadClientC { + fn from(value: &mut PadClient) -> Self { + value.into() + } +} // 构建 #[unsafe(no_mangle)] -pub extern "C" fn init_client(address: *const c_char) -> *mut PadClient { - let addr_str = c_char_to_string_safe(address).unwrap_or("127.0.0.1".to_string()); +pub extern "C" fn init_client(address: *const c_char) -> PadClientC { + let addr_str = str_c_to_rs(address).unwrap_or("127.0.0.1".to_string()); let addr_v4 = Ipv4Addr::from_str(addr_str.as_str()).unwrap_or( Ipv4Addr::new(127, 0, 0, 1)); - box_into_raw!(PadClient::bind_addr_with_port(IpAddr::from(addr_v4), DEFAULT_PORT)) + PadClient::bind_addr_with_port(IpAddr::from(addr_v4), DEFAULT_PORT).into() } #[unsafe(no_mangle)] -pub unsafe extern "C" fn init_client_with_port(address: *const c_char, port: u16) -> *mut PadClient { - let addr_str = c_char_to_string_safe(address).unwrap_or("127.0.0.1".to_string()); +pub unsafe extern "C" fn init_client_with_port(address: *const c_char, port: u16) -> PadClientC { + let addr_str = str_c_to_rs(address).unwrap_or("127.0.0.1".to_string()); let addr_v4 = Ipv4Addr::from_str(addr_str.as_str()).unwrap_or( Ipv4Addr::new(127, 0, 0, 1)); - box_into_raw!(PadClient::bind_addr_with_port(IpAddr::from(addr_v4), port)) + PadClient::bind_addr_with_port(IpAddr::from(addr_v4), port).into() +} + +#[unsafe(no_mangle)] +pub extern "C" fn set_client_quiet(client: PadClientC) -> PadClientC { + let mut raw: PadClient = client.into(); + raw.quiet().into() } #[unsafe(no_mangle)] -pub extern "C" fn set_client_quiet(client: &mut PadClient) { - client.quiet(); +pub extern "C" fn enable_client_console(client: PadClientC) -> PadClientC { + let mut raw: PadClient = client.into(); + raw.enable_console().into() } #[unsafe(no_mangle)] -pub extern "C" fn enable_client_console(client: &mut PadClient) { - client.enable_console(); +pub extern "C" fn bind_player_to_client(client: PadClientC, info: PlayerInfoC) -> PadClientC { + let mut raw: PadClient = client.into(); + raw.bind_player(info.into()).into() } #[unsafe(no_mangle)] -pub extern "C" fn bind_player_to_client(client: &mut PadClient, info: &mut PlayerInfo) { - client.bind_player(info.clone()); +pub extern "C" fn complete(client: PadClientC) -> *mut PadClient { + let client: PadClient = client.into(); + box_into_raw!(client) } // 状态控制 #[unsafe(no_mangle)] -pub extern "C" fn connect_client_to_server(client: *mut PadClient) { +pub extern "C" fn connect_client_to_server(client: &mut PadClient) { let client = unsafe { Box::from_raw(client) }; client.connect(); } @@ -58,16 +111,16 @@ pub extern "C" fn exit_client_from_server(client: &PadClient) { // 消息管理 #[unsafe(no_mangle)] -pub extern "C" fn put_a_msg_to_server(client: &PadClient, msg: CtrlMsgC) { +pub extern "C" fn put_a_msg_to_server(client: &PadClient, msg: ControlMessageC) { client.put_msg(msg.into()) } #[unsafe(no_mangle)] -pub extern "C" fn pop_a_msg_from_server(client: &PadClient) -> GameMsgC { +pub extern "C" fn pop_a_msg_from_server(client: &PadClient) -> GameMessageC { client.pop_a_msg().unwrap_or(GameMessage::Err).into() } #[unsafe(no_mangle)] -pub extern "C" fn pop_msg_from_server_or(client: &PadClient, or: GameMsgC) -> GameMsgC { +pub extern "C" fn pop_msg_from_server_or(client: &PadClient, or: GameMessageC) -> GameMessageC { client.pop_msg_or(or.into()).into() } \ No newline at end of file diff --git a/core_c/src/service_c/padserver.rs b/core_c/src/service_c/padserver.rs index d0e3267..ee1a6a8 100644 --- a/core_c/src/service_c/padserver.rs +++ b/core_c/src/service_c/padserver.rs @@ -1,23 +1,24 @@ -use std::collections::HashMap; -use crate::{box_into_raw, c_char_to_string_safe}; -use nogamepads_lib_rs::pad_data::game_profile::game_profile::GameProfile; +use crate::data_c::control_message_c::ControlMessageC; +use crate::data_c::game_message_c::GameMessageC; +use crate::data_c::game_profile_c::GameProfileC; +use crate::data_c::player_info_c::PlayerInfoC; +use crate::data_c::player_info_list_c::PlayerList; +use crate::{box_into_raw, str_c_to_rs}; +use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::ControlMessage; +use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; use nogamepads_lib_rs::pad_service::server::nogamepads_server::PadServer; use nogamepads_lib_rs::DEFAULT_PORT; +use std::collections::HashMap; use std::ffi::c_char; use std::net::{IpAddr, Ipv4Addr}; use std::str::FromStr; use std::sync::{Arc, MutexGuard, PoisonError}; -use nogamepads_lib_rs::pad_data::pad_messages::nogamepads_messages::ControlMessage; -use nogamepads_lib_rs::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; -use crate::data_c::control_message_c::CtrlMsgC; -use crate::data_c::game_message_c::GameMsgC; -use crate::data_c::player_info_list_c::PlayerList; // 构建 #[unsafe(no_mangle)] pub extern "C" fn init_server(address: *const c_char) -> *mut PadServer { - let addr_str = c_char_to_string_safe(address).unwrap_or("127.0.0.1".to_string()); + let addr_str = str_c_to_rs(address).unwrap_or("127.0.0.1".to_string()); let addr_v4 = Ipv4Addr::from_str(addr_str.as_str()).unwrap_or( Ipv4Addr::new(127, 0, 0, 1)); let mut server = PadServer::default(); @@ -27,7 +28,7 @@ pub extern "C" fn init_server(address: *const c_char) -> *mut PadServer { #[unsafe(no_mangle)] pub extern "C" fn init_server_with_port(address: *const c_char, port: u16) -> *mut PadServer { - let addr_str = c_char_to_string_safe(address).unwrap_or("127.0.0.1".to_string()); + let addr_str = str_c_to_rs(address).unwrap_or("127.0.0.1".to_string()); let addr_v4 = Ipv4Addr::from_str(addr_str.as_str()).unwrap_or( Ipv4Addr::new(127, 0, 0, 1)); let mut server = PadServer::default(); @@ -46,8 +47,8 @@ pub extern "C" fn enable_server_console(server: &mut PadServer) { } #[unsafe(no_mangle)] -pub extern "C" fn bind_profile_to_server(server: &mut PadServer, profile: &mut GameProfile) { - server.put_profile(profile.clone()); +pub extern "C" fn bind_profile_to_server(server: &mut PadServer, profile: &GameProfileC) { + server.put_profile(profile.clone().into()); } // 状态控制 @@ -85,59 +86,59 @@ pub extern "C" fn is_server_game_locked(server: *mut PadServer) -> bool { // 消息管理 #[unsafe(no_mangle)] -pub extern "C" fn put_a_msg_to_player(server: *mut PadServer, msg: GameMsgC, player: &PlayerInfo) { +pub extern "C" fn put_a_msg_to_player(server: *mut PadServer, msg: GameMessageC, player: &PlayerInfoC) { let server = unsafe { Box::from_raw(server) }; - server.put_msg_to(msg.into(), player); + server.put_msg_to(msg.into(), player.into()); } #[unsafe(no_mangle)] -pub extern "C" fn put_msg_to_all_players(server: *mut PadServer, msg: GameMsgC) { +pub extern "C" fn put_msg_to_all_players(server: *mut PadServer, msg: GameMessageC) { let server = unsafe { Box::from_raw(server) }; server.put_msg_to_all(&msg.into()); } #[unsafe(no_mangle)] -pub extern "C" fn pop_a_msg_from_player(server: *mut PadServer, player: &PlayerInfo) -> CtrlMsgC { +pub extern "C" fn pop_a_msg_from_player(server: *mut PadServer, player: &PlayerInfoC) -> ControlMessageC { let server = unsafe { Box::from_raw(server) }; - server.pop_a_msg(player).unwrap_or(ControlMessage::Err).into() + server.pop_a_msg(player.into()).unwrap_or(ControlMessage::Err).into() } #[unsafe(no_mangle)] -pub extern "C" fn pop_msg_from_player_or(server: *mut PadServer, player: &PlayerInfo, or: CtrlMsgC) -> CtrlMsgC { +pub extern "C" fn pop_msg_from_player_or(server: *mut PadServer, player: &PlayerInfoC, or: ControlMessageC) -> ControlMessageC { let server = unsafe { Box::from_raw(server) }; - let msg = server.pop_msg_or(player, or.into()); + let msg = server.pop_msg_or(player.into(), or.into()); msg.into() } // 玩家管理 #[unsafe(no_mangle)] -pub extern "C" fn is_player_online(server: *mut PadServer, player: &PlayerInfo) -> bool { +pub extern "C" fn is_player_online(server: *mut PadServer, player: &PlayerInfoC) -> bool { let server = unsafe { Box::from_raw(server) }; - server.is_player_online(player) + server.is_player_online(player.into()) } #[unsafe(no_mangle)] -pub extern "C" fn is_player_banned(server: *mut PadServer, player: &PlayerInfo) -> bool { +pub extern "C" fn is_player_banned(server: *mut PadServer, player: &PlayerInfoC) -> bool { let server = unsafe { Box::from_raw(server) }; - server.is_player_banned(player) + server.is_player_banned(player.into()) } #[unsafe(no_mangle)] -pub extern "C" fn kick_player(server: *mut PadServer, player: &PlayerInfo) { +pub extern "C" fn kick_player(server: *mut PadServer, player: &PlayerInfoC) { let server = unsafe { Box::from_raw(server) }; - server.kick_player(player); + server.kick_player(player.into()); } #[unsafe(no_mangle)] -pub extern "C" fn ban_player(server: *mut PadServer, player: &PlayerInfo) { +pub extern "C" fn ban_player(server: *mut PadServer, player: &PlayerInfoC) { let server = unsafe { Box::from_raw(server) }; - server.ban_player(player); + server.ban_player(player.into()); } #[unsafe(no_mangle)] -pub extern "C" fn pardon_player(server: *mut PadServer, player: &PlayerInfo) { +pub extern "C" fn pardon_player(server: *mut PadServer, player: &PlayerInfoC) { let server = unsafe { Box::from_raw(server) }; - server.pardon_player(player); + server.pardon_player(player.into()); } #[unsafe(no_mangle)] @@ -161,8 +162,12 @@ fn process_list_result(list: Result, PoisonError = Vec::new(); + for item in result { + result_c.push(item.into()); + } - let mut vec = result.into_boxed_slice(); + let mut vec = result_c.into_boxed_slice(); let ptr = vec.as_mut_ptr(); let len = vec.len(); let capacity = vec.len(); -- cgit