diff options
Diffstat (limited to 'bindings/c/src/service_c')
| -rw-r--r-- | bindings/c/src/service_c/common.rs | 4 | ||||
| -rw-r--r-- | bindings/c/src/service_c/mod.rs | 4 | ||||
| -rw-r--r-- | bindings/c/src/service_c/padclient.rs | 126 | ||||
| -rw-r--r-- | bindings/c/src/service_c/padserver.rs | 174 |
4 files changed, 308 insertions, 0 deletions
diff --git a/bindings/c/src/service_c/common.rs b/bindings/c/src/service_c/common.rs new file mode 100644 index 0000000..8b13da0 --- /dev/null +++ b/bindings/c/src/service_c/common.rs @@ -0,0 +1,4 @@ +use nogamepads_lib_rs::DEFAULT_PORT; + +#[unsafe(no_mangle)] +pub extern "C" fn get_default_port() -> u16 { DEFAULT_PORT }
\ No newline at end of file diff --git a/bindings/c/src/service_c/mod.rs b/bindings/c/src/service_c/mod.rs new file mode 100644 index 0000000..674baf7 --- /dev/null +++ b/bindings/c/src/service_c/mod.rs @@ -0,0 +1,4 @@ +pub mod common; + +pub mod padclient; +pub mod padserver;
\ No newline at end of file diff --git a/bindings/c/src/service_c/padclient.rs b/bindings/c/src/service_c/padclient.rs new file mode 100644 index 0000000..b7bac43 --- /dev/null +++ b/bindings/c/src/service_c/padclient.rs @@ -0,0 +1,126 @@ +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; + +#[repr(C)] +#[derive(Copy, Clone)] +#[allow(unused_imports)] +pub struct PadClientC { + pub target_address: *const c_char, + pub target_port: u16, + pub bind_player: PlayerInfoC, + pub enable_console: bool, + pub quiet: bool +} + +impl From<PadClientC> 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<PadClient> 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) -> 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)); + 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) -> 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)); + 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 enable_client_console(client: PadClientC) -> PadClientC { + let mut raw: PadClient = client.into(); + raw.enable_console().into() +} + +#[unsafe(no_mangle)] +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 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) { + let client = unsafe { Box::from_raw(client) }; + client.connect(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn exit_client_from_server(client: &PadClient) { + client.exit_server(); +} + +// 消息管理 + +#[unsafe(no_mangle)] +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) -> 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: GameMessageC) -> GameMessageC { + client.pop_msg_or(or.into()).into() +}
\ No newline at end of file diff --git a/bindings/c/src/service_c/padserver.rs b/bindings/c/src/service_c/padserver.rs new file mode 100644 index 0000000..98c5792 --- /dev/null +++ b/bindings/c/src/service_c/padserver.rs @@ -0,0 +1,174 @@ +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_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}; + +// 构建 + +#[unsafe(no_mangle)] +pub extern "C" fn init_server(address: *const c_char) -> *mut PadServer { + 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(); + server.addr(IpAddr::from(addr_v4), DEFAULT_PORT); + box_into_raw!(server) +} + +#[unsafe(no_mangle)] +pub extern "C" fn init_server_with_port(address: *const c_char, port: u16) -> *mut PadServer { + 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(); + server.addr(IpAddr::from(addr_v4), port); + box_into_raw!(server) +} + +#[unsafe(no_mangle)] +pub extern "C" fn set_server_quiet(server: &mut PadServer) { + server.quiet(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn enable_server_console(server: &mut PadServer) { + server.enable_console(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn bind_profile_to_server(server: &mut PadServer, profile: &GameProfileC) { + server.put_profile(profile.clone().into()); +} + +// 状态控制 + +#[unsafe(no_mangle)] +pub extern "C" fn start_server(server: *mut PadServer) { + let server = unsafe { Box::from_raw(server) }; + let arc = Arc::new(server.as_ref().clone()); + PadServer::start_server(arc); +} + +#[unsafe(no_mangle)] +pub extern "C" fn stop_server(server: *mut PadServer) { + let server = unsafe { Box::from_raw(server) }; + server.stop_server(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn lock_game_on_server(server: *mut PadServer) { + let server = unsafe { Box::from_raw(server) }; + server.lock_game(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn unlock_game_on_server(server: *mut PadServer) { + let server = unsafe { Box::from_raw(server) }; + server.unlock_game(); +} + +#[unsafe(no_mangle)] +pub extern "C" fn is_server_game_locked(server: *mut PadServer) -> bool { + let server = unsafe { Box::from_raw(server) }; + server.is_game_locked() +} + +// 消息管理 +#[unsafe(no_mangle)] +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.into()); +} + +#[unsafe(no_mangle)] +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(server: *mut PadServer) -> ControlMessageC { +// let server = unsafe { Box::from_raw(server) }; +// let msg = server.pop_a_msg(); +// if msg.is_some() { +// let (player, msg) = msg.unwrap(); +// } +// } + +// 玩家管理 +#[unsafe(no_mangle)] +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.into()) +} + +#[unsafe(no_mangle)] +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.into()) +} + +#[unsafe(no_mangle)] +pub extern "C" fn kick_player(server: *mut PadServer, player: &PlayerInfoC) { + let server = unsafe { Box::from_raw(server) }; + server.kick_player(player.into()); +} + +#[unsafe(no_mangle)] +pub extern "C" fn ban_player(server: *mut PadServer, player: &PlayerInfoC) { + let server = unsafe { Box::from_raw(server) }; + server.ban_player(player.into()); +} + +#[unsafe(no_mangle)] +pub extern "C" fn pardon_player(server: *mut PadServer, player: &PlayerInfoC) { + let server = unsafe { Box::from_raw(server) }; + server.pardon_player(player.into()); +} + +#[unsafe(no_mangle)] +pub extern "C" fn list_online_players(server: *mut PadServer) -> PlayerList { + let server = unsafe { Box::from_raw(server) }; + let list = server.list_players(); + process_list_result(list) +} + +#[unsafe(no_mangle)] +pub extern "C" fn list_banned_players(server: *mut PadServer) -> PlayerList { + let server = unsafe { Box::from_raw(server) }; + let list = server.list_players_banned(); + process_list_result(list) +} + +fn process_list_result(list: Result<Vec<PlayerInfo>, PoisonError<MutexGuard<HashMap<String, PlayerInfo>>>>) -> PlayerList { + let result : Vec<PlayerInfo>; + if list.is_ok() { + result = list.unwrap(); + } else { + result = vec![]; + } + let mut result_c: Vec<PlayerInfoC> = Vec::new(); + for item in result { + result_c.push(item.into()); + } + + let mut vec = result_c.into_boxed_slice(); + let ptr = vec.as_mut_ptr(); + let len = vec.len(); + let capacity = vec.len(); + + PlayerList { + players: ptr, + len, + capacity + } +}
\ No newline at end of file |
