aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeicao Mao <1992414357@qq.com>2025-06-16 05:00:08 +0800
committerGitHub <noreply@github.com>2025-06-16 05:00:08 +0800
commitf5072499d9241b22e7a259267cc0315841b7589d (patch)
treeda0ef21a88131b6e495bf6ec0dc03092e2815a76
parentbb7a31c753df0a7663cdcc89aff840384b16564e (diff)
parentb44b687c3c90642bbe609593b301cd248745dfc6 (diff)
Merge pull request #5 from CatilGrass/c_bindings
Add CBindings of GameData, GameRuntime
-rw-r--r--core/bindings/lang/clang/configures/nogamepads_data.toml3
-rw-r--r--core/bindings/lang/clang/configures/nogamepads_data_cpp.toml15
-rw-r--r--core/bindings/lang/clang/headers/nogamepads_data.h253
-rw-r--r--core/bindings/lang/clang/headers/nogamepads_data_cpp.h245
-rw-r--r--core/bindings/lang/clang/src/data/mod.rs5
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_controller.rs76
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_game.rs641
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_game_info.rs2
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_message.rs109
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_player.rs24
-rw-r--r--core/bindings/lang/clang/src/lib.rs1
-rw-r--r--core/bindings/lang/clang/src/service/mod.rs1
-rw-r--r--core/bindings/lang/clang/src/service/ngpd_service_types.rs36
-rw-r--r--core/src/data/game/game_cli.rs4
-rw-r--r--core/src/data/game/game_data.rs4
-rw-r--r--core/src/data/game/game_runtime.rs2
-rw-r--r--core/src/data/player/player_data.rs11
17 files changed, 1062 insertions, 370 deletions
diff --git a/core/bindings/lang/clang/configures/nogamepads_data.toml b/core/bindings/lang/clang/configures/nogamepads_data.toml
index 5c7e91b..a408296 100644
--- a/core/bindings/lang/clang/configures/nogamepads_data.toml
+++ b/core/bindings/lang/clang/configures/nogamepads_data.toml
@@ -12,4 +12,7 @@ include = [
"ngpd_message",
"ngpd_player",
"ngpd_controller",
+ "ngpd_game",
+
+ "ngpd_service_types",
] \ No newline at end of file
diff --git a/core/bindings/lang/clang/configures/nogamepads_data_cpp.toml b/core/bindings/lang/clang/configures/nogamepads_data_cpp.toml
deleted file mode 100644
index 82afbf4..0000000
--- a/core/bindings/lang/clang/configures/nogamepads_data_cpp.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-language = "C++"
-include_guard = "NOGAMEPADS_DATA_H"
-header = "// Auto generated by cbindgen 0.29.0"
-cpp_compat = true
-
-[parse]
-parse_deps = true
-include = [
- "string_converter",
-
- "ngpd_game_info",
- "ngpd_message",
- "ngpd_player",
- "ngpd_controller",
-] \ No newline at end of file
diff --git a/core/bindings/lang/clang/headers/nogamepads_data.h b/core/bindings/lang/clang/headers/nogamepads_data.h
index 81dca74..8340bdd 100644
--- a/core/bindings/lang/clang/headers/nogamepads_data.h
+++ b/core/bindings/lang/clang/headers/nogamepads_data.h
@@ -61,6 +61,12 @@ typedef enum FfiJoinFailedMessage {
UnknownError,
} FfiJoinFailedMessage;
+typedef enum FfiServiceType {
+ TCPConnection,
+ BlueTooth,
+ USB,
+} FfiServiceType;
+
typedef struct FfiAccount {
char *id;
char *player_hash;
@@ -151,6 +157,52 @@ typedef struct FfiControllerRuntime {
void (*drop_fn)(void*);
} FfiControllerRuntime;
+typedef struct FfiGameData {
+ void *_0;
+} FfiGameData;
+
+typedef struct FfiGameRuntimeArchive {
+ void *_0;
+} FfiGameRuntimeArchive;
+
+typedef struct FfiGameRuntime {
+ void *inner;
+ void (*drop_fn)(void*);
+} FfiGameRuntime;
+
+typedef struct FfiControlEvent {
+ struct FfiPlayer player;
+ struct FfiControlMessage message;
+} FfiControlEvent;
+
+typedef struct FfiButtonStatus {
+ bool found;
+ bool pressed;
+ bool released;
+} FfiButtonStatus;
+
+typedef struct FfiAxis {
+ bool found;
+ double axis;
+} FfiAxis;
+
+typedef struct FfiDirection {
+ bool found;
+ double x;
+ double y;
+} FfiDirection;
+
+typedef struct FfiBooleanResult {
+ bool found;
+ bool result;
+} FfiBooleanResult;
+
+typedef struct FfiPlayerList {
+ struct FfiPlayer *players;
+ uintptr_t len;
+ uintptr_t cap;
+} FfiPlayerList;
+
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
@@ -163,6 +215,16 @@ void free_c_string(char *ptr);
struct FfiPlayer *player_register(const char *id, const char *password);
/**
+ * Register a player from hash
+ */
+struct FfiPlayer *player_from_hash(const char *hash);
+
+/**
+ * Get a hash from player
+ */
+const char *player_get_hash(struct FfiPlayer *player);
+
+/**
* Check if the player's password is correct
*/
bool player_check(const struct FfiPlayer *player, const char *password);
@@ -190,32 +252,32 @@ void free_player(struct FfiPlayer *player);
/**
* Free ControlMessage
*/
-void free_control_message(struct FfiControlMessage msg);
+void free_control_message(struct FfiControlMessage *msg);
/**
* Free GameMessage
*/
-void free_game_message(struct FfiGameMessage msg);
+void free_game_message(struct FfiGameMessage *msg);
/**
* Free ExitReason
*/
-void free_exit_reason(enum FfiExitReason msg);
+void free_exit_reason(enum FfiExitReason *msg);
/**
* Free ConnectionMessage
*/
-void free_connection_message(struct FfiConnectionMessage msg);
+void free_connection_message(struct FfiConnectionMessage *msg);
/**
* Free ConnectionResponseMessage
*/
-void free_connection_response_message(struct FfiConnectionResponseMessage msg);
+void free_connection_response_message(struct FfiConnectionResponseMessage *msg);
/**
* Free JoinFailedMessage
*/
-void free_join_failed_message(enum FfiJoinFailedMessage msg);
+void free_join_failed_message(enum FfiJoinFailedMessage *msg);
void free_game_info(struct FfiGameInfo map);
@@ -288,7 +350,184 @@ struct FfiGameMessage *controller_runtime_pop(struct FfiControllerRuntime *runti
/**
* Free runtime memory
*/
-void controller_runtime_free(struct FfiControllerRuntime *runtime);
+void free_controller_runtime(struct FfiControllerRuntime *runtime);
+
+/**
+ * Create game data
+ */
+struct FfiGameData *game_data_new(void);
+
+/**
+ * Load data archive
+ */
+struct FfiGameData *game_data_load_archive(struct FfiGameData *data,
+ struct FfiGameRuntimeArchive *archive);
+
+/**
+ * Build runtime by data
+ */
+struct FfiGameRuntime *game_data_build_runtime(struct FfiGameData *data);
+
+/**
+ * Free data
+ */
+void free_game_data(struct FfiGameData *data);
+
+/**
+ * Create game archive data
+ */
+struct FfiGameRuntimeArchive *game_archive_data_new(void);
+
+/**
+ * Add ban player
+ */
+struct FfiGameRuntimeArchive *game_archive_data_add_ban_player(struct FfiGameRuntimeArchive *data,
+ struct FfiPlayer *ffi_player);
+
+/**
+ * Free data
+ */
+void free_game_archive_data(struct FfiGameRuntimeArchive *data);
+
+/**
+ * Send a message to
+ */
+void game_runtime_send_message_to(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ struct FfiGameMessage *message,
+ enum FfiServiceType *service_type);
+
+/**
+ * Send a text message
+ */
+void game_runtime_send_text_message(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ enum FfiServiceType *service_type,
+ const char *text);
+
+/**
+ * Send a event message
+ */
+void game_runtime_send_event(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ enum FfiServiceType *service_type,
+ uint8_t key);
+
+/**
+ * Pop a control event
+ */
+struct FfiControlEvent *game_runtime_pop_control_event(struct FfiGameRuntime *runtime);
+
+/**
+ * Let player exit
+ */
+void game_runtime_let_exit(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ enum FfiServiceType *service_type,
+ enum FfiExitReason *reason);
+
+/**
+ * Kick a player
+ */
+void game_runtime_kick_player(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ enum FfiServiceType *service_type);
+
+/**
+ * Ban a player (And kick)
+ */
+void game_runtime_ban_player(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ enum FfiServiceType *service_type);
+
+/**
+ * Pardon a player
+ */
+void game_runtime_pardon_player(struct FfiGameRuntime *runtime, const struct FfiPlayer *player);
+
+/**
+ * Close runtime
+ */
+void game_runtime_close(struct FfiGameRuntime *runtime);
+
+/**
+ * Lock game
+ */
+void game_runtime_lock(struct FfiGameRuntime *runtime);
+
+/**
+ * Unlock game
+ */
+void game_runtime_unlock(struct FfiGameRuntime *runtime);
+
+/**
+ * Get game lock status
+ */
+bool game_runtime_get_lock_status(struct FfiGameRuntime *runtime);
+
+/**
+ * Get button status of player
+ */
+struct FfiButtonStatus game_runtime_get_button_status(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ uint8_t key);
+
+/**
+ * Get axis value of player
+ */
+struct FfiAxis game_runtime_get_axis(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ uint8_t key);
+
+/**
+ * Get direction value of player
+ */
+struct FfiDirection game_runtime_get_direction(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player,
+ uint8_t key);
+
+/**
+ * Get service type of player
+ */
+const enum FfiServiceType *game_runtime_get_service_type(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player);
+
+/**
+ * Is player banned
+ */
+struct FfiBooleanResult game_runtime_is_player_banned(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player);
+
+/**
+ * Is player online
+ */
+struct FfiBooleanResult game_runtime_is_player_online(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player);
+
+/**
+ * Get online list
+ */
+struct FfiPlayerList game_runtime_get_online_list(struct FfiGameRuntime *runtime);
+
+/**
+ * Get banned list
+ */
+struct FfiPlayerList game_runtime_get_banned_list(struct FfiGameRuntime *runtime);
+
+/**
+ * Free control event
+ */
+void free_control_event(struct FfiControlEvent *event);
+
+/**
+ * Free player list
+ */
+void free_player_list(struct FfiPlayerList list);
+
+/**
+ * Free service type tag
+ */
+void free_ffi_service_type(enum FfiServiceType *ptr);
#ifdef __cplusplus
} // extern "C"
diff --git a/core/bindings/lang/clang/headers/nogamepads_data_cpp.h b/core/bindings/lang/clang/headers/nogamepads_data_cpp.h
deleted file mode 100644
index 2c128bb..0000000
--- a/core/bindings/lang/clang/headers/nogamepads_data_cpp.h
+++ /dev/null
@@ -1,245 +0,0 @@
-// Auto generated by cbindgen 0.29.0
-
-#ifndef NOGAMEPADS_DATA_H
-#define NOGAMEPADS_DATA_H
-
-#include <cstdarg>
-#include <cstdint>
-#include <cstdlib>
-#include <ostream>
-#include <new>
-
-enum class FfiConnectionMessageTag {
- ConnectionJoin,
- ConnectionRequestGameInfos,
- ConnectionRequestLayoutConfigure,
- ConnectionRequestSkinPackage,
- ConnectionReady,
- ConnectionError,
-};
-
-enum class FfiConnectionResponseMessageTag {
- GameInfosResponse,
- DenyResponse,
- FailResponse,
- OkResponse,
- WelcomeResponse,
- ErrorResponse,
-};
-
-enum class FfiControlMessageTag {
- CtrlMsg,
- CtrlPressed,
- CtrlReleased,
- CtrlAxis,
- CtrlDir,
- CtrlExit,
- CtrlError,
- CtrlEnd,
-};
-
-enum class FfiExitReason {
- ExitReason,
- GameOverReason,
- ServerClosedReason,
- YouAreKickedReason,
- YouAreBannedReason,
- ErrorReason,
-};
-
-enum class FfiGameMessageTag {
- GameEventTrigger,
- GameMsg,
- GameLetExit,
- GameError,
- GameEnd,
-};
-
-enum class FfiJoinFailedMessage {
- ContainIdenticalPlayer,
- PlayerBanned,
- GameLocked,
- UnknownError,
-};
-
-template<typename T = void>
-struct ManuallyDrop;
-
-struct FfiAccount {
- char *id;
- char *player_hash;
-};
-
-struct FfiCustomize {
- char *nickname;
- int color_hue;
- double color_saturation;
- double color_value;
-};
-
-struct FfiPlayer {
- FfiAccount account;
- FfiCustomize *customize;
-};
-
-struct FfiKeyAndAxis {
- uint8_t key;
- double axis;
-};
-
-struct FfiKeyAndDirection {
- uint8_t key;
- double x;
- double y;
-};
-
-union FfiControlMessageUnion {
- char *message;
- uint8_t key;
- ManuallyDrop<FfiKeyAndAxis> key_and_axis;
- ManuallyDrop<FfiKeyAndDirection> key_and_direction;
-};
-
-struct FfiControlMessage {
- FfiControlMessageTag tag;
- FfiControlMessageUnion data;
-};
-
-union FfiGameMessageUnion {
- uint8_t key;
- char *message;
- ManuallyDrop<FfiExitReason> exit_reason;
-};
-
-struct FfiGameMessage {
- FfiGameMessageTag tag;
- FfiGameMessageUnion data;
-};
-
-union FfiConnectionMessageUnion {
- ManuallyDrop<FfiPlayer> player;
-};
-
-struct FfiConnectionMessage {
- FfiConnectionMessageTag tag;
- FfiConnectionMessageUnion data;
-};
-
-struct KeyValuePair {
- char *key;
- char *value;
-};
-
-struct FfiGameInfo {
- KeyValuePair *data;
- uintptr_t len;
- uintptr_t cap;
-};
-
-union FfiConnectionResponseMessageUnion {
- ManuallyDrop<FfiGameInfo> game_info;
- ManuallyDrop<FfiJoinFailedMessage> failed_message;
-};
-
-struct FfiConnectionResponseMessage {
- FfiConnectionResponseMessageTag tag;
- FfiConnectionResponseMessageUnion data;
-};
-
-struct FfiControllerData {
- void *_0;
-};
-
-struct FfiControllerRuntime {
- void *inner;
- void (*drop_fn)(void*);
-};
-
-extern "C" {
-
-void free_c_string(char *ptr);
-
-/// Register a player
-FfiPlayer *player_register(const char *id, const char *password);
-
-/// Check if the player's password is correct
-bool player_check(const FfiPlayer *player, const char *password);
-
-/// Set the player's nickname
-void player_set_nickname(FfiPlayer *player, const char *nickname);
-
-/// Set the player's hue
-void player_set_hue(FfiPlayer *player, int hue);
-
-/// Set the player's HSV color
-void player_set_hsv(FfiPlayer *player, int hue, double saturation, double value);
-
-/// Free the player
-void free_player(FfiPlayer *player);
-
-/// Free ControlMessage
-void free_control_message(FfiControlMessage msg);
-
-/// Free GameMessage
-void free_game_message(FfiGameMessage msg);
-
-/// Free ExitReason
-void free_exit_reason(FfiExitReason msg);
-
-/// Free ConnectionMessage
-void free_connection_message(FfiConnectionMessage msg);
-
-/// Free ConnectionResponseMessage
-void free_connection_response_message(FfiConnectionResponseMessage msg);
-
-/// Free JoinFailedMessage
-void free_join_failed_message(FfiJoinFailedMessage msg);
-
-void free_game_info(FfiGameInfo map);
-
-/// Create controller data
-FfiControllerData *controller_data_new();
-
-/// Bind player to controller
-void controller_data_bind_player(FfiControllerData *controller, FfiPlayer *ffi_player);
-
-/// Build runtime
-FfiControllerRuntime *controller_data_build_runtime(FfiControllerData *controller);
-
-/// Free ControllerData memory
-void controller_data_free(FfiControllerData *controller);
-
-/// Close runtime and exit game
-void controller_runtime_close(FfiControllerRuntime *runtime);
-
-/// Send control message
-void controller_runtime_send_message(FfiControllerRuntime *runtime,
- FfiControlMessage *control_message);
-
-/// Send text message
-void controller_runtime_send_text_message(FfiControllerRuntime *runtime, const char *message_ptr);
-
-/// Press a button
-void controller_runtime_press_a_button(FfiControllerRuntime *runtime, uint8_t key);
-
-/// Release a button
-void controller_runtime_release_a_button(FfiControllerRuntime *runtime, uint8_t key);
-
-/// Change axis value
-void controller_runtime_change_axis(FfiControllerRuntime *runtime, uint8_t key, double axis);
-
-/// Change direction value
-void controller_runtime_change_direction(FfiControllerRuntime *runtime,
- uint8_t key,
- double x,
- double y);
-
-/// Pop a message from the queue
-FfiGameMessage *controller_runtime_pop(FfiControllerRuntime *runtime);
-
-/// Free runtime memory
-void controller_runtime_free(FfiControllerRuntime *runtime);
-
-} // extern "C"
-
-#endif // NOGAMEPADS_DATA_H
diff --git a/core/bindings/lang/clang/src/data/mod.rs b/core/bindings/lang/clang/src/data/mod.rs
index ca432f9..67e630a 100644
--- a/core/bindings/lang/clang/src/data/mod.rs
+++ b/core/bindings/lang/clang/src/data/mod.rs
@@ -1,4 +1,5 @@
pub mod ngpd_player;
pub mod ngpd_message;
-mod ngpd_game_info;
-mod ngpd_controller; \ No newline at end of file
+pub mod ngpd_game_info;
+pub mod ngpd_controller;
+pub mod ngpd_game; \ No newline at end of file
diff --git a/core/bindings/lang/clang/src/data/ngpd_controller.rs b/core/bindings/lang/clang/src/data/ngpd_controller.rs
index 923218b..c954df4 100644
--- a/core/bindings/lang/clang/src/data/ngpd_controller.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_controller.rs
@@ -30,7 +30,7 @@ impl FfiControllerData {
/// Bind player to controller
#[unsafe(no_mangle)]
#[allow(unsafe_op_in_unsafe_fn)]
- pub unsafe extern "C" fn controller_data_bind_player(
+ pub extern "C" fn controller_data_bind_player(
controller: *mut FfiControllerData,
ffi_player: *mut FfiPlayer
) {
@@ -47,13 +47,13 @@ impl FfiControllerData {
controller_inner.bind_player(player);
// Release the FFI Player
- drop(Box::from_raw(ffi_player));
+ drop(unsafe { Box::from_raw(ffi_player) });
}
/// Build runtime
#[unsafe(no_mangle)]
#[allow(unsafe_op_in_unsafe_fn)]
- pub unsafe extern "C" fn controller_data_build_runtime(
+ pub extern "C" fn controller_data_build_runtime(
controller: *mut FfiControllerData
) -> *mut FfiControllerRuntime {
assert!(!controller.is_null(), "ControllerData pointer is null");
@@ -85,7 +85,7 @@ impl FfiControllerData {
/// Free ControllerData memory
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_data_free(controller: *mut FfiControllerData) {
+ pub extern "C" fn controller_data_free(controller: *mut FfiControllerData) {
if controller.is_null() {
return;
}
@@ -106,7 +106,7 @@ impl FfiControllerRuntime {
/// Close runtime and exit game
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_close(
+ pub extern "C" fn controller_runtime_close(
runtime: *mut FfiControllerRuntime
) {
if runtime.is_null() {
@@ -126,7 +126,7 @@ impl FfiControllerRuntime {
/// Send control message
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_send_message(
+ pub extern "C" fn controller_runtime_send_message(
runtime: *mut FfiControllerRuntime,
control_message: *mut FfiControlMessage
) {
@@ -147,7 +147,7 @@ impl FfiControllerRuntime {
/// Send text message
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_send_text_message(
+ pub extern "C" fn controller_runtime_send_text_message(
runtime: *mut FfiControllerRuntime,
message_ptr: *const c_char
) {
@@ -159,17 +159,15 @@ impl FfiControllerRuntime {
let text = c_str.to_string_lossy().into_owned();
let message = FfiControlMessage::from(ControlMessage::Msg(text));
- unsafe {
- Self::controller_runtime_send_message(
- runtime,
- Box::into_raw(Box::new(message))
- )
- }
+ Self::controller_runtime_send_message(
+ runtime,
+ Box::into_raw(Box::new(message))
+ )
}
/// Press a button
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_press_a_button(
+ pub extern "C" fn controller_runtime_press_a_button(
runtime: *mut FfiControllerRuntime,
key: u8
) {
@@ -181,17 +179,15 @@ impl FfiControllerRuntime {
ControlMessage::Pressed(key)
);
- unsafe {
- Self::controller_runtime_send_message(
- runtime,
- Box::into_raw(Box::new(message))
- )
- }
+ Self::controller_runtime_send_message(
+ runtime,
+ Box::into_raw(Box::new(message))
+ )
}
/// Release a button
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_release_a_button(
+ pub extern "C" fn controller_runtime_release_a_button(
runtime: *mut FfiControllerRuntime,
key: u8
) {
@@ -203,17 +199,15 @@ impl FfiControllerRuntime {
ControlMessage::Released(key)
);
- unsafe {
- Self::controller_runtime_send_message(
- runtime,
- Box::into_raw(Box::new(message))
- )
- }
+ Self::controller_runtime_send_message(
+ runtime,
+ Box::into_raw(Box::new(message))
+ )
}
/// Change axis value
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_change_axis(
+ pub extern "C" fn controller_runtime_change_axis(
runtime: *mut FfiControllerRuntime,
key: u8,
axis: c_double
@@ -226,17 +220,15 @@ impl FfiControllerRuntime {
ControlMessage::Axis(key, axis)
);
- unsafe {
- Self::controller_runtime_send_message(
- runtime,
- Box::into_raw(Box::new(message))
- )
- }
+ Self::controller_runtime_send_message(
+ runtime,
+ Box::into_raw(Box::new(message))
+ )
}
/// Change direction value
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_change_direction(
+ pub extern "C" fn controller_runtime_change_direction(
runtime: *mut FfiControllerRuntime,
key: u8,
x: c_double,
@@ -250,17 +242,15 @@ impl FfiControllerRuntime {
ControlMessage::Dir(key, (x, y))
);
- unsafe {
- Self::controller_runtime_send_message(
- runtime,
- Box::into_raw(Box::new(message))
- )
- }
+ Self::controller_runtime_send_message(
+ runtime,
+ Box::into_raw(Box::new(message))
+ )
}
/// Pop a message from the queue
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_pop(
+ pub extern "C" fn controller_runtime_pop(
runtime: *mut FfiControllerRuntime
) -> *mut FfiGameMessage {
if runtime.is_null() {
@@ -294,7 +284,7 @@ impl FfiControllerRuntime {
/// Free runtime memory
#[unsafe(no_mangle)]
- pub unsafe extern "C" fn controller_runtime_free(runtime: *mut FfiControllerRuntime) {
+ pub extern "C" fn free_controller_runtime(runtime: *mut FfiControllerRuntime) {
if runtime.is_null() {
return;
}
diff --git a/core/bindings/lang/clang/src/data/ngpd_game.rs b/core/bindings/lang/clang/src/data/ngpd_game.rs
new file mode 100644
index 0000000..dc82822
--- /dev/null
+++ b/core/bindings/lang/clang/src/data/ngpd_game.rs
@@ -0,0 +1,641 @@
+use crate::data::ngpd_message::{free_control_message, FfiControlMessage, FfiExitReason, FfiGameMessage};
+use crate::data::ngpd_player::{free_player, FfiPlayer};
+use crate::service::ngpd_service_types::FfiServiceType;
+use nogamepads::entry_mutex;
+use nogamepads_core::data::game::game_data::{GameData, GameRuntimeDataArchive};
+use nogamepads_core::data::game::game_runtime::GameRuntime;
+use nogamepads_core::data::message::message_enums::{ExitReason, GameMessage};
+use nogamepads_core::data::player::player_data::Player;
+use nogamepads_core::service::service_types::ServiceType;
+use std::ffi::{c_char, c_double, c_void, CStr};
+use std::ptr::null;
+use std::sync::{Arc, Mutex, MutexGuard};
+
+#[repr(C)]
+pub struct FfiGameData(*mut c_void);
+
+#[repr(C)]
+pub struct FfiGameRuntimeArchive(*mut c_void);
+
+#[repr(C)]
+pub struct FfiControlEvent {
+ player: FfiPlayer,
+ message: FfiControlMessage
+}
+
+#[repr(C)]
+pub struct FfiGameRuntime {
+ inner: *mut c_void,
+ drop_fn: extern "C" fn(*mut c_void),
+}
+
+#[repr(C)]
+pub struct FfiButtonStatus {
+ found: bool,
+ pressed: bool,
+ released: bool
+}
+
+#[repr(C)]
+pub struct FfiAxis {
+ found: bool,
+ axis: c_double
+}
+
+#[repr(C)]
+pub struct FfiDirection {
+ found: bool,
+ x: c_double,
+ y: c_double,
+}
+
+#[repr(C)]
+pub struct FfiBooleanResult {
+ found: bool,
+ result: bool
+}
+
+#[repr(C)]
+pub struct FfiPlayerList {
+ players: *mut FfiPlayer,
+ len: usize,
+ cap: usize,
+}
+
+impl FfiGameData {
+
+ /// Create game data
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_new() -> *mut FfiGameData {
+ let game_data = GameData::default();
+ let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(game_data)) as *mut _)));
+ raw
+ }
+
+ /// Load data archive
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_load_archive(
+ data: *mut FfiGameData,
+ archive: *mut FfiGameRuntimeArchive,
+ ) -> *mut FfiGameData {
+ if data.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ if archive.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
+ let archive_inner = unsafe { &mut *((*archive).0 as *mut GameRuntimeDataArchive) };
+ let archive = *unsafe { Box::from_raw(archive_inner) };
+ data_inner.load_data(archive);
+
+ let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _)));
+ raw
+ }
+
+ /// Build runtime by data
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_build_runtime(
+ data: *mut FfiGameData
+ ) -> *mut FfiGameRuntime {
+ if data.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
+ let game_data = *unsafe { Box::from_raw(data_inner) };
+
+ let runtime = game_data.runtime();
+
+ extern "C" fn drop_runtime(raw: *mut c_void) {
+ unsafe {
+ let arc_ptr = raw as *const Arc<Mutex<GameRuntime>>;
+ drop(Arc::from_raw(arc_ptr));
+ }
+ }
+
+ let arc_raw = Arc::into_raw(runtime.clone()) as *mut c_void;
+
+ Box::into_raw(Box::new(FfiGameRuntime {
+ inner: arc_raw,
+ drop_fn: drop_runtime,
+ }))
+ }
+
+ /// Free data
+ #[unsafe(no_mangle)]
+ pub extern "C" fn free_game_data(data: *mut FfiGameData) {
+ if data.is_null() {
+ return;
+ }
+ let ffi_wrapper = unsafe { Box::from_raw(data) };
+ let inner_ptr = ffi_wrapper.0 as *mut GameData;
+ let _ = unsafe { Box::from_raw(inner_ptr) };
+ }
+}
+
+impl FfiGameRuntimeArchive {
+
+ /// Create game archive data
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_archive_data_new() -> *mut FfiGameRuntimeArchive {
+ let archive_data = GameRuntimeDataArchive::default();
+ let raw = Box::into_raw(Box::new(FfiGameRuntimeArchive(Box::into_raw(Box::new(archive_data)) as *mut _)));
+ raw
+ }
+
+ /// Add ban player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_archive_data_add_ban_player(
+ data: *mut FfiGameRuntimeArchive,
+ ffi_player: *mut FfiPlayer
+ ) -> *mut FfiGameRuntimeArchive {
+ if data.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ if ffi_player.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameRuntimeDataArchive) };
+ let ffi_player_ref = unsafe { &*ffi_player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+
+ data_inner.banned.push(player.account);
+
+ Box::into_raw(Box::new(FfiGameRuntimeArchive(Box::into_raw(Box::new(data_inner)) as *mut _)))
+ }
+
+ /// Free data
+ #[unsafe(no_mangle)]
+ pub extern "C" fn free_game_archive_data(data: *mut FfiGameRuntimeArchive) {
+ if data.is_null() {
+ return;
+ }
+ let ffi_wrapper = unsafe { Box::from_raw(data) };
+ let inner_ptr = ffi_wrapper.0 as *mut GameRuntimeDataArchive;
+ let _ = unsafe { Box::from_raw(inner_ptr) };
+ }
+}
+
+impl FfiGameRuntime {
+
+ fn send_message_to(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType,
+ message: GameMessage,
+ ) {
+ if runtime.is_null() || player.is_null() { return; }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let service = unsafe { ServiceType::from(&service_type.read()) };
+
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ mutex_guard.send_game_message(&player.account, message, service);
+ });
+ }
+
+ fn do_on_rt(
+ runtime: *mut FfiGameRuntime,
+ do_on: fn(guard: &mut MutexGuard<GameRuntime>)
+ ) {
+ if runtime.is_null() { return; }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ do_on(mutex_guard);
+ });
+ }
+
+ /// Send a message to
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_send_message_to(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ message: *mut FfiGameMessage,
+ service_type: *mut FfiServiceType
+ ) {
+ if message.is_null() { return; }
+ let msg = unsafe { GameMessage::from(message.read()) };
+ Self::send_message_to(runtime, player, service_type, msg);
+ }
+
+ /// Send a text message
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_send_text_message(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType,
+ text: *const c_char
+ ) {
+ let text_str = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned().to_string();
+ Self::send_message_to(runtime, player, service_type, GameMessage::Msg(text_str));
+ }
+
+ /// Send a event message
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_send_event(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType,
+ key: u8
+ ) {
+ Self::send_message_to(runtime, player, service_type, GameMessage::EventTrigger(key));
+ }
+
+ /// Pop a control event
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_pop_control_event(runtime: *mut FfiGameRuntime) -> *mut FfiControlEvent {
+ if runtime.is_null() { return std::ptr::null_mut(); }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ let mut control_event = None;
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ control_event = mutex_guard.pop_control_event();
+ });
+ match control_event {
+ None => { std::ptr::null_mut() }
+ Some((account, message)) => {
+ let hash = account.player_hash;
+ let player = FfiPlayer::from(&Player::register_from_hash(hash));
+ let message = FfiControlMessage::from(message);
+ Box::into_raw(Box::new(FfiControlEvent { player, message }))
+ }
+ }
+ }
+
+ /// Let player exit
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_let_exit(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType,
+ reason: *mut FfiExitReason
+ ) {
+ if reason.is_null() { return; }
+ let reason = unsafe { reason.read() };
+ let reason_msg = GameMessage::LetExit(ExitReason::from(&reason));
+ Self::send_message_to(runtime, player, service_type, reason_msg);
+ }
+
+ /// Kick a player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_kick_player(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType
+ ) {
+ if runtime.is_null() || player.is_null() || service_type.is_null() { return; }
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let service = unsafe { ServiceType::from(&service_type.read()) };
+
+ if runtime.is_null() { return; }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ mutex_guard.kick_player(&player, service);
+ });
+ }
+
+ /// Ban a player (And kick)
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_ban_player(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ service_type: *mut FfiServiceType
+ ) {
+ if runtime.is_null() || player.is_null() || service_type.is_null() { return; }
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let service = unsafe { ServiceType::from(&service_type.read()) };
+
+ if runtime.is_null() { return; }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ mutex_guard.ban_player(&player, service);
+ });
+ }
+
+ /// Pardon a player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_pardon_player(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer
+ ) {
+ if runtime.is_null() || player.is_null() { return; }
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+
+ if runtime.is_null() { return; }
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ mutex_guard.pardon_player(&player);
+ });
+ }
+
+ /// Close runtime
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_close(runtime: *mut FfiGameRuntime) {
+ if runtime.is_null() { return; }
+ Self::do_on_rt(runtime, |guard| {
+ guard.close_game();
+ })
+ }
+
+ /// Lock game
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_lock(runtime: *mut FfiGameRuntime) {
+ if runtime.is_null() { return; }
+ Self::do_on_rt(runtime, |guard| {
+ guard.lock_game();
+ })
+ }
+
+ /// Unlock game
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_unlock(runtime: *mut FfiGameRuntime) {
+ if runtime.is_null() { return; }
+ Self::do_on_rt(runtime, |guard| {
+ guard.unlock_game();
+ })
+ }
+
+ /// Get game lock status
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_lock_status(runtime: *mut FfiGameRuntime) -> bool {
+ if runtime.is_null() { return false; }
+
+ let mut locked = false;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ locked = mutex_guard.is_game_locked();
+ });
+
+ locked
+ }
+
+ /// Get button status of player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_button_status(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ key: u8
+ ) -> FfiButtonStatus {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut status = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ status = mutex_guard.control.get_button_status(&account, &key);
+ });
+
+ match status {
+ None => { FfiButtonStatus { found: false, pressed: false, released: false } }
+ Some(status) => {
+ FfiButtonStatus { found: true, pressed: status, released: !status }
+ }
+ }
+ }
+
+ /// Get axis value of player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_axis(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ key: u8
+ ) -> FfiAxis {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut status = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ status = mutex_guard.control.get_axis(&account, &key);
+ });
+
+ match status {
+ None => { FfiAxis { found: false, axis: 0.0 } }
+ Some(status) => {
+ FfiAxis { found: true, axis: status }
+ }
+ }
+ }
+
+ /// Get direction value of player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_direction(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer,
+ key: u8
+ ) -> FfiDirection {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut status = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ status = mutex_guard.control.get_direction(&account, &key);
+ });
+
+ match status {
+ None => { FfiDirection { found: false, x: 0.0, y: 0.0 } }
+ Some(status) => {
+ FfiDirection { found: true, x: status.0, y: status.1 }
+ }
+ }
+ }
+
+ /// Get service type of player
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_service_type(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer
+ ) -> *const FfiServiceType {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut service_type = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ service_type = mutex_guard.data.get_service_type(&account);
+ });
+
+ match service_type {
+ None => { null() }
+ Some(r) => {
+ Box::into_raw(Box::new(FfiServiceType::from(&r)))
+ }
+ }
+ }
+
+ /// Is player banned
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_is_player_banned(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer
+ ) -> FfiBooleanResult {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut banned = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ banned = Some(mutex_guard.data.is_account_banned(&account));
+ });
+
+ match banned {
+ None => { FfiBooleanResult { found: false, result: false } }
+ Some(r) => {
+ FfiBooleanResult { found: false, result: r }
+ }
+ }
+ }
+
+ /// Is player online
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_is_player_online(
+ runtime: *mut FfiGameRuntime,
+ player: *const FfiPlayer
+ ) -> FfiBooleanResult {
+
+ let ffi_player_ref = unsafe { &*player };
+ let player = Player::try_from(&*ffi_player_ref).unwrap_or_default();
+ let account = player.account;
+
+ let mut online = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ online = Some(mutex_guard.data.is_account_online(&account));
+ });
+
+ match online {
+ None => { FfiBooleanResult { found: false, result: false } }
+ Some(r) => {
+ FfiBooleanResult { found: false, result: r }
+ }
+ }
+ }
+
+ /// Get online list
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_online_list(runtime: *mut FfiGameRuntime) -> FfiPlayerList {
+
+ let mut online_list = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ online_list = Some(mutex_guard.data.online_accounts());
+ });
+
+ let mut result : Vec<FfiPlayer> = vec![];
+ if online_list.is_some() {
+ for online in online_list.unwrap() {
+ result.push(FfiPlayer::from(&Player::register_from_hash(online.player_hash)));
+ }
+ }
+
+ let len = result.len();
+ let cap = result.capacity();
+ let ptr = result.as_mut_ptr();
+ FfiPlayerList {
+ players: ptr,
+ len,
+ cap,
+ }
+ }
+
+ /// Get banned list
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_runtime_get_banned_list(runtime: *mut FfiGameRuntime) -> FfiPlayerList {
+
+ let mut banned_list = None;
+ let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ entry_mutex!(*arc_ref, |mutex_guard| {
+ banned_list = Some(mutex_guard.data.banned_accounts());
+ });
+
+ let mut result : Vec<FfiPlayer> = vec![];
+ if banned_list.is_none() {
+ for online in banned_list.unwrap() {
+ result.push(FfiPlayer::from(&Player::register_from_hash(online.player_hash)));
+ }
+ }
+
+ let len = result.len();
+ let cap = result.capacity();
+ let ptr = result.as_mut_ptr();
+ FfiPlayerList {
+ players: ptr,
+ len,
+ cap,
+ }
+ }
+}
+
+impl FfiControlEvent {
+
+ /// Free control event
+ #[unsafe(no_mangle)]
+ pub extern "C" fn free_control_event(event: *mut FfiControlEvent) {
+ if event.is_null() {
+ return;
+ }
+
+ let event_box = unsafe { Box::from_raw(event) };
+
+ let player_ptr = Box::into_raw(Box::new(event_box.player));
+ free_player(player_ptr);
+
+ let message_ptr = Box::into_raw(Box::new(event_box.message));
+ free_control_message(message_ptr);
+ }
+}
+
+impl FfiPlayerList {
+
+ /// Free player list
+ #[unsafe(no_mangle)]
+ pub extern "C" fn free_player_list(list: FfiPlayerList) {
+ if !list.players.is_null() {
+ let _ = unsafe {
+ Vec::from_raw_parts(
+ list.players,
+ list.len,
+ list.cap,
+ )
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/core/bindings/lang/clang/src/data/ngpd_game_info.rs b/core/bindings/lang/clang/src/data/ngpd_game_info.rs
index b83d0f7..c85d2f3 100644
--- a/core/bindings/lang/clang/src/data/ngpd_game_info.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_game_info.rs
@@ -96,7 +96,7 @@ impl From<&FfiGameInfo> for Option<HashMap<String, String>> {
}
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_game_info(map: FfiGameInfo) {
+pub extern "C" fn free_game_info(map: FfiGameInfo) {
let kv_pairs = unsafe { Vec::from_raw_parts(map.data, map.len, map.cap) };
for pair in kv_pairs {
diff --git a/core/bindings/lang/clang/src/data/ngpd_message.rs b/core/bindings/lang/clang/src/data/ngpd_message.rs
index 624d0b8..58635c3 100644
--- a/core/bindings/lang/clang/src/data/ngpd_message.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_message.rs
@@ -483,96 +483,105 @@ impl From<&FfiJoinFailedMessage> for JoinFailedMessage {
/// Free ControlMessage
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_control_message(msg: *mut FfiControlMessage) {
+pub extern "C" fn free_control_message(msg: *mut FfiControlMessage) {
if msg.is_null() { return; }
- let msg = Box::from_raw(msg);
+ let msg = unsafe { Box::from_raw(msg) };
- match msg.tag {
- FfiControlMessageTag::CtrlMsg => {
- if !msg.data.message.is_null() {
- drop(CString::from_raw(msg.data.message));
+ unsafe {
+ match msg.tag {
+ FfiControlMessageTag::CtrlMsg => {
+ if !msg.data.message.is_null() {
+ drop(CString::from_raw(msg.data.message));
+ }
}
+ FfiControlMessageTag::CtrlAxis => {
+ let ptr = ManuallyDrop::into_inner(msg.data.key_and_axis);
+ drop(ptr);
+ }
+ FfiControlMessageTag::CtrlDir => {
+ let ptr = ManuallyDrop::into_inner(msg.data.key_and_direction);
+ drop(ptr);
+ }
+ _ => {}
}
- FfiControlMessageTag::CtrlAxis => {
- let ptr = ManuallyDrop::into_inner(msg.data.key_and_axis);
- drop(ptr);
- }
- FfiControlMessageTag::CtrlDir => {
- let ptr = ManuallyDrop::into_inner(msg.data.key_and_direction);
- drop(ptr);
- }
- _ => {}
}
}
/// Free GameMessage
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_game_message(msg: *mut FfiGameMessage) {
+pub extern "C" fn free_game_message(msg: *mut FfiGameMessage) {
if msg.is_null() { return; }
- let msg = Box::from_raw(msg);
+ let msg = unsafe { Box::from_raw(msg) };
- match msg.tag {
- FfiGameMessageTag::GameMsg => {
- if !msg.data.message.is_null() {
- drop(CString::from_raw(msg.data.message));
+ unsafe {
+ match msg.tag {
+ FfiGameMessageTag::GameMsg => {
+ if !msg.data.message.is_null() {
+ drop(CString::from_raw(msg.data.message));
+ }
}
+ FfiGameMessageTag::GameLetExit => {
+ let reason = ManuallyDrop::into_inner(msg.data.exit_reason);
+ drop(reason);
+ }
+ _ => {}
}
- FfiGameMessageTag::GameLetExit => {
- let reason = ManuallyDrop::into_inner(msg.data.exit_reason);
- drop(reason);
- }
- _ => {}
}
}
/// Free ExitReason
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_exit_reason(msg: *mut FfiExitReason) {
+pub extern "C" fn free_exit_reason(msg: *mut FfiExitReason) {
if !msg.is_null() {
- drop(Box::from_raw(msg));
+ drop(unsafe { Box::from_raw(msg) });
}
}
+
/// Free ConnectionMessage
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_connection_message(msg: *mut FfiConnectionMessage) {
+pub extern "C" fn free_connection_message(msg: *mut FfiConnectionMessage) {
if msg.is_null() { return; }
- let msg = Box::from_raw(msg);
+ let msg = unsafe { Box::from_raw(msg) };
- match msg.tag {
- FfiConnectionMessageTag::ConnectionJoin => {
- let player = ManuallyDrop::into_inner(msg.data.player);
- let player_ptr = Box::into_raw(Box::new(player));
+ unsafe {
+ match msg.tag {
+ FfiConnectionMessageTag::ConnectionJoin => {
+ let player = ManuallyDrop::into_inner(msg.data.player);
+ let player_ptr = Box::into_raw(Box::new(player));
- free_player(player_ptr);
+ free_player(player_ptr);
+ }
+ _ => {}
}
- _ => {}
}
}
/// Free ConnectionResponseMessage
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_connection_response_message(msg: *mut FfiConnectionResponseMessage) {
+pub extern "C" fn free_connection_response_message(msg: *mut FfiConnectionResponseMessage) {
if msg.is_null() { return; }
- let msg = Box::from_raw(msg);
+ let msg = unsafe { Box::from_raw(msg) };
- match msg.tag {
- FfiConnectionResponseMessageTag::GameInfosResponse => {
- let game_info = ManuallyDrop::into_inner(msg.data.game_info);
- free_game_info(game_info);
- }
- FfiConnectionResponseMessageTag::DenyResponse |
- FfiConnectionResponseMessageTag::FailResponse => {
- let failed_msg = ManuallyDrop::into_inner(msg.data.failed_message);
- drop(failed_msg);
+ unsafe {
+ match msg.tag {
+ FfiConnectionResponseMessageTag::GameInfosResponse => {
+ let game_info = ManuallyDrop::into_inner(msg.data.game_info);
+ free_game_info(game_info);
+ }
+ FfiConnectionResponseMessageTag::DenyResponse |
+ FfiConnectionResponseMessageTag::FailResponse => {
+ let failed_msg = ManuallyDrop::into_inner(msg.data.failed_message);
+ drop(failed_msg);
+ }
+ _ => {}
}
- _ => {}
}
}
/// Free JoinFailedMessage
#[unsafe(no_mangle)]
-pub unsafe extern "C" fn free_join_failed_message(msg: *mut FfiJoinFailedMessage) {
+pub extern "C" fn free_join_failed_message(msg: *mut FfiJoinFailedMessage) {
if !msg.is_null() {
- drop(Box::from_raw(msg));
+ drop(unsafe { Box::from_raw(msg) });
}
} \ No newline at end of file
diff --git a/core/bindings/lang/clang/src/data/ngpd_player.rs b/core/bindings/lang/clang/src/data/ngpd_player.rs
index c2c3378..0c4710b 100644
--- a/core/bindings/lang/clang/src/data/ngpd_player.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_player.rs
@@ -1,11 +1,12 @@
use std::ffi::{c_char, c_double, c_int, CStr, CString};
use std::ptr;
use nogamepads_core::data::player::player_data::{Account, Customize, Player};
+use crate::converter::string_converter::str_rs_to_c;
#[repr(C)]
pub struct FfiAccount {
- id: *mut c_char,
- player_hash: *mut c_char,
+ pub(crate) id: *mut c_char,
+ pub(crate) player_hash: *mut c_char,
}
#[repr(C)]
@@ -82,6 +83,25 @@ pub extern "C" fn player_register(id: *const c_char, password: *const c_char) ->
Box::into_raw(Box::new(FfiPlayer::from(&player)))
}
+/// Register a player from hash
+#[unsafe(no_mangle)]
+pub extern "C" fn player_from_hash(hash: *const c_char) -> *mut FfiPlayer {
+ let hash_str = unsafe { CStr::from_ptr(hash) }.to_string_lossy();
+
+ let player = Player::register_from_hash(hash_str.into_owned());
+ Box::into_raw(Box::new(FfiPlayer::from(&player)))
+}
+
+/// Get a hash from player
+#[unsafe(no_mangle)]
+pub extern "C" fn player_get_hash(player: *mut FfiPlayer) -> *const c_char {
+ let rust_player : Player = unsafe { (&*player).try_into().unwrap() };
+
+ let hash = rust_player.account.player_hash.clone();
+ *unsafe { &mut *player } = FfiPlayer::from(&rust_player);
+ unsafe { str_rs_to_c(hash) }
+}
+
/// Check if the player's password is correct
#[unsafe(no_mangle)]
pub extern "C" fn player_check(player: *const FfiPlayer, password: *const c_char) -> bool {
diff --git a/core/bindings/lang/clang/src/lib.rs b/core/bindings/lang/clang/src/lib.rs
index 9a8fe37..f939758 100644
--- a/core/bindings/lang/clang/src/lib.rs
+++ b/core/bindings/lang/clang/src/lib.rs
@@ -1,2 +1,3 @@
pub mod converter;
pub mod data;
+pub mod service;
diff --git a/core/bindings/lang/clang/src/service/mod.rs b/core/bindings/lang/clang/src/service/mod.rs
new file mode 100644
index 0000000..464cfba
--- /dev/null
+++ b/core/bindings/lang/clang/src/service/mod.rs
@@ -0,0 +1 @@
+pub mod ngpd_service_types; \ No newline at end of file
diff --git a/core/bindings/lang/clang/src/service/ngpd_service_types.rs b/core/bindings/lang/clang/src/service/ngpd_service_types.rs
new file mode 100644
index 0000000..8701284
--- /dev/null
+++ b/core/bindings/lang/clang/src/service/ngpd_service_types.rs
@@ -0,0 +1,36 @@
+use nogamepads_core::service::service_types::ServiceType;
+
+#[repr(C)]
+pub enum FfiServiceType {
+ TCPConnection,
+ BlueTooth,
+ USB,
+}
+
+impl From<&ServiceType> for FfiServiceType {
+ fn from(value: &ServiceType) -> Self {
+ match value {
+ ServiceType::TCPConnection => { FfiServiceType::TCPConnection }
+ ServiceType::BlueTooth => { FfiServiceType::BlueTooth }
+ ServiceType::USB => { FfiServiceType::USB }
+ }
+ }
+}
+
+impl From<&FfiServiceType> for ServiceType {
+ fn from(value: &FfiServiceType) -> Self {
+ match value {
+ FfiServiceType::TCPConnection => { ServiceType::TCPConnection }
+ FfiServiceType::BlueTooth => { ServiceType::BlueTooth }
+ FfiServiceType::USB => { ServiceType::USB }
+ }
+ }
+}
+
+/// Free service type tag
+#[unsafe(no_mangle)]
+pub extern "C" fn free_ffi_service_type(ptr: *mut FfiServiceType) {
+ if !ptr.is_null() {
+ unsafe { let _ = Box::from_raw(ptr); }
+ }
+} \ No newline at end of file
diff --git a/core/src/data/game/game_cli.rs b/core/src/data/game/game_cli.rs
index 521de3f..fd71556 100644
--- a/core/src/data/game/game_cli.rs
+++ b/core/src/data/game/game_cli.rs
@@ -172,7 +172,7 @@ pub fn process_game_cli(runtime: Arc<Mutex<GameRuntime>>, cmd: GameCli) -> bool
Commands::Pop => {
entry_mutex!(runtime, |guard| {
- if let Some((account, message)) = guard.pop_event() {
+ if let Some((account, message)) = guard.pop_control_event() {
info!("{}: {:?}", account.id, message);
} else {
info!("None")
@@ -182,7 +182,7 @@ pub fn process_game_cli(runtime: Arc<Mutex<GameRuntime>>, cmd: GameCli) -> bool
Commands::PopAll => {
entry_mutex!(runtime, |guard| {
- while let Some((account, message)) = guard.pop_event() {
+ while let Some((account, message)) = guard.pop_control_event() {
info!("{}: {:?}", account.id, message);
}
});
diff --git a/core/src/data/game/game_data.rs b/core/src/data/game/game_data.rs
index 3bdf28b..35a5c0e 100644
--- a/core/src/data/game/game_data.rs
+++ b/core/src/data/game/game_data.rs
@@ -71,8 +71,8 @@ impl GameData {
}
/// Read game runtime archive data
- pub fn load_data(&mut self, storage: GameRuntimeDataArchive) -> &mut GameData {
- self.archive = storage;
+ pub fn load_data(&mut self, archive: GameRuntimeDataArchive) -> &mut GameData {
+ self.archive = archive;
self
}
diff --git a/core/src/data/game/game_runtime.rs b/core/src/data/game/game_runtime.rs
index 1c5a548..7ce1991 100644
--- a/core/src/data/game/game_runtime.rs
+++ b/core/src/data/game/game_runtime.rs
@@ -154,7 +154,7 @@ impl GameRuntime {
}
/// Pop an event message
- pub fn pop_event(&mut self) -> Option<(Account, ControlMessage)> {
+ pub fn pop_control_event(&mut self) -> Option<(Account, ControlMessage)> {
let pop = self.control.events.pop_front();
if pop.is_some() {
let (account, msg) = pop.unwrap();
diff --git a/core/src/data/player/player_data.rs b/core/src/data/player/player_data.rs
index 1fe5ff0..9b1ab71 100644
--- a/core/src/data/player/player_data.rs
+++ b/core/src/data/player/player_data.rs
@@ -65,6 +65,17 @@ impl Player {
player
}
+ pub fn register_from_hash(hash: String) -> Player {
+ let mut player = Player {
+ customize: None,
+ account: Account::default()
+ };
+
+ player.account.id = "$only_hash$".to_string();
+ player.account.player_hash = hash;
+ player
+ }
+
pub fn check(&self, password: String) -> bool {
let hash = Self::gen_hash(self.account.id.clone(), password);
hash == self.account.player_hash