# Security SDK 使用說明文件
## 目錄
- [SDK 簡介](#SDK-簡介)
- [功能模組使用方式](#功能模組使用方式)
- [建立 SDK 實例](#建立-SDK-實例)
- [裝置資訊](#裝置資訊)
- [模擬器辨識](#模擬器辨識)
- [IMU追蹤](#IMU追蹤)
- [觸控資料](#觸控資料)
- [Callback 機制說明](#Callback-機制說明)
- [附錄](#附錄)
<br/>
## SDK 簡介
Security SDK 提供跨平台的感測器資料收集功能,主要應用於裝置行為識別與異常使用者偵測。SDK 採模組化設計,支援透過 Lua 或 C++ 調用,回傳資料為 C++ 結構(struct)格式。
目前支援 Android 平台,包含以下三大功能模組:
- **裝置資訊收集**:回傳設備的硬體、系統與網路特徵(如 model、CPU Info、RAM、fingerprint 等)。
- **IMU 追蹤(Inertial Measurement Unit)**:包含陀螺儀(Gyroscope)與加速度計,可追蹤角速度、角度變化與加速度。
- **觸控資料紀錄**:定時收集點擊座標與時間戳,用於分析使用者的操作樣態。
> 下圖為 SDK 整體模組架構:

<br/>
## 功能模組使用方式
> 平台實作都在預編好的 `libsecuritysdk.so`。
使用者只需要 include 下列檔案,以及加入 SecuritySDK.cpp 即可,其他實作都已經編入 .so。
#### SDK介面檔案:
- `ISecuritySDK.h`:定義功能操作的純虛擬介面
- `SecuritySDKTypes.h`:定義共用資料結構
- `SecuritySDK.h`:統一入口,負責實例建立與平台綁定
- `SecuritySDK.cpp`:因為內含 `cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(...)`,避免把 cocos2d 拉進 .so 而使體積暴增,所以放在外面。
#### SDK平台檔案
- `SecuritySDKImplAndroid.h`
- `SecuritySDKImplIOS.h`
#### 模組功能檔案
- `DeviceInfo/DeviceInfo.h`
- `Emulator/EmulatorDetector.h`
- `Emulator/IEmulatorDetectionCondition.h`
- `Emulator/JsonEmulatorCondition.h`
- `IMU/IMUData.h`
- `IMU/IMUSensor.h`
- `TouchEvent/TouchEventCollector.h`
- `TouchEvent/TouchPointData.h`
### 建立 SDK 實例
請於初始化階段建立並註冊 `SecuritySDK` 實例,建議如下使用:
#### C++
```cpp
#include "securitysdk/SecuritySDK.h"
auto securitySDK = SecuritySDK::getInstance();
securitySDK->RegisterSecuritySDK();
// 使用方法:檢測模擬器
securitysdk::DeviceInfo info = securitySDK->getDeviceInfo();
```
#### Lua
在C++使用`RegisterLua(lua_State* L);` 註冊 Lua 綁定類別與方法
```cpp
SecuritySDK::getInstance()->RegisterLua(L);
```
Lua 端初始化與使用
```lua
-- 獲得 C++ 層單例
self.sdk = Inanna.GetSecuritySDK()
-- 初始化平台原生實作(Android / iOS)
self.sdk:RegisterSecuritySDK()
-- 獲得DeviceInfo
local info = self.sdk:getDeviceInfo()
```
所有功能請以 `securitySDK` 作為入口。`RegisterSecuritySDK()` 會根據平台自動建立對應的實作類別
<br/>
### 裝置資訊
可使用下列方法獲取裝置資訊:
```cpp
DeviceInfo info = securitySDK->getDeviceInfo();
```
#### DeviceInfo回傳結構:
```cpp
struct DeviceInfo {
std::string ID;
std::string model;
std::string osVersion;
std::string cpuInfo;
std::string fingerprint;
std::string localIpAddress;
std::string networkType;
std::string macAddress;
std::string kernelABIInfo;
int totalMemoryMb;
int availableMemoryMb;
std::string buildInfo;
int screenWidth;
int screenHeight;
};
```
#### DeviceInfo結構說明:
| 欄位名稱 | 型別 | 說明 |
| ------------------- | ------------- | ---------------------- |
| `ID` | `std::string` | 裝置唯一識別碼(如 Android ID) |
| `model` | `std::string` | 裝置型號 |
| `osVersion` | `std::string` | 作業系統版本 |
| `cpuInfo` | `std::string` | CPU 架構與型號 |
| `fingerprint` | `std::string` | 系統建置指紋 |
| `localIpAddress` | `std::string` | 裝置的內網 IP 位址 |
| `networkType` | `std::string` | 網路類型(如 Wi-Fi、LTE) |
| `macAddress` | `std::string` | 裝置 MAC 位址 |
| `kernelABIInfo` | `std::string` | 核心 ABI 描述(如 arm64-v8a) |
| `totalMemoryMb` | `int` | 總記憶體(MB) |
| `availableMemoryMb` | `int` | 可用記憶體(MB) |
| `buildInfo` | `std::string` | 系統 build 資訊 |
| `screenWidth` | `int` | 螢幕寬度(像素,橫向解析度) |
| `screenHeight` | `int` | 螢幕高度(像素,縱向解析度) |
---
<br/>
### 模擬器辨識
模擬器偵測邏輯使用 JsonEmulatorCondition 實作,支援多層邏輯巢狀與字串比對操作,條件配置格式如下:

#### Function 說明
- `setEmulatorDetectionCondition(const std::string& jsonConfig)`
- **參數:**
- `jsonConfig`:JSON 設定字串(而非檔案路徑)
- **功能:** 載入指定的模擬器判斷條件(JSON 格式字串),供後續判斷使用。
- **回傳值:** `bool` — 成功載入為 `true`,載入失敗為 `false`
- `reloadEmulatorDetectionCondition()` ⚠️ **已棄用**
- **功能:** 重新載入上次設定的 JSON 條件內容(已棄用,不建議使用)。
- **回傳值:** `bool` — 目前固定回傳 `false`
- `getEmulatorDetectionDescription()`
- **功能:** 回傳目前載入的條件來源描述。
- **回傳值:** `std::string` — 條件說明文字
- `isEmulator()`
- **功能:** 執行模擬器判斷,根據目前條件返回結果。若未設定條件,預設為 false。
- **回傳值:** `bool` — 為模擬器則回傳 `true`,否則回傳 `false`
- `getTriggerRules()`
- **功能**: 回傳觸發目前判定為模擬器的條件規則
- **回傳值**: `std::vector<TriggeredRule>` - 字串描述被觸發的規則
#### 資料結構說明
TriggeredRule
| 欄位名稱 | 型別 | 說明 |
|----------------|----------------|------------------------------|
| `field` | `std::string` | 檢測欄位名稱 |
| `operation` | `std::string` | 邏輯運算類型 |
| `actualValue` | `std::string` | 實際值 |
| `expectedValue` | `std::string` | 期望值 |
| `description` | `std::string` | 規則描述 |
#### 使用方法
1. **準備 JSON 配置字串**:將模擬器檢測的 JSON 配置準備為字串格式
2. **呼叫 `setEmulatorDetectionCondition(jsonConfig)`** 設定條件(傳入 JSON 字串而非檔案路徑)
3. **呼叫 `isEmulator()`** 檢查是否為模擬器
詳見附錄提供在 `AppDelegate.cpp` 中初始化 `SecuritySDK` 和調用 `JsonEmulator` 的完整範例
#### 支援操作 (Operation)
| 操作名稱 | 說明 |
| ----------------------- | ------------ |
| `equals` | 精確匹配 |
| `contains` | 包含字串 |
| `starts_with` | 前綴比對 |
| `ends_with` | 後綴比對 |
| `regex` | 通配符比對(\*, ?) |
| `less_than` | 小於 |
| `greater_than` | 大於 |
| `less_than_or_equal` | 小於等於 |
| `greater_than_or_equal` | 大於等於 |
#### 詳細模擬器檢測文件
- [模擬器檢測系統使用說明](https://hackmd.io/ppgD4A8_SeGneP9uSo9YvQ)
- [JSON 模擬器檢測條件系統](https://hackmd.io/4A9gr2pqS-m1sJliby8nMA?view)
---
<br/>
### 觸控資料
#### Function 說明
- `startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, float intervalMs = 0.1f)`
- **參數:**
- `cb`:Lua callback 函式,會在指定時間結束時觸發
- `durationSeconds`:資料收集持續的時間(秒)
- `intervalMs`:間隔秒數(毫秒)
- **功能:** 啟動觸控資料收集,期間內會記錄所有點擊座標與時間。
- **回傳值:** `void`
- `stopDetectTouch(const luabridge::LuaRef cb)`
- **參數:**
- `cb`:Lua callback 函式,會在停止後立即觸發
- **功能:** 中止正在進行中的觸控資料收集流程。
- **回傳值:** `void`
- `exportTouchData()`
- **參數:** 無
- **功能:** 將目前已收集到的觸控點資料導出為列表。
- **回傳值:** `std::vector<TouchExportData>` — 一組觸控點資料
#### 資料結構說明
TouchExportData
| 欄位名稱 | 型別 | 說明 |
|----------------|----------------|------------------------------|
| `x` | `float` | 點擊座標 X |
| `y` | `float` | 點擊座標 Y |
| `timestamp` | `uint64_t` | 點擊時間 |
| `hasRapidClicks` | `bool` | 是否快速點擊 |
| `hasIntegerCoordinates` | `bool` | 是否點在整數座標 |
> 每筆點擊紀錄代表一次觸控事件(如點擊螢幕)。
#### 使用順序建議:
1. **開始收集觸控資料**
呼叫 `startDetectTouch(callback, durationSeconds)` 啟動收集。SDK 將於背景中記錄每次點擊的 `(x, y)` 與對應時間戳。
2. **等待結束通知(或手動停止)**
當收集時間結束,或你主動呼叫 `stopDetectTouch(callback)` 時,SDK 將觸發 callback 通知資料已蒐集完成。
3. **導出觸控資料**
在 callback 觸發後立即呼叫 `exportTouchData()`,即可取得已收集的 `TouchExportData` 列表,包含所有點擊事件。
---
<br/>
### IMU追蹤
#### Function 說明
- `startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalMs = 100.0f)`
- **參數:**
- `cb`:Lua callback 函式,會在追蹤時間結束時觸發
- `durationSeconds`:資料收集持續的時間(秒)
- `sampleIntervalMs`:取樣區間(豪秒)
- **功能:** 啟動 IMU 資料收集,並在指定時間結束時觸發 callback。
- **回傳值:** `void`
- `stopIMUTracking(const luabridge::LuaRef cb)`
- **參數:**
- `cb`:Lua callback 函式,會在停止後立即觸發
- **功能:** 中止正在進行中的 IMU 收集流程。
- **回傳值:** `void`
- `exportIMUData()`
- **參數:** 無
- **功能:** 將當前緩衝區中的 IMU 資料導出為列表
- **回傳值:** `std::vector<GyroExportData>` — 一組已收集的 IMU 資料點
---
#### 資料結構說明
IMUExportData
| 欄位名稱 | 型別 | 說明 |
| ----------------------- | ---------- | --------------------- |
| `timestamp` | `uint64_t` | 資料結束時的時間戳(單位:ns) |
| `interval` | `float` | 此筆資料涵蓋的時間區段(秒) |
| `deltaAngles[3]` | `std::array<float, 3>` | X, Y, Z 軸的角度總變化量 |
| `avgAngularVelocity[3]` | `std::array<float, 3>` | X, Y, Z 軸的平均角速度 |
| `avgAccelVelocity[3]` | `std::array<float, 3>` | X, Y, Z 軸的平均加速度(保留欄位) |
| `sampleCount` | `size_t` | 該筆統計所使用的樣本數 |
#### 使用順序建議:
1. **開始收集 IMU 資料**
呼叫 `startIMUTracking(callback, durationSeconds)` 啟動收集。SDK 將每 10ms 取樣一次角速度,並計算累積角度與統計值。
2. **等待結束通知(或手動停止)**
當收集時間結束(或你主動呼叫 `stopIMUTracking(callback)` 時),SDK 將觸發 callback 通知資料已準備完成。
3. **導出資料**
在 callback 觸發後呼叫 `exportIMUData()`,可取得一組 `IMUExportData` 統計結果,包含時間戳、平均角速度與樣本數等。
<br/>
<br/>
## Callback 機制說明
本 SDK 所有支援 callback 的資料收集 API,皆要求傳入合法的 Lua function 作為 callback。
若未傳入合法函式(`luabridge::LuaRef`),對應的主功能(例如開始或停止收集)將不會執行。
---
### 支援 callback 的 API 一覽
| 函式名稱 | 觸發時機 |
|------------------------------|------------------|
| `startIMUTracking(const luabridge::LuaRef cb, float durationSeconds)` | 時間結束後觸發 |
| `stopIMUTracking(const luabridge::LuaRef cb)` | 停止後立即觸發 |
| `startDetectTouch(const luabridge::LuaRef cb, float durationSeconds)` | 時間結束後觸發 |
| `stopDetectTouch(const luabridge::LuaRef cb)` | 停止後立即觸發 |
---
### 行為說明
- 所有 callback 使用 `luabridge::LuaRef` 傳入,必須為有效的 Lua function。
- 若未傳入合法 callback,SDK 會記錄錯誤並**跳過主功能執行**。
- 所有 callback 都會被 `try-catch` 包裝,避免 Lua/C++ 層錯誤導致崩潰。
---
### 使用範例(Lua)
```lua
local function handleGyroDetectionComplete()
print("陀螺儀偵測完成!時間到了")
end
SecuritySDK.startGyroTracking(handleGyroDetectionComplete, 10)
```
<br/>
<br/>
## 附錄:
### 公開 Interface 定義(ISecuritySDK.h)
```cpp
#ifndef ISECURITYSDK_H
#define ISECURITYSDK_H
#include "SecuritySDKTypes.h"
#include <memory>
#include <string>
#if defined(ANDROID)
#include <jni.h>
#endif
namespace luabridge {
class LuaRef;
}
namespace securitysdk{
struct ISecuritySDK {
virtual ~ISecuritySDK() {};
virtual DeviceInfo getDeviceInfo(std::string *outStringFormat = nullptr) = 0;
virtual void startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalSecond = 0.1f) = 0;
virtual void stopIMUTracking(const luabridge::LuaRef cb) = 0;
virtual std::vector<IMUExportData> exportIMUData() = 0;
virtual void startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, uint64_t intervalMs = 100) = 0;
virtual void stopDetectTouch(const luabridge::LuaRef cb) = 0;
virtual std::vector<TouchExportData> exportTouchData() = 0;
//--------------------------------
// EmulatorDetection
//--------------------------------
// 設定EmulatorDetection, 如果jsonConfig為空,則使用預設的模擬器檢測配置
virtual bool setEmulatorDetectionCondition(const std::string& jsonConfig = "") = 0;
// 重啟EmulatorDetection(deprecated)
virtual bool reloadEmulatorDetectionCondition() = 0;
// 取得EmulatorDetection的描述
virtual std::string getEmulatorDetectionDescription() = 0;
// 取得EmulatorDetection的觸發規則
virtual std::vector<TriggeredRule> getTriggeredRules() = 0;
// 清除EmulatorDetection的觸發規則
virtual void clearTriggeredRules() = 0;
// 檢查是否為模擬器
virtual bool isEmulator() = 0;
};
typedef std::shared_ptr<ISecuritySDK> ISecuritySDKPtr;
} // namespace securitysdk
#endif // ISECURITYSDK_H
```
### 公開 struct 定義(SecuritySDK.h)
```cpp
#pragma once
#include <string>
#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
#include "ISecuritySDK.h"
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
#include "SecuritySDKImplAndroid.h"
#elif ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
#include "SecuritySDKImplIOS.h"
#endif
class SecuritySDK
{
public:
static SecuritySDK* getInstance();
SecuritySDK();
virtual ~SecuritySDK();
void RegisterLua(lua_State* L);
void RegisterSecuritySDK();
void UnregisterSecuritySDK();
int m_testInt = 640;
securitysdk::DeviceInfo getDeviceInfo();
void startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalSecond = 0.1f);
void stopIMUTracking(const luabridge::LuaRef cb);
std::vector<securitysdk::IMUExportData> exportIMUData();
void startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, uint64_t intervalMs = 100);
void stopDetectTouch(const luabridge::LuaRef cb);
std::vector<securitysdk::TouchExportData> exportTouchData();
//--------------------------------
// EmulatorDetection
//--------------------------------
// 設定EmulatorDetection, 如果jsonConfigPath為空,則使用預設的模擬器檢測配置
bool setEmulatorDetectionCondition(const std::string& jsonConfig = "");
// 重啟EmulatorDetection,
// 目前JsonEmulatorCondition可以通過setEmulatorDetectionCondition直接修改,如果是有需要動態調整模擬器檢測的可以使用reloadEmulatorDetectionCondition
bool reloadEmulatorDetectionCondition();
// 取得EmulatorDetection的描述
std::string getEmulatorDetectionDescription();
// 取得EmulatorDetection的觸發規則
std::vector<securitysdk::TriggeredRule> getTriggeredRules();
// 清除EmulatorDetection的觸發規則
void clearTriggeredRules();
// 檢查是否為模擬器
bool isEmulator();
void startDetectTouchLua(luabridge::LuaRef cb, luabridge::LuaRef durationRef, luabridge::LuaRef intervalRef);
luabridge::LuaRef exportTouchDataLua(lua_State* L);
void startIMUTrackingLua(luabridge::LuaRef cb, luabridge::LuaRef durationRef, luabridge::LuaRef intervalRef);
luabridge::LuaRef exportIMUDataLua(lua_State* L);
luabridge::LuaRef getTriggeredRulesLua(lua_State* L);
protected:
static SecuritySDK* _instance;
securitysdk::ISecuritySDKPtr m_securitySDKNative;
std::vector<securitysdk::IMUExportData> m_IMUExportData = {};
std::vector<securitysdk::TouchExportData> m_touchExportData = {};
std::vector<securitysdk::TriggeredRule> m_triggeredRules = {};
securitysdk::DeviceInfo m_deviceInfo = {};
};
```
### 公開 struct 定義(SecuritySDKTypes.h)
```cpp
#ifndef SECURITYSDKTYPES_H
#define SECURITYSDKTYPES_H
#include <string>
#include <vector>
#include <cstdint>
#include <array>
namespace securitysdk {
struct DeviceInfo {
std::string ID;
std::string model;
std::string osVersion;
std::string cpuInfo;
std::string fingerprint;
std::string localIpAddress;
std::string networkType;
std::string macAddress;
std::string kernelABIInfo;
int totalMemoryMb;
int availableMemoryMb;
std::string buildInfo;
int screenWidth;
int screenHeight;
// 移除用於模擬器檢測的欄位
};
struct TouchExportData {
float x;
float y;
uint64_t timestamp;
bool hasRapidClicks = false;
bool hasIntegerCoordinates = false;
};
struct IMUExportData {
uint64_t timestamp = 0;
float interval = 0.0f;
std::array<float, 3> deltaAngles{};
std::array<float, 3> avgAngularVelocity{};
std::array<float, 3> avgAccelVelocity{};
size_t sampleCount = 0;
};
struct TriggeredRule {
std::string field; // 檢測欄位
std::string operation; // 操作類型
std::string actualValue; // 實際值
std::string expectedValue; // 期望值
std::string description; // 規則描述
};
} // namespace securitysdk
#endif // SECURITYSDKTYPES_H
```
### 模擬器檢測 JSON 配置範例
#### 預設 Android 配置範例
```json
{
"logic": "OR",
"rules": [
{
"field": "brand",
"operation": "equals",
"values": [
"generic"
],
"caseSensitive": false
},
{
"field": "model",
"operation": "contains",
"values": [
"android sdk",
"sdk",
"emulator",
"generic"
],
"caseSensitive": false
},
{
"field": "product",
"operation": "contains",
"values": [
"sdk",
"emulator",
"generic"
],
"caseSensitive": false
},
{
"field": "device",
"operation": "contains",
"values": [
"generic",
"sdk"
],
"caseSensitive": false
},
{
"field": "hardware",
"operation": "contains",
"values": [
"goldfish",
"ranchu",
"vbox86"
],
"caseSensitive": false
},
{
"field": "board",
"operation": "contains",
"values": [
"goldfish",
"ranchu",
"vbox86"
],
"caseSensitive": false
},
{
"field": "host",
"operation": "contains",
"values": [
"ubuntu"
],
"caseSensitive": false
},
{
"field": "localIpAddress",
"operation": "starts_with",
"values": [
"172."
],
"caseSensitive": false
},
{
"field": "kernelABIInfo",
"operation": "contains",
"values": [
"x86",
"x86_64"
],
"caseSensitive": false
},
{
"field": "totalMemoryMb",
"operation": "less_than",
"values": [
"2048"
],
"caseSensitive": false
}
],
"groups": [
{
"logic": "AND",
"rules": [
{
"field": "brand",
"operation": "equals",
"values": [
"generic"
],
"caseSensitive": false
},
{
"field": "model",
"operation": "starts_with",
"values": [
"android sdk"
],
"caseSensitive": false
}
]
},
{
"logic": "OR",
"rules": [
{
"field": "hardware",
"operation": "regex",
"values": [
"*goldfish*",
"*ranchu*",
"*vbox*"
],
"caseSensitive": false
},
{
"field": "board",
"operation": "regex",
"values": [
"*goldfish*",
"*ranchu*",
"*vbox*"
],
"caseSensitive": false
}
]
}
]
}
```
#### 預設 iOS 配置範例
>[!Warning] 現在規劃
>目前尚無 iOS 模擬器的參考範例,僅先行建立功能,待未來實際捕捉到 iOS 模擬器資料後(階段二),再完善其相關 JSON 文件。
```json
{}
```
### AppDelegate.cpp 參考範例
```cpp
#include "AppDelegate.h"
#include "securitysdk/ISecuritySDK.h"
#include "securitysdk/SecuritySDKFactory.h"
#include "cocos2d.h"
bool AppDelegate::applicationDidFinishLaunching()
{
// === SecuritySDK 模擬器檢測初始化 ===
try {
// 創建 SecuritySDK 實例並設定為全域實例
auto securitySDK = createSecuritySDK();
if (securitySDK) {
// 將實例設定為全域實例,供 Lua 綁定使用
extern ISecuritySDK* g_sdk;
g_sdk = securitySDK;
// 嘗試從多個位置讀取 JSON 配置檔案
std::string jsonConfig = "";
auto fileUtils = cocos2d::FileUtils::getInstance();
std::vector<std::string> configPaths = {
"emulator_detection_config.json",
"res/emulator_detection_config.json",
"src/emulator_detection_config.json",
"assets/emulator_detection_config.json"
};
bool configLoaded = false;
for (const auto& configPath : configPaths) {
std::string fullPath = fileUtils->fullPathForFilename(configPath);
if (fileUtils->isFileExist(fullPath)) {
jsonConfig = fileUtils->getStringFromFile(fullPath);
cocos2d::log("SecuritySDK: JSON 配置檔案讀取成功 - %s", configPath.c_str());
configLoaded = true;
break;
}
}
if (!configLoaded) {
// 使用內建的預設配置
jsonConfig = R"({
"logic": "OR",
"groups": [
{
"logic": "AND",
"rules": [
{
"field": "manufacturer",
"operation": "contains",
"values": ["google", "genymotion", "android_x86"],
"caseSensitive": false
},
{
"field": "model",
"operation": "contains",
"values": ["sdk", "emulator", "google_sdk"],
"caseSensitive": false
}
]
}
]
})";
cocos2d::log("SecuritySDK: 使用內建預設配置");
}
// 設定模擬器檢測配置(使用 JSON 字串)
if (securitySDK->setEmulatorDetectionCondition(jsonConfig)) {
cocos2d::log("SecuritySDK: 模擬器檢測配置載入成功");
// 執行模擬器檢測
bool isEmulator = securitySDK->isEmulator();
cocos2d::log("SecuritySDK: 模擬器檢測結果 - %s", isEmulator ? "檢測到模擬器" : "真實裝置");
// 取得觸發的規則
auto triggeredRules = securitySDK->getTriggeredRules();
if (!triggeredRules.empty()) {
cocos2d::log("SecuritySDK: 觸發的檢測規則:");
for (const auto& rule : triggeredRules) {
cocos2d::log(" - %s %s (實際值: %s, 期望值: %s)",
rule.field.c_str(),
rule.operation.c_str(),
rule.actualValue.c_str(),
rule.expectedValue.c_str());
}
}
} else {
cocos2d::log("SecuritySDK: 模擬器檢測配置載入失敗");
}
} else {
cocos2d::log("SecuritySDK: 創建 SecuritySDK 實例失敗");
}
} catch (const std::exception& e) {
cocos2d::log("SecuritySDK: 初始化異常 - %s", e.what());
}
// === SecuritySDK 初始化完成 ===
// ... 其他初始化程式碼 ...
}
```