aboutsummaryrefslogtreecommitdiff
path: root/core/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'core/bindings')
-rw-r--r--core/bindings/lang/clang/Cargo.toml1
-rw-r--r--core/bindings/lang/clang/binding_example/.idea/misc.xml1
-rw-r--r--core/bindings/lang/clang/binding_example/CMakeLists.txt6
-rw-r--r--core/bindings/lang/clang/binding_example/tcp_client.c68
-rw-r--r--core/bindings/lang/clang/binding_example/tcp_server.c64
-rw-r--r--core/bindings/lang/clang/configures/nogamepads_utils.toml10
-rw-r--r--core/bindings/lang/clang/headers/nogamepads_data.h40
-rw-r--r--core/bindings/lang/clang/headers/nogamepads_utils.h671
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_controller.rs121
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_game.rs355
-rw-r--r--core/bindings/lang/clang/src/lib.rs1
-rw-r--r--core/bindings/lang/clang/src/logger_utils.rs13
-rw-r--r--core/bindings/lang/clang/src/service/ngpd_service_types.rs4
-rw-r--r--core/bindings/lang/clang/src/service/ngpd_tcp_service.rs68
14 files changed, 1161 insertions, 262 deletions
diff --git a/core/bindings/lang/clang/Cargo.toml b/core/bindings/lang/clang/Cargo.toml
index 7eae084..a0c8283 100644
--- a/core/bindings/lang/clang/Cargo.toml
+++ b/core/bindings/lang/clang/Cargo.toml
@@ -8,6 +8,7 @@ build = "build.rs"
[dependencies]
nogamepads = { path = "./../../../../../NoGamepads" }
nogamepads-core = { path = "./../../../../core" }
+log = "0.4.27"
[build-dependencies]
cbindgen = "0.29.0"
diff --git a/core/bindings/lang/clang/binding_example/.idea/misc.xml b/core/bindings/lang/clang/binding_example/.idea/misc.xml
index 0b76fe5..e479d63 100644
--- a/core/bindings/lang/clang/binding_example/.idea/misc.xml
+++ b/core/bindings/lang/clang/binding_example/.idea/misc.xml
@@ -4,4 +4,5 @@
<option name="pythonIntegrationState" value="YES" />
</component>
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
+ <component name="WestSettings"><![CDATA[{}]]></component>
</project> \ No newline at end of file
diff --git a/core/bindings/lang/clang/binding_example/CMakeLists.txt b/core/bindings/lang/clang/binding_example/CMakeLists.txt
index 29b5fda..02185bf 100644
--- a/core/bindings/lang/clang/binding_example/CMakeLists.txt
+++ b/core/bindings/lang/clang/binding_example/CMakeLists.txt
@@ -3,12 +3,18 @@ project(binding_example C)
set(CMAKE_C_STANDARD 99)
+# Executables
+
add_executable(example_server_listening tcp_server.c)
add_executable(example_connect_server tcp_client.c)
+# Includes
+
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/libs)
+# Libraries
+
target_link_libraries(example_server_listening
${PROJECT_SOURCE_DIR}/libs/nogamepads_c.dll.lib
)
diff --git a/core/bindings/lang/clang/binding_example/tcp_client.c b/core/bindings/lang/clang/binding_example/tcp_client.c
index ba219a9..7caa647 100644
--- a/core/bindings/lang/clang/binding_example/tcp_client.c
+++ b/core/bindings/lang/clang/binding_example/tcp_client.c
@@ -1,35 +1,67 @@
-#include <stdio.h>
#include "include/nogamepads_data.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define USERNAME "juliet"
+#define PASSWORD "12345678"
+#define DISPLAY_NAME "IM JULIET"
+#define SERVER_IP {127, 0, 0, 1}
+#define SERVER_PORT 5989
int main(void) {
- printf("//////////////////////////////////////// \n");
- printf("///// NoGamepads C Binding ///////////// \n");
- printf("///// Example: Connect to a server ///// \n");
- printf("//////////////////////////////////////// \n");
- printf("\n");
+ // Create player
+ FfiPlayer *player = player_register(USERNAME, PASSWORD);
+ if (!player) {
+ fprintf(stderr, "Failed to register player\n");
+ return EXIT_FAILURE;
+ }
- FfiPlayer *player = player_register("juliet", "12345678");
+ // Configure player attributes
player_set_hsv(player, 120, 0.5, 0.9);
- player_set_nickname(player, "IM JULIET");
- printf("Player created. \n");
+ player_set_nickname(player, DISPLAY_NAME);
+ // Initialize controller
FfiControllerData *controller = controller_data_new();
- controller_data_bind_player(controller, player);
- printf("Controller data created. \n");
+ if (!controller) {
+ fprintf(stderr, "Failed to create controller\n");
+ free_player(player);
+ return EXIT_FAILURE;
+ } else {
+ controller_data_bind_player(controller, player);
+ }
+ // Create runtime
FfiControllerRuntime *rt = controller_data_build_runtime(controller);
- printf("Runtime created. \n");
+ if (!rt) {
+ fprintf(stderr, "Failed to create runtime\n");
+ free_player(player);
+ free_controller_data(controller);
+ return EXIT_FAILURE;
+ }
+ // Create TcpNetwork client
FfiTcpClientService *client = tcp_client_build(rt);
- printf("Tcp client built. \n");
+ if (!client) {
+ fprintf(stderr, "Failed to create client\n");
+ free_controller_runtime(rt);
+ free_controller_data(controller);
+ free_player(player);
+ return EXIT_FAILURE;
+ } else {
+ uint8_t ip[4] = SERVER_IP;
+ tcp_client_bind_address_v4(client, ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
+ }
- tcp_client_bind_address_v4(client, 127, 0, 0, 1, 5989);
- printf("Address bind. \n");
+ enable_logger(0);
- printf("Connecting \n");
+ // Connect to server and block
tcp_client_connect(client);
- printf("Disconnected \n");
+
+ // Release memory
+ free_controller_runtime(rt);
+ free_controller_data(controller);
+ free_player(player);
return 0;
-}
+} \ No newline at end of file
diff --git a/core/bindings/lang/clang/binding_example/tcp_server.c b/core/bindings/lang/clang/binding_example/tcp_server.c
index b0ff629..dd02a4a 100644
--- a/core/bindings/lang/clang/binding_example/tcp_server.c
+++ b/core/bindings/lang/clang/binding_example/tcp_server.c
@@ -1,43 +1,57 @@
-#include <stdio.h>
-#include <pthread.h>
#include "include/nogamepads_data.h"
+#include <stdio.h>
+#include <stdlib.h>
-void* server_thread(void* arg) {
- FfiTcpServerService *server = arg;
- tcp_server_listening_block_on(server);
-
- printf("Server stopped. \n");
- return NULL;
-}
+#define GAME_NAME "My Hero"
+#define GAME_VERSION "0.1.0"
+#define SERVER_IP {127, 0, 0, 1}
+#define SERVER_PORT 5989
int main(void) {
- printf("//////////////////////////////////// \n");
- printf("///// NoGamepads C Binding ///////// \n");
- printf("///// Example: Start a server. ///// \n");
- printf("//////////////////////////////////// \n");
- printf("\n");
-
+ // Game data initialization
FfiGameData *data = game_data_new();
- printf("Data created. \n");
+ if (!data) {
+ fprintf(stderr, "Failed to create game data\n");
+ return EXIT_FAILURE;
+ }
+
+ // Configure game information
+ game_data_set_name_info(data, GAME_NAME);
+ game_data_set_version_info(data, GAME_VERSION);
+ // Create runtime
FfiGameRuntime *rt = game_data_build_runtime(data);
- printf("Runtime created. \n");
+ if (!rt) {
+ fprintf(stderr, "Failed to create runtime\n");
+ free_game_data(data);
+ return EXIT_FAILURE;
+ }
+ // Start the server
FfiTcpServerService *server = tcp_server_build(rt);
- printf("Tcp services created. \n");
+ if (!server) {
+ fprintf(stderr, "Failed to create server\n");
+ free_game_runtime(rt);
+ free_game_data(data);
+ return EXIT_FAILURE;
+ }
- tcp_server_bind_address_v4(server, 127, 0, 0, 1, 5989);
- printf("Address bind. \n");
+ // Bind address
+ uint8_t ip[4] = SERVER_IP;
+ tcp_server_bind_address_v4(server, ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
- pthread_t thread;
- pthread_create(&thread, NULL, server_thread, server);
+ printf("Server started at %d.%d.%d.%d:%d\n", ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
- printf("Server started. Press Enter to stop...\n");
+ enable_logger(2);
- getchar();
+ // Start server listening
+ tcp_server_listening_block_on(server);
- printf("Process stopped. \n");
+ printf("Server closed\n");
+ // Release memory
+ free_game_runtime(rt);
+ free_game_data(data);
return 0;
} \ No newline at end of file
diff --git a/core/bindings/lang/clang/configures/nogamepads_utils.toml b/core/bindings/lang/clang/configures/nogamepads_utils.toml
new file mode 100644
index 0000000..4d1c271
--- /dev/null
+++ b/core/bindings/lang/clang/configures/nogamepads_utils.toml
@@ -0,0 +1,10 @@
+language = "C"
+include_guard = "NOGAMEPADS_UTILS_H"
+header = "// Auto generated by cbindgen 0.29.0"
+cpp_compat = true
+
+[parse]
+parse_deps = true
+include = [
+ "logger_utils"
+] \ 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 91a07d9..d0fc002 100644
--- a/core/bindings/lang/clang/headers/nogamepads_data.h
+++ b/core/bindings/lang/clang/headers/nogamepads_data.h
@@ -62,6 +62,7 @@ typedef enum FfiJoinFailedMessage {
} FfiJoinFailedMessage;
typedef enum FfiServiceType {
+ Unknown,
TCPConnection,
BlueTooth,
USB,
@@ -308,7 +309,7 @@ struct FfiControllerRuntime *controller_data_build_runtime(struct FfiControllerD
/**
* Free ControllerData memory
*/
-void controller_data_free(struct FfiControllerData *controller);
+void free_controller_data(struct FfiControllerData *controller);
/**
* Close runtime and exit game
@@ -366,6 +367,23 @@ void free_controller_runtime(struct FfiControllerRuntime *runtime);
struct FfiGameData *game_data_new(void);
/**
+ * Add info
+ */
+struct FfiGameData *game_data_add_info(struct FfiGameData *data,
+ const char *key,
+ const char *value);
+
+/**
+ * Set name info
+ */
+struct FfiGameData *game_data_set_name_info(struct FfiGameData *data, const char *name);
+
+/**
+ * Set version info
+ */
+struct FfiGameData *game_data_set_version_info(struct FfiGameData *data, const char *version);
+
+/**
* Load data archive
*/
struct FfiGameData *game_data_load_archive(struct FfiGameData *data,
@@ -403,14 +421,14 @@ void free_game_archive_data(struct FfiGameRuntimeArchive *data);
void game_runtime_send_message_to(struct FfiGameRuntime *runtime,
const struct FfiPlayer *player,
struct FfiGameMessage *message,
- enum FfiServiceType *service_type);
+ 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,
+ enum FfiServiceType service_type,
const char *text);
/**
@@ -418,7 +436,7 @@ void game_runtime_send_text_message(struct FfiGameRuntime *runtime,
*/
void game_runtime_send_event(struct FfiGameRuntime *runtime,
const struct FfiPlayer *player,
- enum FfiServiceType *service_type,
+ enum FfiServiceType service_type,
uint8_t key);
/**
@@ -431,22 +449,22 @@ struct FfiControlEvent *game_runtime_pop_control_event(struct FfiGameRuntime *ru
*/
void game_runtime_let_exit(struct FfiGameRuntime *runtime,
const struct FfiPlayer *player,
- enum FfiServiceType *service_type,
- enum FfiExitReason *reason);
+ 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);
+ 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);
+ enum FfiServiceType service_type);
/**
* Pardon a player
@@ -497,8 +515,8 @@ struct FfiDirection game_runtime_get_direction(struct FfiGameRuntime *runtime,
/**
* Get service type of player
*/
-const enum FfiServiceType *game_runtime_get_service_type(struct FfiGameRuntime *runtime,
- const struct FfiPlayer *player);
+enum FfiServiceType game_runtime_get_service_type(struct FfiGameRuntime *runtime,
+ const struct FfiPlayer *player);
/**
* Is player banned
@@ -644,6 +662,8 @@ void tcp_server_listening_block_on(struct FfiTcpServerService *service);
*/
void free_tcp_server(struct FfiTcpServerService *service);
+void enable_logger(uint8_t level);
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
diff --git a/core/bindings/lang/clang/headers/nogamepads_utils.h b/core/bindings/lang/clang/headers/nogamepads_utils.h
new file mode 100644
index 0000000..df8628e
--- /dev/null
+++ b/core/bindings/lang/clang/headers/nogamepads_utils.h
@@ -0,0 +1,671 @@
+// Auto generated by cbindgen 0.29.0
+
+#ifndef NOGAMEPADS_UTILS_H
+#define NOGAMEPADS_UTILS_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef enum FfiConnectionMessageTag {
+ ConnectionJoin,
+ ConnectionRequestGameInfos,
+ ConnectionRequestLayoutConfigure,
+ ConnectionRequestSkinPackage,
+ ConnectionReady,
+ ConnectionError,
+} FfiConnectionMessageTag;
+
+typedef enum FfiConnectionResponseMessageTag {
+ GameInfosResponse,
+ DenyResponse,
+ FailResponse,
+ OkResponse,
+ WelcomeResponse,
+ ErrorResponse,
+} FfiConnectionResponseMessageTag;
+
+typedef enum FfiControlMessageTag {
+ CtrlMsg,
+ CtrlPressed,
+ CtrlReleased,
+ CtrlAxis,
+ CtrlDir,
+ CtrlExit,
+ CtrlError,
+ CtrlEnd,
+} FfiControlMessageTag;
+
+typedef enum FfiExitReason {
+ ExitReason,
+ GameOverReason,
+ ServerClosedReason,
+ YouAreKickedReason,
+ YouAreBannedReason,
+ ErrorReason,
+} FfiExitReason;
+
+typedef enum FfiGameMessageTag {
+ GameEventTrigger,
+ GameMsg,
+ GameLetExit,
+ GameError,
+ GameEnd,
+} FfiGameMessageTag;
+
+typedef enum FfiJoinFailedMessage {
+ ContainIdenticalPlayer,
+ PlayerBanned,
+ GameLocked,
+ UnknownError,
+} FfiJoinFailedMessage;
+
+typedef enum FfiServiceType {
+ Unknown,
+ TCPConnection,
+ BlueTooth,
+ USB,
+} FfiServiceType;
+
+typedef struct FfiAccount {
+ char *id;
+ char *player_hash;
+} FfiAccount;
+
+typedef struct FfiCustomize {
+ char *nickname;
+ int color_hue;
+ double color_saturation;
+ double color_value;
+} FfiCustomize;
+
+typedef struct FfiPlayer {
+ struct FfiAccount account;
+ struct FfiCustomize *customize;
+} FfiPlayer;
+
+typedef struct FfiKeyAndAxis {
+ uint8_t key;
+ double axis;
+} FfiKeyAndAxis;
+
+typedef struct FfiKeyAndDirection {
+ uint8_t key;
+ double x;
+ double y;
+} FfiKeyAndDirection;
+
+typedef union FfiControlMessageUnion {
+ char *message;
+ uint8_t key;
+ struct FfiKeyAndAxis key_and_axis;
+ struct FfiKeyAndDirection key_and_direction;
+} FfiControlMessageUnion;
+
+typedef struct FfiControlMessage {
+ enum FfiControlMessageTag tag;
+ union FfiControlMessageUnion data;
+} FfiControlMessage;
+
+typedef union FfiGameMessageUnion {
+ uint8_t key;
+ char *message;
+ enum FfiExitReason exit_reason;
+} FfiGameMessageUnion;
+
+typedef struct FfiGameMessage {
+ enum FfiGameMessageTag tag;
+ union FfiGameMessageUnion data;
+} FfiGameMessage;
+
+typedef union FfiConnectionMessageUnion {
+ struct FfiPlayer player;
+} FfiConnectionMessageUnion;
+
+typedef struct FfiConnectionMessage {
+ enum FfiConnectionMessageTag tag;
+ union FfiConnectionMessageUnion data;
+} FfiConnectionMessage;
+
+typedef struct KeyValuePair {
+ char *key;
+ char *value;
+} KeyValuePair;
+
+typedef struct FfiGameInfo {
+ struct KeyValuePair *data;
+ uintptr_t len;
+ uintptr_t cap;
+} FfiGameInfo;
+
+typedef union FfiConnectionResponseMessageUnion {
+ struct FfiGameInfo game_info;
+ enum FfiJoinFailedMessage failed_message;
+} FfiConnectionResponseMessageUnion;
+
+typedef struct FfiConnectionResponseMessage {
+ enum FfiConnectionResponseMessageTag tag;
+ union FfiConnectionResponseMessageUnion data;
+} FfiConnectionResponseMessage;
+
+typedef struct FfiControllerData {
+ void *_0;
+} FfiControllerData;
+
+typedef struct FfiControllerRuntime {
+ void *inner;
+ 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;
+
+typedef struct FfiTcpClientService {
+ void *_0;
+} FfiTcpClientService;
+
+typedef struct FfiTcpServerService {
+ void *_0;
+} FfiTcpServerService;
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+void free_c_string(char *ptr);
+
+/**
+ * Register a player
+ */
+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);
+
+/**
+ * Set the player's nickname
+ */
+void player_set_nickname(struct FfiPlayer *player, const char *nickname);
+
+/**
+ * Set the player's hue
+ */
+void player_set_hue(struct FfiPlayer *player, int hue);
+
+/**
+ * Set the player's HSV color
+ */
+void player_set_hsv(struct FfiPlayer *player, int hue, double saturation, double value);
+
+/**
+ * Free the player
+ */
+void free_player(struct FfiPlayer *player);
+
+/**
+ * Free ControlMessage
+ */
+void free_control_message(struct FfiControlMessage *msg);
+
+/**
+ * Free GameMessage
+ */
+void free_game_message(struct FfiGameMessage *msg);
+
+/**
+ * Free ExitReason
+ */
+void free_exit_reason(enum FfiExitReason *msg);
+
+/**
+ * Free ConnectionMessage
+ */
+void free_connection_message(struct FfiConnectionMessage *msg);
+
+/**
+ * Free ConnectionResponseMessage
+ */
+void free_connection_response_message(struct FfiConnectionResponseMessage *msg);
+
+/**
+ * Free JoinFailedMessage
+ */
+void free_join_failed_message(enum FfiJoinFailedMessage *msg);
+
+void free_game_info(struct FfiGameInfo map);
+
+/**
+ * Create controller data
+ */
+struct FfiControllerData *controller_data_new(void);
+
+/**
+ * Bind player to controller
+ */
+void controller_data_bind_player(struct FfiControllerData *controller,
+ struct FfiPlayer *ffi_player);
+
+/**
+ * Build runtime
+ */
+struct FfiControllerRuntime *controller_data_build_runtime(struct FfiControllerData *controller);
+
+/**
+ * Free ControllerData memory
+ */
+void free_controller_data(struct FfiControllerData *controller);
+
+/**
+ * Close runtime and exit game
+ */
+void controller_runtime_close(struct FfiControllerRuntime *runtime);
+
+/**
+ * Send control message
+ */
+void controller_runtime_send_message(struct FfiControllerRuntime *runtime,
+ struct FfiControlMessage *control_message);
+
+/**
+ * Send text message
+ */
+void controller_runtime_send_text_message(struct FfiControllerRuntime *runtime,
+ const char *message_ptr);
+
+/**
+ * Press a button
+ */
+void controller_runtime_press_a_button(struct FfiControllerRuntime *runtime, uint8_t key);
+
+/**
+ * Release a button
+ */
+void controller_runtime_release_a_button(struct FfiControllerRuntime *runtime, uint8_t key);
+
+/**
+ * Change axis value
+ */
+void controller_runtime_change_axis(struct FfiControllerRuntime *runtime, uint8_t key, double axis);
+
+/**
+ * Change direction value
+ */
+void controller_runtime_change_direction(struct FfiControllerRuntime *runtime,
+ uint8_t key,
+ double x,
+ double y);
+
+/**
+ * Pop a message from the queue
+ */
+struct FfiGameMessage *controller_runtime_pop(struct FfiControllerRuntime *runtime);
+
+/**
+ * Free runtime memory
+ */
+void free_controller_runtime(struct FfiControllerRuntime *runtime);
+
+/**
+ * Create game data
+ */
+struct FfiGameData *game_data_new(void);
+
+/**
+ * Add info
+ */
+struct FfiGameData *game_data_add_info(struct FfiGameData *data,
+ const char *key,
+ const char *value);
+
+/**
+ * Set name info
+ */
+struct FfiGameData *game_data_set_name_info(struct FfiGameData *data, const char *name);
+
+/**
+ * Set version info
+ */
+struct FfiGameData *game_data_set_version_info(struct FfiGameData *data, const char *version);
+
+/**
+ * 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
+ */
+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 game runtime
+ */
+void free_game_runtime(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);
+
+/**
+ * Build tcp client
+ */
+struct FfiTcpClientService *tcp_client_build(struct FfiControllerRuntime *runtime);
+
+/**
+ * Bind ipv4 address
+ */
+void tcp_client_bind_ipv4(struct FfiTcpClientService *service,
+ uint8_t a0,
+ uint8_t a1,
+ uint8_t a2,
+ uint8_t a3);
+
+/**
+ * Bind ipv6 address
+ */
+bool tcp_client_bind_ipv6(struct FfiTcpClientService *service, const char *ip_str);
+
+/**
+ * Bind port
+ */
+void tcp_client_bind_port(struct FfiTcpClientService *service, uint16_t port);
+
+/**
+ * Bind address with ipv4
+ */
+void tcp_client_bind_address_v4(struct FfiTcpClientService *service,
+ uint8_t a0,
+ uint8_t a1,
+ uint8_t a2,
+ uint8_t a3,
+ uint16_t port);
+
+/**
+ * Bind address with ipv6
+ */
+bool tcp_client_bind_address_v6(struct FfiTcpClientService *service,
+ const char *ip_str,
+ uint16_t port);
+
+/**
+ * Connect
+ */
+void tcp_client_connect(struct FfiTcpClientService *service);
+
+/**
+ * Free tcp client
+ */
+void free_tcp_client(struct FfiTcpClientService *service);
+
+/**
+ * Build tcp server
+ */
+struct FfiTcpServerService *tcp_server_build(struct FfiGameRuntime *runtime);
+
+/**
+ * Bind ipv4 address
+ */
+void tcp_server_bind_ipv4(struct FfiTcpServerService *service,
+ uint8_t a0,
+ uint8_t a1,
+ uint8_t a2,
+ uint8_t a3);
+
+/**
+ * Bind ipv6 address
+ */
+bool tcp_server_bind_ipv6(struct FfiTcpServerService *service, const char *ip_str);
+
+/**
+ * Bind port
+ */
+void tcp_server_bind_port(struct FfiTcpServerService *service, uint16_t port);
+
+/**
+ * Bind address with ipv4
+ */
+void tcp_server_bind_address_v4(struct FfiTcpServerService *service,
+ uint8_t a0,
+ uint8_t a1,
+ uint8_t a2,
+ uint8_t a3,
+ uint16_t port);
+
+/**
+ * Bind address with ipv6
+ */
+bool tcp_server_bind_address_v6(struct FfiTcpServerService *service,
+ const char *ip_str,
+ uint16_t port);
+
+/**
+ * Start listening
+ */
+void tcp_server_listening_block_on(struct FfiTcpServerService *service);
+
+/**
+ * Free tcp server
+ */
+void free_tcp_server(struct FfiTcpServerService *service);
+
+void enable_logger(uint8_t level);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif /* NOGAMEPADS_UTILS_H */
diff --git a/core/bindings/lang/clang/src/data/ngpd_controller.rs b/core/bindings/lang/clang/src/data/ngpd_controller.rs
index d7f7b96..3c710fb 100644
--- a/core/bindings/lang/clang/src/data/ngpd_controller.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_controller.rs
@@ -6,7 +6,8 @@ use nogamepads_core::data::controller::controller_runtime::ControllerRuntime;
use nogamepads_core::data::message::message_enums::ControlMessage;
use nogamepads_core::data::player::player_data::Player;
use std::ffi::{c_char, c_double, c_void, CStr};
-use std::sync::{Arc, Mutex};
+use std::ptr::null_mut;
+use std::sync::{Arc, Mutex, MutexGuard};
#[repr(C)]
pub struct FfiControllerData(*mut c_void);
@@ -29,13 +30,11 @@ impl FfiControllerData {
/// Bind player to controller
#[unsafe(no_mangle)]
- #[allow(unsafe_op_in_unsafe_fn)]
pub extern "C" fn controller_data_bind_player(
controller: *mut FfiControllerData,
ffi_player: *mut FfiPlayer
) {
- assert!(!controller.is_null(), "ControllerData pointer is null");
- assert!(!ffi_player.is_null(), "FfiPlayer pointer is null");
+ if controller.is_null() || ffi_player.is_null() { return; }
let ffi_player_ref = unsafe { &*ffi_player };
@@ -52,39 +51,32 @@ impl FfiControllerData {
/// Build runtime
#[unsafe(no_mangle)]
- #[allow(unsafe_op_in_unsafe_fn)]
pub extern "C" fn controller_data_build_runtime(
controller: *mut FfiControllerData
) -> *mut FfiControllerRuntime {
- assert!(!controller.is_null(), "ControllerData pointer is null");
+ let controller_inner = unsafe { &mut *((*controller).0 as *mut ControllerData) };
+ let arc = controller_inner.runtime_with_borrowed_data();
+ let ptr = Arc::into_raw(arc) as *mut c_void;
- // Take ownership
- let controller_box = unsafe { Box::from_raw(controller) };
- let raw_data = controller_box.0;
+ let ffi_runtime = Box::new(FfiControllerRuntime {
+ inner: ptr,
+ drop_fn: Self::drop_controller_runtime,
+ });
- // Convert ControllerData
- let controller_data: Box<ControllerData> = unsafe { Box::from_raw(raw_data as *mut ControllerData) };
+ Box::into_raw(ffi_runtime)
+ }
- // Define custom drop function
- extern "C" fn drop_runtime(raw: *mut c_void) {
+ extern "C" fn drop_controller_runtime(ptr: *mut c_void) {
+ if !ptr.is_null() {
unsafe {
- let arc_ptr = raw as *const Arc<Mutex<ControllerRuntime>>;
- drop(Arc::from_raw(arc_ptr));
+ let _ = Arc::<Mutex<ControllerRuntime>>::from_raw(ptr as *mut _);
}
}
-
- // Convert to an FFI-safe structure
- let arc_raw = Arc::into_raw(controller_data.runtime()) as *mut c_void;
-
- Box::into_raw(Box::new(FfiControllerRuntime {
- inner: arc_raw,
- drop_fn: drop_runtime,
- }))
}
/// Free ControllerData memory
#[unsafe(no_mangle)]
- pub extern "C" fn controller_data_free(controller: *mut FfiControllerData) {
+ pub extern "C" fn free_controller_data(controller: *mut FfiControllerData) {
if controller.is_null() {
return;
}
@@ -103,6 +95,43 @@ impl FfiControllerData {
// ControllerRuntime implementation
impl FfiControllerRuntime {
+ fn operate_controller_runtime(
+ runtime: *mut FfiControllerRuntime,
+ callback: fn(guard: &mut MutexGuard<ControllerRuntime>)
+ ) {
+ unsafe {
+ let ffi_runtime = &*runtime;
+ Arc::increment_strong_count(ffi_runtime.inner);
+ let arc = Arc::<Mutex<ControllerRuntime>>::from_raw(ffi_runtime.inner as *mut _);
+ let arc_clone = Arc::clone(&arc);
+ let _ = Arc::into_raw(arc);
+ entry_mutex!(arc_clone, |guard| {
+ callback(guard);
+ });
+ Arc::decrement_strong_count(ffi_runtime.inner);
+ }
+ }
+
+ fn operate_controller_runtime_with_return<Input, Result>(
+ runtime: *mut FfiControllerRuntime,
+ input: Input,
+ callback: fn(guard: &mut MutexGuard<ControllerRuntime>, input: Input) -> Option<Result>
+ ) -> Option<Result> {
+ unsafe {
+ let ffi_runtime = &*runtime;
+ Arc::increment_strong_count(ffi_runtime.inner);
+ let arc = Arc::<Mutex<ControllerRuntime>>::from_raw(ffi_runtime.inner as *mut _);
+ let arc_clone = Arc::clone(&arc);
+ let _ = Arc::into_raw(arc);
+ let mut result = None;
+ entry_mutex!(arc_clone, |guard| {
+ result = callback(guard, input);
+ });
+ Arc::decrement_strong_count(ffi_runtime.inner);
+ result
+ }
+ }
+
/// Close runtime and exit game
#[unsafe(no_mangle)]
pub extern "C" fn controller_runtime_close(
@@ -112,15 +141,9 @@ impl FfiControllerRuntime {
return;
}
- let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> };
- let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
-
- entry_mutex!(arc_ref, |mutex_guard| {
- mutex_guard.close();
+ Self::operate_controller_runtime(runtime, |guard| {
+ guard.close();
});
-
- // Reconstruct Arc
- let _ = Arc::into_raw(arc_ref);
}
/// Send control message
@@ -133,19 +156,12 @@ impl FfiControllerRuntime {
return;
}
- let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> };
- let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ let msg = unsafe { ControlMessage::from(control_message.read()) };
- let msg = unsafe {
- let boxed_msg = Box::from_raw(control_message);
- ControlMessage::from(*boxed_msg)
- };
-
- entry_mutex!(arc_ref, |mutex_guard| {
- mutex_guard.send_message(msg);
+ Self::operate_controller_runtime_with_return(runtime, msg, |guard, input| {
+ guard.send_message(input);
+ Some(())
});
-
- let _ = Arc::into_raw(arc_ref);
}
/// Send text message
@@ -257,20 +273,19 @@ impl FfiControllerRuntime {
runtime: *mut FfiControllerRuntime
) -> *mut FfiGameMessage {
if runtime.is_null() {
- return std::ptr::null_mut();
+ return null_mut();
}
let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> };
- let arc_ref = unsafe { Arc::from_raw(arc_ptr) };
+ let arc_ref = unsafe { Arc::from_raw(arc_ptr).clone() };
let result = {
- let mut pop_result = None;
-
- entry_mutex!(arc_ref, |mutex_guard| {
- pop_result = mutex_guard.pop();
- });
-
- pop_result
+ Self::operate_controller_runtime_with_return(runtime, (), |guard, _| {
+ match guard.pop() {
+ None => { None }
+ Some(msg) => { Some(msg) }
+ }
+ })
};
// Reconstruct Arc
@@ -281,7 +296,7 @@ impl FfiControllerRuntime {
let ffi_msg = Box::new(FfiGameMessage::from(msg));
Box::into_raw(ffi_msg)
} else {
- std::ptr::null_mut()
+ null_mut()
}
}
diff --git a/core/bindings/lang/clang/src/data/ngpd_game.rs b/core/bindings/lang/clang/src/data/ngpd_game.rs
index 829c5ed..2892ecc 100644
--- a/core/bindings/lang/clang/src/data/ngpd_game.rs
+++ b/core/bindings/lang/clang/src/data/ngpd_game.rs
@@ -8,7 +8,6 @@ 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)]
@@ -72,6 +71,68 @@ impl FfiGameData {
raw
}
+ /// Add info
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_add_info(
+ data: *mut FfiGameData,
+ key: *const c_char,
+ value: *const c_char,
+ ) -> *mut FfiGameData {
+
+ if data.is_null() || key.is_null() || value.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let key_str = unsafe { CStr::from_ptr(key) }.to_string_lossy().into_owned();
+ let value_str = unsafe { CStr::from_ptr(value) }.to_string_lossy().into_owned();
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
+ data_inner.info(key_str, value_str);
+
+ let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _)));
+ raw
+ }
+
+ /// Set name info
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_set_name_info(
+ data: *mut FfiGameData,
+ name: *const c_char,
+ ) -> *mut FfiGameData {
+
+ if data.is_null() || name.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let name_str = unsafe { CStr::from_ptr(name) }.to_string_lossy().into_owned();
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
+ data_inner.name(name_str);
+
+ let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _)));
+ raw
+ }
+
+ /// Set version info
+ #[unsafe(no_mangle)]
+ pub extern "C" fn game_data_set_version_info(
+ data: *mut FfiGameData,
+ version: *const c_char,
+ ) -> *mut FfiGameData {
+
+ if data.is_null() || version.is_null() {
+ return std::ptr::null_mut();
+ }
+
+ let version_str = unsafe { CStr::from_ptr(version) }.to_string_lossy().into_owned();
+
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
+ data_inner.version(version_str);
+
+ let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _)));
+ raw
+ }
+
/// Load data archive
#[unsafe(no_mangle)]
pub extern "C" fn game_data_load_archive(
@@ -104,24 +165,25 @@ impl FfiGameData {
return std::ptr::null_mut();
}
- let data_inner = unsafe { data.read() };
- let raw_data = data_inner.0;
+ let data_inner = unsafe { &mut *((*data).0 as *mut GameData) };
- let game_data: Box<GameData> = unsafe { Box::from_raw(raw_data as *mut GameData) };
+ let arc = data_inner.runtime_with_borrowed_data();
+ let ptr = Arc::into_raw(arc) as *mut c_void;
- extern "C" fn drop_runtime(raw: *mut c_void) {
+ let ffi_runtime = Box::new(FfiGameRuntime {
+ inner: ptr,
+ drop_fn: Self::drop_game_runtime,
+ });
+
+ Box::into_raw(ffi_runtime)
+ }
+
+ extern "C" fn drop_game_runtime(ptr: *mut c_void) {
+ if !ptr.is_null() {
unsafe {
- let arc_ptr = raw as *const Arc<Mutex<GameRuntime>>;
- drop(Arc::from_raw(arc_ptr));
+ let _ = Arc::<Mutex<GameRuntime>>::from_raw(ptr as *mut _);
}
}
-
- let arc_raw = Arc::into_raw(game_data.runtime()) as *mut c_void;
-
- Box::into_raw(Box::new(FfiGameRuntime {
- inner: arc_raw,
- drop_fn: drop_runtime,
- }))
}
/// Free data
@@ -183,34 +245,62 @@ impl FfiGameRuntimeArchive {
impl FfiGameRuntime {
+ fn operate_game_runtime(
+ runtime: *mut FfiGameRuntime,
+ callback: fn(guard: &mut MutexGuard<GameRuntime>)
+ ) {
+ unsafe {
+ let ffi_runtime = &*runtime;
+ Arc::increment_strong_count(ffi_runtime.inner);
+ let arc = Arc::<Mutex<GameRuntime>>::from_raw(ffi_runtime.inner as *mut _);
+ let arc_clone = Arc::clone(&arc);
+ let _ = Arc::into_raw(arc);
+ entry_mutex!(arc_clone, |guard| {
+ callback(guard);
+ });
+ Arc::decrement_strong_count(ffi_runtime.inner);
+ }
+ }
+
+ fn operate_game_runtime_with_return<Input, Result>(
+ runtime: *mut FfiGameRuntime,
+ input: Input,
+ callback: fn(guard: &mut MutexGuard<GameRuntime>, input: Input) -> Option<Result>
+ ) -> Option<Result> {
+ unsafe {
+ let ffi_runtime = &*runtime;
+ Arc::increment_strong_count(ffi_runtime.inner);
+ let arc = Arc::<Mutex<GameRuntime>>::from_raw(ffi_runtime.inner as *mut _);
+ let arc_clone = Arc::clone(&arc);
+ let _ = Arc::into_raw(arc);
+ let mut result = None;
+ entry_mutex!(arc_clone, |guard| {
+ result = callback(guard, input);
+ });
+ Arc::decrement_strong_count(ffi_runtime.inner);
+ result
+ }
+ }
+
fn send_message_to(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType,
+ service_type: 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) };
+ let service = ServiceType::from(&service_type);
- entry_mutex!(arc_ref, |mutex_guard| {
- do_on(mutex_guard);
+ Self::operate_game_runtime_with_return(
+ runtime,
+ (&player.account, message, service),
+ |guard, (account, message, service)| {
+ guard.send_game_message(account, message, service);
+ Some(())
});
}
@@ -220,7 +310,7 @@ impl FfiGameRuntime {
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
message: *mut FfiGameMessage,
- service_type: *mut FfiServiceType
+ service_type: FfiServiceType
) {
if message.is_null() { return; }
let msg = unsafe { GameMessage::from(message.read()) };
@@ -232,7 +322,7 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_send_text_message(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType,
+ service_type: FfiServiceType,
text: *const c_char
) {
let text_str = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned().to_string();
@@ -244,7 +334,7 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_send_event(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType,
+ service_type: FfiServiceType,
key: u8
) {
Self::send_message_to(runtime, player, service_type, GameMessage::EventTrigger(key));
@@ -254,12 +344,13 @@ impl FfiGameRuntime {
#[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();
- });
+
+ let control_event = Self::operate_game_runtime_with_return(
+ runtime,
+ (), |guard, _| {
+ guard.pop_control_event()
+ });
+
match control_event {
None => { std::ptr::null_mut() }
Some((account, message)) => {
@@ -276,13 +367,21 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_let_exit(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType,
- reason: *mut FfiExitReason
+ service_type: FfiServiceType,
+ reason: 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);
+ 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();
+
+ Self::operate_game_runtime_with_return(
+ runtime, (&player.account, ExitReason::from(&reason), ServiceType::from(&service_type)),
+ |guard, (account, reason, service)| {
+ guard.let_account_exit(account, reason, service);
+ Some(())
+ }
+ );
}
/// Kick a player
@@ -290,20 +389,20 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_kick_player(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType
+ service_type: FfiServiceType
) {
- if runtime.is_null() || player.is_null() || service_type.is_null() { return; }
+ 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();
- 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);
- });
+ Self::operate_game_runtime_with_return(
+ runtime, (&player, ServiceType::from(&service_type)),
+ |guard, (player, service)| {
+ guard.kick_player(player, service);
+ Some(())
+ }
+ );
}
/// Ban a player (And kick)
@@ -311,20 +410,20 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_ban_player(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer,
- service_type: *mut FfiServiceType
+ service_type: FfiServiceType
) {
- if runtime.is_null() || player.is_null() || service_type.is_null() { return; }
+ 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();
- 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);
- });
+ Self::operate_game_runtime_with_return(
+ runtime, (&player, ServiceType::from(&service_type)),
+ |guard, (player, service)| {
+ guard.ban_player(player, service);
+ Some(())
+ }
+ );
}
/// Pardon a player
@@ -338,19 +437,20 @@ impl FfiGameRuntime {
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);
- });
+ Self::operate_game_runtime_with_return(
+ runtime, &player,
+ |guard, player| {
+ guard.pardon_player(player);
+ Some(())
+ }
+ );
}
/// 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| {
+ Self::operate_game_runtime(runtime, |guard| {
guard.close_game();
})
}
@@ -359,7 +459,7 @@ impl FfiGameRuntime {
#[unsafe(no_mangle)]
pub extern "C" fn game_runtime_lock(runtime: *mut FfiGameRuntime) {
if runtime.is_null() { return; }
- Self::do_on_rt(runtime, |guard| {
+ Self::operate_game_runtime(runtime, |guard| {
guard.lock_game();
})
}
@@ -368,7 +468,7 @@ impl FfiGameRuntime {
#[unsafe(no_mangle)]
pub extern "C" fn game_runtime_unlock(runtime: *mut FfiGameRuntime) {
if runtime.is_null() { return; }
- Self::do_on_rt(runtime, |guard| {
+ Self::operate_game_runtime(runtime, |guard| {
guard.unlock_game();
})
}
@@ -377,15 +477,12 @@ impl FfiGameRuntime {
#[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();
+ let result = Self::operate_game_runtime_with_return(
+ runtime, (),
+ |guard, _| {
+ Some(guard.is_game_locked())
});
-
- locked
+ result.unwrap_or(false)
}
/// Get button status of player
@@ -400,12 +497,11 @@ impl FfiGameRuntime {
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);
- });
+ let status = Self::operate_game_runtime_with_return(
+ runtime, (account, key), |guard, (account, key)| {
+ guard.control.get_button_status(&account, &key)
+ }
+ );
match status {
None => { FfiButtonStatus { found: false, pressed: false, released: false } }
@@ -427,12 +523,11 @@ impl FfiGameRuntime {
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);
- });
+ let status = Self::operate_game_runtime_with_return(
+ runtime, (account, key), |guard, (account, key)| {
+ guard.control.get_axis(&account, &key)
+ }
+ );
match status {
None => { FfiAxis { found: false, axis: 0.0 } }
@@ -454,12 +549,11 @@ impl FfiGameRuntime {
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);
- });
+ let status = Self::operate_game_runtime_with_return(
+ runtime, (account, key), |guard, (account, key)| {
+ guard.control.get_direction(&account, &key)
+ }
+ );
match status {
None => { FfiDirection { found: false, x: 0.0, y: 0.0 } }
@@ -474,23 +568,22 @@ impl FfiGameRuntime {
pub extern "C" fn game_runtime_get_service_type(
runtime: *mut FfiGameRuntime,
player: *const FfiPlayer
- ) -> *const FfiServiceType {
+ ) -> 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);
- });
+ let service_type = Self::operate_game_runtime_with_return(
+ runtime, account, |guard, account| {
+ guard.data.get_service_type(&account)
+ }
+ );
match service_type {
- None => { null() }
+ None => { FfiServiceType::BlueTooth }
Some(r) => {
- Box::into_raw(Box::new(FfiServiceType::from(&r)))
+ FfiServiceType::from(&r)
}
}
}
@@ -506,12 +599,11 @@ impl FfiGameRuntime {
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));
- });
+ let banned = Self::operate_game_runtime_with_return(
+ runtime, account, |guard, account| {
+ Some(guard.data.is_account_banned(&account))
+ }
+ );
match banned {
None => { FfiBooleanResult { found: false, result: false } }
@@ -532,12 +624,11 @@ impl FfiGameRuntime {
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));
- });
+ let online = Self::operate_game_runtime_with_return(
+ runtime, account, |guard, account| {
+ Some(guard.data.is_account_online(&account))
+ }
+ );
match online {
None => { FfiBooleanResult { found: false, result: false } }
@@ -551,12 +642,11 @@ impl FfiGameRuntime {
#[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 online_list = Self::operate_game_runtime_with_return(
+ runtime, (), |guard, _| {
+ Some(guard.data.online_accounts())
+ }
+ );
let mut result : Vec<FfiPlayer> = vec![];
if online_list.is_some() {
@@ -579,12 +669,11 @@ impl FfiGameRuntime {
#[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 banned_list = Self::operate_game_runtime_with_return(
+ runtime, (), |guard, _| {
+ Some(guard.data.banned_accounts())
+ }
+ );
let mut result : Vec<FfiPlayer> = vec![];
if banned_list.is_none() {
diff --git a/core/bindings/lang/clang/src/lib.rs b/core/bindings/lang/clang/src/lib.rs
index f939758..08da79e 100644
--- a/core/bindings/lang/clang/src/lib.rs
+++ b/core/bindings/lang/clang/src/lib.rs
@@ -1,3 +1,4 @@
pub mod converter;
pub mod data;
pub mod service;
+pub mod logger_utils;
diff --git a/core/bindings/lang/clang/src/logger_utils.rs b/core/bindings/lang/clang/src/logger_utils.rs
new file mode 100644
index 0000000..96bd0dc
--- /dev/null
+++ b/core/bindings/lang/clang/src/logger_utils.rs
@@ -0,0 +1,13 @@
+use nogamepads::logger_utils::logger_build;
+
+#[unsafe(no_mangle)]
+pub extern "C" fn enable_logger(level: u8) {
+ let level_filter = match level {
+ 0 => log::LevelFilter::Info,
+ 1 => log::LevelFilter::Debug,
+ 2 => log::LevelFilter::Trace,
+ _ => { log::LevelFilter::Info }
+ };
+
+ logger_build(level_filter);
+} \ 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
index 8701284..a11c2f1 100644
--- a/core/bindings/lang/clang/src/service/ngpd_service_types.rs
+++ b/core/bindings/lang/clang/src/service/ngpd_service_types.rs
@@ -2,6 +2,7 @@ use nogamepads_core::service::service_types::ServiceType;
#[repr(C)]
pub enum FfiServiceType {
+ Unknown,
TCPConnection,
BlueTooth,
USB,
@@ -23,6 +24,9 @@ impl From<&FfiServiceType> for ServiceType {
FfiServiceType::TCPConnection => { ServiceType::TCPConnection }
FfiServiceType::BlueTooth => { ServiceType::BlueTooth }
FfiServiceType::USB => { ServiceType::USB }
+ _ => {
+ ServiceType::default()
+ }
}
}
}
diff --git a/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs b/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs
index 2c8995c..6e706b5 100644
--- a/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs
+++ b/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs
@@ -1,13 +1,14 @@
use crate::data::ngpd_controller::FfiControllerRuntime;
use crate::data::ngpd_game::FfiGameRuntime;
-use nogamepads_core::data::controller::controller_runtime::ControllerRuntime;
-use nogamepads_core::data::game::game_runtime::GameRuntime;
use nogamepads_core::service::tcp_network::pad_client::pad_client_service::PadClientNetwork;
use nogamepads_core::service::tcp_network::pad_server::pad_server_service::PadServerNetwork;
+use nogamepads_core::service::tcp_network::utils::tokio_utils::build_tokio_runtime;
use std::ffi::{c_char, c_void, CStr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
+use std::ptr::null_mut;
use std::sync::{Arc, Mutex};
-use nogamepads_core::service::tcp_network::utils::tokio_utils::build_tokio_runtime;
+use nogamepads_core::data::controller::controller_runtime::ControllerRuntime;
+use nogamepads_core::data::game::game_runtime::GameRuntime;
#[repr(C)]
pub struct FfiTcpClientService(*mut c_void);
@@ -24,16 +25,22 @@ impl FfiTcpClientService {
) -> *mut FfiTcpClientService {
if runtime.is_null() {
- return std::ptr::null_mut();
+ return null_mut();
}
- let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> };
- let arc_ref = unsafe { Arc::clone(&*arc_ptr) };
+ let runtime_ref = unsafe { &*runtime };
+ let data_ptr = runtime_ref.inner as *const Mutex<ControllerRuntime>;
+
+ let arc = unsafe {
+ let atomic_arc = Arc::from_raw(data_ptr);
+ Arc::clone(&atomic_arc)
+ };
- let service = PadClientNetwork::build(Arc::clone(&arc_ref));
- let raw = Box::into_raw(Box::new(FfiTcpClientService(Box::into_raw(Box::new(service)) as *mut _)));
+ let client = PadClientNetwork::build(arc.clone());
- raw
+ let client_box = Box::new(client);
+ let service = FfiTcpClientService(Box::into_raw(client_box) as *mut _);
+ Box::into_raw(Box::new(service))
}
/// Bind ipv4 address
@@ -160,12 +167,17 @@ impl FfiTcpClientService {
pub extern "C" fn free_tcp_client(
service: *mut FfiTcpClientService
) {
- if service.is_null() { return; }
+ if service.is_null() {
+ return;
+ }
- let service_ptr = service as *mut PadClientNetwork;
+ let wrapper = unsafe { Box::from_raw(service) };
+ let client_ptr = wrapper.0;
unsafe {
- let _ = Box::from_raw(service_ptr);
+ if !client_ptr.is_null() {
+ let _ = Box::from_raw(client_ptr as *mut PadClientNetwork);
+ }
}
}
}
@@ -178,15 +190,23 @@ impl FfiTcpServerService {
runtime: *mut FfiGameRuntime,
) -> *mut FfiTcpServerService {
- if runtime.is_null() { return std::ptr::null_mut(); }
+ if runtime.is_null() {
+ return null_mut();
+ }
+
+ let runtime_ref = unsafe { &*runtime };
+ let data_ptr = runtime_ref.inner as *const Mutex<GameRuntime>;
- let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> };
- let arc_ref = unsafe { Arc::clone(&*arc_ptr) };
+ let arc = unsafe {
+ let atomic_arc = Arc::from_raw(data_ptr);
+ Arc::clone(&atomic_arc)
+ };
- let service = PadServerNetwork::build(Arc::clone(&arc_ref));
- let raw = Box::into_raw(Box::new(FfiTcpServerService(Box::into_raw(Box::new(service)) as *mut _)));
+ let server = PadServerNetwork::build(arc.clone());
- raw
+ let server_box = Box::new(server);
+ let service = FfiTcpServerService(Box::into_raw(server_box) as *mut _);
+ Box::into_raw(Box::new(service))
}
/// Bind ipv4 address
@@ -305,12 +325,14 @@ impl FfiTcpServerService {
pub extern "C" fn free_tcp_server(
service: *mut FfiTcpServerService
) {
- if service.is_null() { return; }
-
- let service_ptr = service as *mut PadServerNetwork;
+ if !service.is_null() {
+ unsafe {
+ let service = Box::from_raw(service);
- unsafe {
- let _ = Box::from_raw(service_ptr);
+ if !service.0.is_null() {
+ Arc::from_raw(service.0 as *mut _);
+ }
+ }
}
}
} \ No newline at end of file