1#![allow(non_upper_case_globals)]
12#![allow(non_camel_case_types)]
13#![allow(non_snake_case)]
14#![allow(dead_code)]
15#![allow(clippy::all)]
16
17include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
19
20pub mod init_result {
24 pub const OK: u32 = 0;
26 pub const FAILED_GENERIC: u32 = 1;
28 pub const NO_PLATFORM: u32 = 2;
30 pub const NOT_LAUNCHED_BY_PLATFORM: u32 = 3;
32 pub const PLATFORM_VERSION_MISMATCH: u32 = 4;
34}
35
36pub mod authorize_result {
38 pub const UNKNOWN: u32 = 0;
40 pub const OK: u32 = 1;
42 pub const FAILED: u32 = 2;
44 pub const IN_FLIGHT: u32 = 3;
46}
47
48pub mod event_id {
50 pub const UNKNOWN: u32 = 0;
52 pub const SYSTEM_STATE_CHANGED: u32 = 1;
54 pub const AUTHORIZE_FINISHED: u32 = 2002;
56 pub const GAME_PLAYABLE_STATUS_CHANGED: u32 = 4001;
58 pub const DLC_PLAYABLE_STATUS_CHANGED: u32 = 4002;
60 pub const CLOUD_SAVE_LIST: u32 = 6001;
62 pub const CLOUD_SAVE_CREATE: u32 = 6002;
64 pub const CLOUD_SAVE_UPDATE: u32 = 6003;
66 pub const CLOUD_SAVE_DELETE: u32 = 6004;
68 pub const CLOUD_SAVE_GET_DATA: u32 = 6005;
70 pub const CLOUD_SAVE_GET_COVER: u32 = 6006;
72}
73
74pub mod system_state {
76 pub const UNKNOWN: u32 = 0;
78 pub const PLATFORM_ONLINE: u32 = 1;
80 pub const PLATFORM_OFFLINE: u32 = 2;
82 pub const PLATFORM_SHUTDOWN: u32 = 3;
84}
85
86pub mod error_code {
88 pub const SUCCESS: i64 = 0;
90 pub const UNKNOWN: i64 = 1;
92 pub const UNAUTHORIZED: i64 = 2;
94 pub const METHOD_NOT_ALLOWED: i64 = 3;
96 pub const UNIMPLEMENTED: i64 = 4;
98 pub const INVALID_ARGUMENTS: i64 = 5;
100 pub const FORBIDDEN: i64 = 6;
102 pub const USER_IS_DEACTIVATED: i64 = 7;
104 pub const INTERNAL_SERVER_ERROR: i64 = 8;
106 pub const INTERNAL_SDK_ERROR: i64 = 9;
108 pub const NETWORK_ERROR: i64 = 10;
110
111 pub const CLOUD_SAVE_INVALID_FILE_SIZE: i64 = 400000;
114 pub const CLOUD_SAVE_UPLOAD_RATE_LIMIT: i64 = 400001;
116 pub const CLOUD_SAVE_FILE_NOT_FOUND: i64 = 400002;
118 pub const CLOUD_SAVE_FILE_COUNT_LIMIT_PER_CLIENT: i64 = 400003;
120 pub const CLOUD_SAVE_STORAGE_SIZE_LIMIT_PER_CLIENT: i64 = 400004;
122 pub const CLOUD_SAVE_TOTAL_STORAGE_SIZE_LIMIT: i64 = 400005;
124 pub const CLOUD_SAVE_TIMEOUT: i64 = 400006;
126 pub const CLOUD_SAVE_CONCURRENT_CALL_DISALLOWED: i64 = 400007;
128 pub const CLOUD_SAVE_STORAGE_SERVER_ERROR: i64 = 400008;
130 pub const CLOUD_SAVE_INVALID_NAME: i64 = 400009;
132}
133
134pub mod cloudsave_result {
136 pub const OK: u32 = 0;
138 pub const UNINITIALIZED: u32 = 1;
140 pub const NO_TAPTAP_CLIENT: u32 = 2;
142 pub const TAPTAP_CLIENT_OUTDATED: u32 = 3;
144 pub const INVALID_ARGUMENT: u32 = 4;
146 pub const SDK_FAILED: u32 = 5;
148 pub const FAILED_TO_READ_SAVE_FILE: u32 = 6;
150 pub const SAVE_FILE_TOO_LARGE: u32 = 7;
152 pub const FAILED_TO_READ_COVER_FILE: u32 = 8;
154 pub const COVER_FILE_TOO_LARGE: u32 = 9;
156}
157
158#[inline]
160pub fn is_platform_supported() -> bool {
161 cfg!(target_os = "windows")
162}
163
164#[inline]
166pub fn unsupported_platform_error() -> &'static str {
167 "TapTap PC SDK is only supported on Windows. This platform (macOS/Linux) is not supported."
168}
169
170#[cfg(all(test, target_os = "windows"))]
171mod tests {
172 use super::*;
173 use std::ffi::CString;
174
175 #[test]
176 fn test_constants() {
177 assert_eq!(init_result::OK, 0);
179 assert_eq!(init_result::NO_PLATFORM, 2);
180 assert_eq!(event_id::AUTHORIZE_FINISHED, 2002);
181 assert_eq!(error_code::SUCCESS, 0);
182 assert_eq!(cloudsave_result::OK, 0);
183 }
184
185 #[test]
186 fn test_dll_loads_and_functions_exist() {
187 let client_id = CString::new("test_client_id").unwrap();
192 let result = unsafe { TapSDK_RestartAppIfNecessary(client_id.as_ptr()) };
193 assert!(
195 !result,
196 "RestartAppIfNecessary should return false when not in TapTap"
197 );
198 }
199
200 #[test]
201 fn test_sdk_init_without_taptap() {
202 let pub_key = CString::new("test_public_key").unwrap();
204 let mut err_msg: [std::os::raw::c_char; 1024] = [0; 1024];
205
206 let result = unsafe { TapSDK_Init(err_msg.as_mut_ptr() as *mut _, pub_key.as_ptr()) };
207
208 assert!(
210 result == init_result::NO_PLATFORM || result == init_result::NOT_LAUNCHED_BY_PLATFORM,
211 "SDK init should fail with NoPlatform or NotLaunchedByPlatform, got: {}",
212 result
213 );
214 }
215
216 #[test]
217 fn test_ownership_check_without_init() {
218 let owned = unsafe { TapApps_IsOwned() };
220 assert!(!owned, "IsOwned should return false when SDK not initialized");
221 }
222
223 #[test]
224 fn test_get_client_id_without_init() {
225 let mut buffer: [std::os::raw::c_char; 256] = [0; 256];
227 let result = unsafe { TapSDK_GetClientID(buffer.as_mut_ptr()) };
228 assert!(
229 !result,
230 "GetClientID should return false when SDK not initialized"
231 );
232 }
233
234 #[test]
235 fn test_get_open_id_without_init() {
236 let mut buffer: [std::os::raw::c_char; 256] = [0; 256];
238 let result = unsafe { TapUser_GetOpenID(buffer.as_mut_ptr()) };
239 assert!(
240 !result,
241 "GetOpenID should return false when SDK not initialized"
242 );
243 }
244
245 #[test]
246 fn test_dlc_check_without_init() {
247 let dlc_id = CString::new("test_dlc").unwrap();
249 let owned = unsafe { TapDLC_IsOwned(dlc_id.as_ptr()) };
250 assert!(
251 !owned,
252 "IsDlcOwned should return false when SDK not initialized"
253 );
254 }
255
256 #[test]
257 fn test_run_callbacks_without_init() {
258 unsafe { TapSDK_RunCallbacks() };
261 }
262
263 #[test]
264 fn test_struct_sizes() {
265 assert!(
267 std::mem::size_of::<TapSDK_Error>() >= 16,
268 "TapSDK_Error should be at least 16 bytes"
269 );
270 assert!(
271 std::mem::size_of::<AuthorizeFinishedResponse>() > 0,
272 "AuthorizeFinishedResponse should have size"
273 );
274 assert!(
275 std::mem::size_of::<TapCloudSaveInfo>() > 0,
276 "TapCloudSaveInfo should have size"
277 );
278 }
279
280 #[test]
281 fn test_cloudsave_without_init() {
282 let handle = unsafe { TapCloudSave() };
284
285 if !handle.is_null() {
286 let result = unsafe { TapCloudSave_AsyncList(handle, 1) };
287 assert!(
289 result == cloudsave_result::UNINITIALIZED
290 || result == cloudsave_result::SDK_FAILED
291 || result == cloudsave_result::NO_TAPTAP_CLIENT,
292 "CloudSave list should fail when not initialized, got: {}",
293 result
294 );
295 }
296 }
297}
298
299#[cfg(all(test, not(target_os = "windows")))]
300mod tests {
301 use super::*;
302
303 #[test]
304 fn test_platform_not_supported() {
305 assert!(!is_platform_supported());
306 }
307
308 #[test]
309 #[should_panic(expected = "only supported on Windows")]
310 fn test_functions_panic_on_unsupported_platform() {
311 use std::ffi::CString;
312 let client_id = CString::new("test").unwrap();
313 unsafe {
314 TapSDK_RestartAppIfNecessary(client_id.as_ptr());
315 }
316 }
317}