aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
author1992414357@qq.com <1992414357@qq.com>2025-06-13 22:33:53 +0800
committer1992414357@qq.com <1992414357@qq.com>2025-06-13 22:33:53 +0800
commit22ccd970a4ea47edd39abe8662805d8137083253 (patch)
tree2561d7131c57a632de0943437c7b6fa739eb8321 /core
parent83c6fc2d55cdd7de949f2815b86dfe0b9cc18f27 (diff)
.
Diffstat (limited to 'core')
-rw-r--r--core/bindings/c_lang/Cargo.toml12
-rw-r--r--core/bindings/c_lang/headers/ngpd_player.h39
-rw-r--r--core/bindings/c_lang/src/data/mod.rs1
-rw-r--r--core/bindings/c_lang/src/data/ngpd_player.rs139
-rw-r--r--core/bindings/c_lang/src/lib.rs1
-rw-r--r--core/src/service/cli_addition/runtime_consoles.rs3
6 files changed, 193 insertions, 2 deletions
diff --git a/core/bindings/c_lang/Cargo.toml b/core/bindings/c_lang/Cargo.toml
new file mode 100644
index 0000000..a0ee61f
--- /dev/null
+++ b/core/bindings/c_lang/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "nogamepads-c-bindings"
+edition = "2024"
+version.workspace = true
+
+[dependencies]
+nogamepads-core = { path = "../../../core" }
+libc = "0.2.172"
+
+[lib]
+name = "nogamepads_c"
+crate-type = ["cdylib"]
diff --git a/core/bindings/c_lang/headers/ngpd_player.h b/core/bindings/c_lang/headers/ngpd_player.h
new file mode 100644
index 0000000..00fbe5b
--- /dev/null
+++ b/core/bindings/c_lang/headers/ngpd_player.h
@@ -0,0 +1,39 @@
+#ifndef PLAYER_FFI_H
+#define PLAYER_FFI_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct FfiAccount {
+ char* id;
+ char* player_hash;
+} FfiAccount;
+
+typedef struct FfiCustomize {
+ char* nickname;
+ int32_t color_hue;
+ double color_saturation;
+ double color_value;
+} FfiCustomize;
+
+typedef struct FfiPlayer {
+ FfiAccount account;
+ FfiCustomize* customize;
+} FfiPlayer;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FfiPlayer* player_register(const char* id, const char* password);
+bool player_check(const FfiPlayer* player, const char* password);
+void player_set_nickname(FfiPlayer* player, const char* nickname);
+void player_set_hue(FfiPlayer* player, int hue);
+void player_set_hsv(FfiPlayer* player, int hue, double saturation, double value);
+void player_free(FfiPlayer* player);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif \ No newline at end of file
diff --git a/core/bindings/c_lang/src/data/mod.rs b/core/bindings/c_lang/src/data/mod.rs
new file mode 100644
index 0000000..32af6d8
--- /dev/null
+++ b/core/bindings/c_lang/src/data/mod.rs
@@ -0,0 +1 @@
+pub mod ngpd_player; \ No newline at end of file
diff --git a/core/bindings/c_lang/src/data/ngpd_player.rs b/core/bindings/c_lang/src/data/ngpd_player.rs
new file mode 100644
index 0000000..2ab615c
--- /dev/null
+++ b/core/bindings/c_lang/src/data/ngpd_player.rs
@@ -0,0 +1,139 @@
+use std::ffi::{CStr, CString};
+use std::os::raw::{c_char, c_double, c_int};
+use std::ptr;
+use nogamepads_core::data::player::player_data::{Account, Customize, Player};
+
+#[repr(C)]
+pub struct FfiAccount {
+ id: *mut c_char,
+ player_hash: *mut c_char,
+}
+
+#[repr(C)]
+pub struct FfiCustomize {
+ nickname: *mut c_char,
+ color_hue: c_int,
+ color_saturation: c_double,
+ color_value: c_double,
+}
+
+#[repr(C)]
+pub struct FfiPlayer {
+ account: FfiAccount,
+ customize: *mut FfiCustomize,
+}
+
+impl From<Account> for FfiAccount {
+ fn from(acc: Account) -> Self {
+ FfiAccount {
+ id: CString::new(acc.id).unwrap().into_raw(),
+ player_hash: CString::new(acc.player_hash).unwrap().into_raw(),
+ }
+ }
+}
+
+impl From<Player> for FfiPlayer {
+ fn from(player: Player) -> Self {
+ let account = FfiAccount::from(player.account);
+ let customize = player.customize.map(|c| {
+ Box::into_raw(Box::new(FfiCustomize {
+ nickname: CString::new(c.nickname).unwrap().into_raw(),
+ color_hue: c.color_hue,
+ color_saturation: c.color_saturation,
+ color_value: c.color_value,
+ }))
+ }).unwrap_or(ptr::null_mut());
+
+ FfiPlayer { account, customize }
+ }
+}
+
+impl TryFrom<&FfiPlayer> for Player {
+ type Error = ();
+
+ fn try_from(ffi: &FfiPlayer) -> Result<Self, Self::Error> {
+ let account = Account {
+ id: unsafe { CStr::from_ptr(ffi.account.id) }.to_str().map_err(|_| ())?.to_owned(),
+ player_hash: unsafe { CStr::from_ptr(ffi.account.player_hash) }.to_str().map_err(|_| ())?.to_owned(),
+ };
+
+ let customize = if !ffi.customize.is_null() {
+ let c = unsafe { &*ffi.customize };
+ Some(Customize {
+ nickname: unsafe { CStr::from_ptr(c.nickname) }.to_str().map_err(|_| ())?.to_owned(),
+ color_hue: c.color_hue,
+ color_saturation: c.color_saturation,
+ color_value: c.color_value,
+ })
+ } else {
+ None
+ };
+
+ Ok(Player { account, customize })
+ }
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_register(id: *const c_char, password: *const c_char) -> *mut FfiPlayer {
+ let id_str = unsafe { CStr::from_ptr(id) }.to_string_lossy();
+ let pass_str = unsafe { CStr::from_ptr(password) }.to_string_lossy();
+
+ let player = Player::register(id_str.into_owned(), pass_str.into_owned());
+ Box::into_raw(Box::new(FfiPlayer::from(player)))
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_check(player: *const FfiPlayer, password: *const c_char) -> bool {
+ let player = unsafe { &*player };
+ let pass_str = unsafe { CStr::from_ptr(password) }.to_string_lossy();
+
+ Player::try_from(player)
+ .map(|p| p.check(pass_str.into_owned()))
+ .unwrap_or(false)
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_set_nickname(player: *mut FfiPlayer, nickname: *const c_char) {
+ let nickname_str = unsafe { CStr::from_ptr(nickname) }.to_string_lossy().into_owned();
+ let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() };
+
+ rust_player.nickname(&nickname_str);
+ *unsafe { &mut *player } = FfiPlayer::from(rust_player);
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_set_hue(player: *mut FfiPlayer, hue: c_int) {
+ let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() };
+
+ rust_player.hue(hue);
+ *unsafe { &mut *player } = FfiPlayer::from(rust_player);
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_set_hsv(
+ player: *mut FfiPlayer, hue: c_int, saturation: c_double, value: c_double
+) {
+ let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() };
+
+ rust_player.hsv(hue, saturation, value);
+ *unsafe { &mut *player } = FfiPlayer::from(rust_player);
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn player_free(player: *mut FfiPlayer) {
+ if player.is_null() { return; }
+
+ let ffi_player = unsafe { Box::from_raw(player) };
+
+ // Free account strings
+ unsafe {
+ let _ = CString::from_raw(ffi_player.account.id);
+ let _ = CString::from_raw(ffi_player.account.player_hash);
+ }
+
+ // Free customize if present
+ if !ffi_player.customize.is_null() {
+ let ffi_custom = unsafe { Box::from_raw(ffi_player.customize) };
+ unsafe { let _ = CString::from_raw(ffi_custom.nickname); };
+ }
+} \ No newline at end of file
diff --git a/core/bindings/c_lang/src/lib.rs b/core/bindings/c_lang/src/lib.rs
new file mode 100644
index 0000000..12e35bb
--- /dev/null
+++ b/core/bindings/c_lang/src/lib.rs
@@ -0,0 +1 @@
+pub mod data; \ No newline at end of file
diff --git a/core/src/service/cli_addition/runtime_consoles.rs b/core/src/service/cli_addition/runtime_consoles.rs
index c96c0f2..2b2984b 100644
--- a/core/src/service/cli_addition/runtime_consoles.rs
+++ b/core/src/service/cli_addition/runtime_consoles.rs
@@ -1,10 +1,9 @@
-use std::process::exit;
use crate::service::cli_addition::utils::read_cli;
use clap::{Command, FromArgMatches};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use log::{info, warn};
-use tokio::{count, join, select, spawn};
+use tokio::{join, select, spawn};
use tokio::signal::ctrl_c;
use tokio::time::sleep;
use crate::service::service_runner::NoGamepadsService;