aboutsummaryrefslogtreecommitdiff
path: root/bindings/c/src/service_c
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/c/src/service_c')
-rw-r--r--bindings/c/src/service_c/common.rs4
-rw-r--r--bindings/c/src/service_c/mod.rs4
-rw-r--r--bindings/c/src/service_c/padclient.rs126
-rw-r--r--bindings/c/src/service_c/padserver.rs174
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