commit 596405b5672f787fc848fc949f415c0f779536aa Author: wsycarlos Date: Sat Dec 6 16:42:27 2025 +0800 First Version of AppsFlyerSDK Package diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff03d40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,106 @@ +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore +# +.utmp/ +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ +*.log + +# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control. +*.blend1 +*.blend1.meta + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/[Mm]emoryCaptures/ + +# Recordings can get excessive in size +/[Rr]ecordings/ + +# Uncomment this line if you wish to ignore the asset store tools plugin +# /[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +/[Aa]ssets/Plugins/Editor/JetBrains* +# Jetbrains Rider personal-layer settings +*.DotSettings.user + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Mono auto generated files +mono_crash.* + +# Builds +*.apk +*.aab +*.unitypackage +*.unitypackage.meta + +# Crashlytics generated file +crashlytics-build.properties + +# TestRunner generated files +InitTestScene*.unity* + +# Addressables default ignores, before user customizations +/ServerData +/[Aa]ssets/StreamingAssets/aa* +/[Aa]ssets/AddressableAssetsData/link.xml* +/[Aa]ssets/Addressables_Temp* +# By default, Addressables content builds will generate addressables_content_state.bin +# files in platform-specific subfolders, for example: +# /Assets/AddressableAssetsData/OSX/addressables_content_state.bin +/[Aa]ssets/AddressableAssetsData/*/*.bin* + +# Visual Scripting auto-generated files +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db.meta +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers.meta + +# Auto-generated scenes by play mode tests +/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity* + +.vsconfig + +Logs/ +[Aa]ssets/ +[Pp]ublish/ +.vscode/settings.json +*.dat \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor.meta b/Packages/com.bywaystudios.appsflyersdk/Editor.meta new file mode 100644 index 0000000..114159c --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fb2821bc1b233f4c92748ea52f3e2e9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef new file mode 100644 index 0000000..a63b527 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef @@ -0,0 +1,17 @@ +{ + "name": "AppsFlyer.Editor", + "references": [ + "AppsFlyer" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef.meta b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef.meta new file mode 100644 index 0000000..f61dfd3 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyer.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d008146f00dea44d38752b4289e5f65b +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml new file mode 100644 index 0000000..c2af605 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml.meta b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml.meta new file mode 100644 index 0000000..1e4d57e --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerDependencies.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a03558dbbfeac45db9afe9e9c2df5a85 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs new file mode 100644 index 0000000..f18e3fa --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs @@ -0,0 +1,84 @@ +using UnityEditor; +using UnityEngine; + + +[CustomEditor(typeof(AppsFlyerObjectScript))] +[CanEditMultipleObjects] +public class AppsFlyerObjectEditor : Editor +{ + + SerializedProperty devKey; + SerializedProperty appID; + SerializedProperty UWPAppID; + SerializedProperty macOSAppID; + SerializedProperty isDebug; + SerializedProperty getConversionData; + + + void OnEnable() + { + devKey = serializedObject.FindProperty("devKey"); + appID = serializedObject.FindProperty("appID"); + UWPAppID = serializedObject.FindProperty("UWPAppID"); + macOSAppID = serializedObject.FindProperty("macOSAppID"); + isDebug = serializedObject.FindProperty("isDebug"); + getConversionData = serializedObject.FindProperty("getConversionData"); + } + + + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + GUILayout.Box((Texture)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(AssetDatabase.FindAssets("appsflyer_logo")[0]), typeof(Texture)), new GUILayoutOption[] { GUILayout.Width(600) }); + + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox("Set your devKey and appID to init the AppsFlyer SDK and start tracking. You must modify these fields and provide:\ndevKey - Your application devKey provided by AppsFlyer.\nappId - For iOS only. Your iTunes Application ID.\nUWP app id - For UWP only. Your application app id \nMac OS app id - For MacOS app only.", MessageType.Info); + + EditorGUILayout.PropertyField(devKey); + EditorGUILayout.PropertyField(appID); + EditorGUILayout.PropertyField(UWPAppID); + EditorGUILayout.PropertyField(macOSAppID); + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox("Enable get conversion data to allow your app to recive deeplinking callbacks", MessageType.None); + EditorGUILayout.PropertyField(getConversionData); + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox("Debugging should be restricted to development phase only.\n Do not distribute the app to app stores with debugging enabled", MessageType.Warning); + EditorGUILayout.PropertyField(isDebug); + EditorGUILayout.Separator(); + + EditorGUILayout.HelpBox("For more information on setting up AppsFlyer check out our relevant docs.", MessageType.None); + + + if (GUILayout.Button("AppsFlyer Unity Docs", new GUILayoutOption[] { GUILayout.Width(200) })) + { + Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/213766183-Unity-SDK-integration-for-developers"); + } + + if (GUILayout.Button("AppsFlyer Android Docs", new GUILayoutOption[] { GUILayout.Width(200) })) + { + Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers"); + } + + if (GUILayout.Button("AppsFlyer iOS Docs", new GUILayoutOption[] { GUILayout.Width(200) })) + { + Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS"); + } + + if (GUILayout.Button("AppsFlyer Deeplinking Docs", new GUILayoutOption[] { GUILayout.Width(200) })) + { + Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-deep-linking-guide#Setups"); + } + + if (GUILayout.Button("AppsFlyer Windows Docs", new GUILayoutOption[] { GUILayout.Width(200) })) + { + Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032026-Windows-and-Xbox-SDK-integration-for-developers"); + } + + + serializedObject.ApplyModifiedProperties(); + } + + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs.meta new file mode 100644 index 0000000..53d8abb --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/AppsFlyerObjectEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d248a134cf494486fb1d6a2e95a05d87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png b/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png new file mode 100644 index 0000000..01c2b8c Binary files /dev/null and b/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png differ diff --git a/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png.meta b/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png.meta new file mode 100644 index 0000000..90005e8 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Editor/appsflyer_logo.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: bc7fa5a6b64b944a4b2900fd877acb8b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins.meta new file mode 100644 index 0000000..5394930 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66297743248ab4e47abdc371a59f1111 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac.meta new file mode 100644 index 0000000..fd182bd --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 96a328019e42349aabc478b546b8605e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle.meta new file mode 100644 index 0000000..edbfc60 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle.meta @@ -0,0 +1,81 @@ +fileFormatVersion: 2 +guid: 682114f7790724ab3b9410e89bbc076c +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 0 + Exclude Linux64: 1 + Exclude OSXUniversal: 0 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 0 + settings: + AndroidSharedLibraryType: Executable + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: OSX + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: x86_64 + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: x86_64 + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/Info.plist b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/Info.plist new file mode 100644 index 0000000..3303ccd --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/Info.plist @@ -0,0 +1,48 @@ + + + + + BuildMachineOSBuild + 20G417 + CFBundleDevelopmentRegion + en + CFBundleExecutable + AppsFlyerBundle + CFBundleIdentifier + com.appsflyer.support.two.AppsFlyerBundle + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + AppsFlyerBundle + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 13A1030d + DTPlatformName + macosx + DTPlatformVersion + 12.0 + DTSDKBuild + 21A344 + DTSDKName + macosx12.0 + DTXcode + 1310 + DTXcodeBuild + 13A1030d + LSMinimumSystemVersion + 11.6 + NSHumanReadableCopyright + + + diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/MacOS/AppsFlyerBundle b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/MacOS/AppsFlyerBundle new file mode 100644 index 0000000..3376a47 Binary files /dev/null and b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/MacOS/AppsFlyerBundle differ diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature/CodeResources b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..d5d0fd7 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature/CodeResources @@ -0,0 +1,115 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows.meta new file mode 100644 index 0000000..859b3f2 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1fbfcb6aeaa7f40e69a0daff450a2450 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri new file mode 100644 index 0000000..f3993be Binary files /dev/null and b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri differ diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri.meta new file mode 100644 index 0000000..ed4fbf8 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.pri.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c621896ec81267f478e98555031271ef +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd new file mode 100644 index 0000000..381ce32 Binary files /dev/null and b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd differ diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd.meta new file mode 100644 index 0000000..f1ba1b7 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerLib.winmd.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 5186898c6f4665f438e46763d4cff3ae +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 0 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 0 + Exclude Win64: 0 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 0 + settings: + AndroidSharedLibraryType: Executable + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: Windows + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + XboxOne: XboxOne + second: + enabled: 1 + settings: {} + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs new file mode 100644 index 0000000..a44fea4 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs @@ -0,0 +1,145 @@ +//#define AFSDK_WIN_DEBUG +//#define UNITY_WSA_10_0 +//#define ENABLE_WINMD_SUPPORT + +#if UNITY_WSA_10_0 +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.ComponentModel; +using UnityEngine; +using System.Threading.Tasks; + +#if ENABLE_WINMD_SUPPORT +using AppsFlyerLib; +#endif + +namespace AppsFlyerSDK +{ + public class AppsFlyerWindows + { +#if ENABLE_WINMD_SUPPORT + static private MonoBehaviour _gameObject = null; +#endif + + public static void InitSDK(string devKey, string appId, MonoBehaviour gameObject) + { +#if ENABLE_WINMD_SUPPORT + +#if AFSDK_WIN_DEBUG + // Remove callstack + Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); +#endif + Log("[InitSDK]: devKey: {0}, appId: {1}, gameObject: {2}", devKey, appId, gameObject == null ? "null" : gameObject.ToString()); + AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker(); + tracker.devKey = devKey; + tracker.appId = appId; + // Interface + _gameObject = gameObject; +#endif + } + + public static string GetAppsFlyerId() + { +#if ENABLE_WINMD_SUPPORT + Log("[GetAppsFlyerId]"); + return AppsFlyerTracker.GetAppsFlyerTracker().GetAppsFlyerUID(); +#else + return ""; +#endif + } + + public static void SetCustomerUserId(string customerUserId) + { +#if ENABLE_WINMD_SUPPORT + Log("[SetCustomerUserId] customerUserId: {0}", customerUserId); + if (customerUserId.Contains("test_device:")) + { + string testDeviceId = customerUserId.Substring(12); + AppsFlyerTracker.GetAppsFlyerTracker().testDeviceId = testDeviceId; + } + AppsFlyerTracker.GetAppsFlyerTracker().customerUserId = customerUserId; +#endif + } + + public static void Start() + { +#if ENABLE_WINMD_SUPPORT + Log("[Start]"); + AppsFlyerTracker.GetAppsFlyerTracker().TrackAppLaunchAsync(Callback); +#endif + } + +#if ENABLE_WINMD_SUPPORT + public static void Callback(AppsFlyerLib.ServerStatusCode code) + { + Log("[Callback]: {0}", code.ToString()); + + AppsFlyerRequestEventArgs eventArgs = new AppsFlyerRequestEventArgs((int)code, code.ToString()); + if (_gameObject != null) { + var method = _gameObject.GetType().GetMethod("AppsFlyerOnRequestResponse"); + if (method != null) { + method.Invoke(_gameObject, new object[] { AppsFlyerTracker.GetAppsFlyerTracker(), eventArgs }); + } + } + } +#endif + + public static void LogEvent(string eventName, Dictionary eventValues) + { +#if ENABLE_WINMD_SUPPORT + if (eventValues == null) + { + eventValues = new Dictionary(); + } + IDictionary result = new Dictionary(); + foreach (KeyValuePair kvp in eventValues) + { + result.Add(kvp.Key.ToString(), kvp.Value); + } + + Log("[LogEvent]: eventName: {0} result: {1}", eventName, result.ToString()); + + AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker(); + tracker.TrackEvent(eventName, result); + +#endif + } + + + public static void GetConversionData(string _reserved) + { +#if ENABLE_WINMD_SUPPORT + Task.Run(async () => + { + AppsFlyerLib.AppsFlyerTracker tracker = AppsFlyerLib.AppsFlyerTracker.GetAppsFlyerTracker(); + string conversionData = await tracker.GetConversionDataAsync(); + + IAppsFlyerConversionData conversionDataHandler = _gameObject as IAppsFlyerConversionData; + + if (conversionDataHandler != null) + { + Log("[GetConversionData] Will call `onConversionDataSuccess` with: {0}", conversionData); + conversionDataHandler.onConversionDataSuccess(conversionData); + } else { + Log("[GetConversionData] Object with `IAppsFlyerConversionData` interface not found! Check `InitSDK` implementation"); + } + // _gameObject.GetType().GetMethod("onConversionDataSuccess").Invoke(_gameObject, new[] { conversionData }); + }); +#endif + } + + private static void Log(string format, params string[] args) + { +#if AFSDK_WIN_DEBUG +#if ENABLE_WINMD_SUPPORT + Debug.Log("AF_UNITY_WSA_10_0" + String.Format(format, args)); +#endif +#endif + } + + } + +} +#endif diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs.meta new file mode 100644 index 0000000..66f10a1 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/Windows/AppsFlyerWindows.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 034d11e52b599954181d7f08c0d89ca8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS.meta new file mode 100644 index 0000000..286d70c --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8325c12a80ff4323b82e2833a8fc287 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift new file mode 100644 index 0000000..e44f781 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift @@ -0,0 +1,79 @@ +import Foundation +import StoreKit + +#if canImport(PurchaseConnector) +import PurchaseConnector + +@available(iOS 15.0, *) +@objc +public class AFUnityStoreKit2Bridge: NSObject { + @objc + public static func fetchAFSDKTransactionSK2(withTransactionId transactionId: String, completion: @escaping (AFSDKTransactionSK2?) -> Void) { + guard let transactionIdUInt64 = UInt64(transactionId) else { + print("Invalid transaction ID format.") + completion(nil) + return + } + Task { + for await result in StoreKit.Transaction.all { + if case .verified(let transaction) = result, transaction.id == transactionIdUInt64 { + let afTransaction = AFSDKTransactionSK2(transaction: transaction) + DispatchQueue.main.async { + completion(afTransaction) + } + return + } + } + DispatchQueue.main.async { + completion(nil) + } + } + } + + @objc + public static func extractSK2ProductInfo(_ products: [AFSDKProductSK2]) -> NSArray { + var result: [[String: Any]] = [] + + for product in products { + if let swiftProduct = Mirror(reflecting: product).children.first(where: { $0.label == "product" })?.value { + let productId = (swiftProduct as? NSObject)?.value(forKey: "id") as? String ?? "" + let title = (swiftProduct as? NSObject)?.value(forKey: "displayName") as? String ?? "" + let desc = (swiftProduct as? NSObject)?.value(forKey: "description") as? String ?? "" + let price = (swiftProduct as? NSObject)?.value(forKey: "price") as? NSDecimalNumber ?? 0 + + result.append([ + "productIdentifier": productId, + "localizedTitle": title, + "localizedDescription": desc, + "price": price + ]) + } + } + + return result as NSArray + } + + @objc + public static func extractSK2TransactionInfo(_ transactions: [AFSDKTransactionSK2]) -> NSArray { + var result: [[String: Any]] = [] + + for txn in transactions { + guard let mirrorChild = Mirror(reflecting: txn).children.first(where: { $0.label == "transaction" }), + let swiftTxn = mirrorChild.value as? StoreKit.Transaction else { + continue + } + + let transactionId = "\(swiftTxn.id)" + let date = NSNumber(value: swiftTxn.purchaseDate.timeIntervalSince1970) + + result.append([ + "transactionIdentifier": transactionId, + "transactionState": "verified", // or skip this line + "transactionDate": date + ]) + } + + return result as NSArray + } +} +#endif diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift.meta new file mode 100644 index 0000000..f269096 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityStoreKit2Bridge.swift.meta @@ -0,0 +1,42 @@ +fileFormatVersion: 2 +guid: 5652805602a6b4273a6e527b00aea272 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + VisionOS: VisionOS + second: + enabled: 1 + settings: {} + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h new file mode 100644 index 0000000..d3fec43 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h @@ -0,0 +1,24 @@ +// +// AFUnityUtils.h +// +// Created by Andrii H. and Dmitry O. on 16 Oct 2023 +// + +#if __has_include() +#import +#else +#import "AppsFlyerLib.h" +#endif + +static NSString* stringFromChar(const char *str); +static NSDictionary* dictionaryFromJson(const char *jsonString); +static const char* stringFromdictionary(NSDictionary* dictionary); +static NSArray *NSArrayFromCArray(int length, const char **arr); +static char* getCString(const char* string); +static AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator* generator); +static EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt); +static AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetwork); +static NSNumber *intFromNullableBool(const char *cStr); +static NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult); +static NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result); + diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h.meta new file mode 100644 index 0000000..bfd501a --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.h.meta @@ -0,0 +1,81 @@ +fileFormatVersion: 2 +guid: 4b0609ff467554f2088aee1c52bf54a2 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + AndroidSharedLibraryType: Executable + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm new file mode 100644 index 0000000..611f269 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm @@ -0,0 +1,211 @@ +// +// AFUnityUtils.mm +// Unity-iPhone +// +// Created by Jonathan Wesfield on 24/07/2019. +// + +#import "AFUnityUtils.h" + +static NSString* stringFromChar(const char *str) { + return str ? [NSString stringWithUTF8String:str] : nil; +} + +static NSDictionary* dictionaryFromJson(const char *jsonString) { + if(jsonString){ + NSData *jsonData = [[NSData alloc] initWithBytes:jsonString length:strlen(jsonString)]; + NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil]; + return dictionary; + } + + return nil; +} + +static const char* stringFromdictionary(NSDictionary* dictionary) { + if(dictionary){ + NSError * err; + NSData * jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&err]; + NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + return [myString UTF8String]; + } + + return nil; +} + +static NSDictionary* dictionaryFromNSError(NSError* error) { + if(error){ + NSInteger code = [error code]; + NSString *localizedDescription = [error localizedDescription]; + + NSDictionary *errorDictionary = @{ + @"code" : @(code) ?: @(-1), + @"localizedDescription" : localizedDescription, + }; + return errorDictionary; + } + + return nil; +} + + +static NSArray *NSArrayFromCArray(int length, const char **arr) { + NSMutableArray *res = [[NSMutableArray alloc] init]; + for(int i = 0; i < length; i++) { + if (arr[i]) { + [res addObject:[NSString stringWithUTF8String:arr[i]]]; + } + } + + return res; +} + +static char* getCString(const char* string){ + if (string == NULL){ + return NULL; + } + + char* res = (char*)malloc(strlen(string) + 1); + strcpy(res, string); + + return res; +} + +static AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator* generator) { + + NSArray* generatorKeys = @[@"channel", @"customerID", @"campaign", @"referrerName", @"referrerImageUrl", @"deeplinkPath", @"baseDeeplink", @"brandDomain"]; + + NSMutableDictionary* mutableDictionary = [dictionary mutableCopy]; + + [generator setChannel:[dictionary objectForKey: @"channel"]]; + [generator setReferrerCustomerId:[dictionary objectForKey: @"customerID"]]; + [generator setCampaign:[dictionary objectForKey: @"campaign"]]; + [generator setReferrerName:[dictionary objectForKey: @"referrerName"]]; + [generator setReferrerImageURL:[dictionary objectForKey: @"referrerImageUrl"]]; + [generator setDeeplinkPath:[dictionary objectForKey: @"deeplinkPath"]]; + [generator setBaseDeeplink:[dictionary objectForKey: @"baseDeeplink"]]; + [generator setBrandDomain:[dictionary objectForKey: @"brandDomain"]]; + + + [mutableDictionary removeObjectsForKeys:generatorKeys]; + + [generator addParameters:mutableDictionary]; + + return generator; +} + +static EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt){ + + EmailCryptType emailCryptType; + switch (emailCryptTypeInt){ + case 1: + emailCryptType = EmailCryptTypeSHA256; + break; + default: + emailCryptType = EmailCryptTypeNone; + break; + } + + return emailCryptType; +} + +static NSNumber *intFromNullableBool(const char *cStr) { + if (!cStr) return nil; + NSString *str = [NSString stringWithUTF8String:cStr]; + + if ([str caseInsensitiveCompare:@"true"] == NSOrderedSame) { + return @YES; + } else if ([str caseInsensitiveCompare:@"false"] == NSOrderedSame) { + return @NO; + } + return nil; +} + +static AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetworkInt){ + + AppsFlyerAdRevenueMediationNetworkType mediationNetworkType; + switch (mediationNetworkInt){ + case 1: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob; + break; + case 2: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeIronSource; + break; + case 3: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeApplovinMax; + break; + case 4: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeFyber; + break; + case 5: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAppodeal; + break; + case 6: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAdmost; + break; + case 7: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTopon; + break; + case 8: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTradplus; + break; + case 9: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeYandex; + break; + case 10: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeChartBoost; + break; + case 11: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeUnity; + break; + case 12: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeToponPte; + break; + case 13: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom; + break; + case 14: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization; + break; + default: + mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom; + break; + } + + return mediationNetworkType; +} + +static NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult){ + NSString* result; + switch (deepLinkResult){ + case AFSDKDeepLinkResultStatusFound: + result = @"FOUND"; + break; + case AFSDKDeepLinkResultStatusFailure: + result = @"ERROR"; + break; + case AFSDKDeepLinkResultStatusNotFound: + result = @"NOT_FOUND"; + break; + default: + result = @"ERROR"; + break; + } + + return result; +} + +static NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result){ + NSString* res; + + if (result && result.error){ + if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1001) { + res = @"TIMEOUT"; + } else if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1009) { + res = @"NETWORK"; + } + } + + res = @"UNKNOWN"; + + return res; +} diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm.meta new file mode 100644 index 0000000..b411375 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AFUnityUtils.mm.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 18a03931864e84d86bedcc99c440e060 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m new file mode 100644 index 0000000..f877576 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m @@ -0,0 +1,164 @@ +// +// AppsFlyer+AppController.m +// Unity-iPhone +// +// Created by Jonathan Wesfield on 24/07/2019. +// + +#import +#import "UnityAppController.h" +#import "AppsFlyeriOSWrapper.h" +#if __has_include() +#import +#else +#import "AppsFlyerLib.h" +#endif + + +@implementation UnityAppController (AppsFlyerSwizzledAppController) + +static BOOL didEnteredBackGround __unused; +static IMP __original_applicationDidBecomeActive_Imp __unused; +static IMP __original_applicationDidEnterBackground_Imp __unused; +static IMP __original_didReceiveRemoteNotification_Imp __unused; +static IMP __original_continueUserActivity_Imp __unused; +static IMP __original_openUrl_Imp __unused; + + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + +#if !AFSDK_SHOULD_SWIZZLE + + id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"]; + BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO; + + if(shouldSwizzle){ + + Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:)); + __original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive); + + Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:)); + __original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground); + + + Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:)); + __original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification); + + + Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:)); + __original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL); + + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + + [self swizzleContinueUserActivity:[self class]]; + } +#elif AFSDK_SHOULD_SWIZZLE + Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:)); + __original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive); + + Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:)); + __original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground); + + + Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:)); + __original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification); + + + Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:)); + __original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL); + + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + + [self swizzleContinueUserActivity:[self class]]; + +#endif + + + }); +} + ++(void)swizzleContinueUserActivity:(Class)class { + + SEL originalSelector = @selector(application:continueUserActivity:restorationHandler:); + + Method defaultMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, @selector(__swizzled_continueUserActivity)); + + BOOL isMethodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); + + if (isMethodExists) { + __original_continueUserActivity_Imp = method_setImplementation(defaultMethod, (IMP)__swizzled_continueUserActivity); + } else { + class_replaceMethod(class, originalSelector, (IMP)__swizzled_continueUserActivity, method_getTypeEncoding(swizzledMethod)); + } +} + +BOOL __swizzled_continueUserActivity(id self, SEL _cmd, UIApplication* application, NSUserActivity* userActivity, void (^restorationHandler)(NSArray*)) { + NSLog(@"swizzled continueUserActivity"); + [[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler]; + + if(__original_continueUserActivity_Imp){ + return ((BOOL(*)(id, SEL, UIApplication*, NSUserActivity*, void (^)(NSArray*)))__original_continueUserActivity_Imp)(self, _cmd, application, userActivity, NULL); + } + + return YES; +} + + + +void __swizzled_applicationDidBecomeActive(id self, SEL _cmd, UIApplication* launchOptions) { + NSLog(@"swizzled applicationDidBecomeActive"); + [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate]; + + if(didEnteredBackGround && AppsFlyeriOSWarpper.didCallStart == YES){ + [[AppsFlyerLib shared] start]; + } + + if(__original_applicationDidBecomeActive_Imp){ + ((void(*)(id,SEL, UIApplication*))__original_applicationDidBecomeActive_Imp)(self, _cmd, launchOptions); + } +} + + +void __swizzled_applicationDidEnterBackground(id self, SEL _cmd, UIApplication* application) { + NSLog(@"swizzled applicationDidEnterBackground"); + didEnteredBackGround = YES; + if(__original_applicationDidEnterBackground_Imp){ + ((void(*)(id,SEL, UIApplication*))__original_applicationDidEnterBackground_Imp)(self, _cmd, application); + } +} + + +BOOL __swizzled_didReceiveRemoteNotification(id self, SEL _cmd, UIApplication* application, NSDictionary* userInfo,void (^UIBackgroundFetchResult)(void) ) { + NSLog(@"swizzled didReceiveRemoteNotification"); + + [[AppsFlyerLib shared] handlePushNotification:userInfo]; + + if(__original_didReceiveRemoteNotification_Imp){ + return ((BOOL(*)(id, SEL, UIApplication*, NSDictionary*, int(UIBackgroundFetchResult)))__original_didReceiveRemoteNotification_Imp)(self, _cmd, application, userInfo, nil); + } + return YES; +} + + + +BOOL __swizzled_openURL(id self, SEL _cmd, UIApplication* application, NSURL* url, NSDictionary * options) { + NSLog(@"swizzled openURL"); + [[AppsFlyerAttribution shared] handleOpenUrl:url options:options]; + if(__original_openUrl_Imp){ + return ((BOOL(*)(id, SEL, UIApplication*, NSURL*, NSDictionary*))__original_openUrl_Imp)(self, _cmd, application, url, options); + } + return NO; +} + + +@end + + + diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m.meta new file mode 100644 index 0000000..24856fa --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyer+AppController.m.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 6ae9e1f7daef2427588fab2fbf8d35d5 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm new file mode 100644 index 0000000..3e492c0 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm @@ -0,0 +1,131 @@ +// +// AppsFlyerAppController.mm +// Unity-iPhone +// +// Created by Jonathan Wesfield on 30/07/2019. +// + +#import +#import "UnityAppController.h" +#import "AppDelegateListener.h" +#import "AppsFlyeriOSWrapper.h" +#if __has_include() +#import +#else +#import "AppsFlyerLib.h" +#endif +#import + +/** + Note if you would like to use method swizzeling see AppsFlyer+AppController.m + If you are using swizzeling then comment out the method that is being swizzeled in AppsFlyerAppController.mm + Only use swizzeling if there are conflicts with other plugins that needs to be resolved. +*/ + + +@interface AppsFlyerAppController : UnityAppController +{ + BOOL didEnteredBackGround; +} +@end + +@implementation AppsFlyerAppController + +- (instancetype)init +{ + self = [super init]; + if (self) { + + id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"]; + BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO; + + if(!shouldSwizzle){ + UnityRegisterAppDelegateListener(self); + } + } + return self; +} + +- (void)didFinishLaunching:(NSNotification*)notification { + NSLog(@"got didFinishLaunching = %@",notification.userInfo); + + + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate]; + + if (notification.userInfo[@"url"]) { + [self onOpenURL:notification]; + } +} + +-(void)didBecomeActive:(NSNotification*)notification { + NSLog(@"got didBecomeActive(out) = %@", notification.userInfo); + if (didEnteredBackGround == YES && AppsFlyeriOSWarpper.didCallStart == YES) { + [[AppsFlyerLib shared] start]; + didEnteredBackGround = NO; + } +} + +- (void)didEnterBackground:(NSNotification*)notification { + NSLog(@"got didEnterBackground = %@", notification.userInfo); + didEnteredBackGround = YES; +} + +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler { + [[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler]; + return YES; +} + + +- (void)onOpenURL:(NSNotification*)notification { + NSLog(@"got onOpenURL = %@", notification.userInfo); + NSURL *url = notification.userInfo[@"url"]; + NSString *sourceApplication = notification.userInfo[@"sourceApplication"]; + + if (sourceApplication == nil) { + sourceApplication = @""; + } + + if (url != nil) { + [[AppsFlyerAttribution shared] handleOpenUrl:url sourceApplication:sourceApplication annotation:nil]; + } + +} + +- (void)didReceiveRemoteNotification:(NSNotification*)notification { + NSLog(@"got didReceiveRemoteNotification = %@", notification.userInfo); + [[AppsFlyerLib shared] handlePushNotification:notification.userInfo]; +} + +@end + +#if !(AFSDK_SHOULD_SWIZZLE) + +IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController) + +#endif +/** +Note if you would not like to use IMPL_APP_CONTROLLER_SUBCLASS you can replace it with the code below. + + +(void)load + { + [AppsFlyerAppController plugin]; + } + + // Singleton accessor. + + (AppsFlyerAppController *)plugin + { + static AppsFlyerAppController *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + + sharedInstance = [[AppsFlyerAppController alloc] init]; + }); + + return sharedInstance; + } + + **/ diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm.meta new file mode 100644 index 0000000..2e8e52c --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAppController.mm.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 2d1497a1493b24fecaa58bd3a7b707f9 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h new file mode 100644 index 0000000..c79fec4 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h @@ -0,0 +1,34 @@ +// +// AppsFlyerAttribution.h +// UnityFramework +// +// Created by Margot Guetta on 11/04/2021. +// + +#ifndef AppsFlyerAttribution_h +#define AppsFlyerAttribution_h +#endif /* AppsFlyerAttribution_h */ +#if __has_include() +#import +#else +#import "AppsFlyerLib.h" +#endif + + +@interface AppsFlyerAttribution : NSObject +@property NSUserActivity*_Nullable userActivity; +@property (nonatomic, copy) void (^ _Nullable restorationHandler)(NSArray *_Nullable ); +@property NSURL * _Nullable url; +@property NSDictionary * _Nullable options; +@property NSString* _Nullable sourceApplication; +@property id _Nullable annotation; +@property BOOL isBridgeReady; + ++ (AppsFlyerAttribution *_Nullable)shared; +- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler; +- (void) handleOpenUrl:(NSURL*_Nullable)url options:(NSDictionary*_Nullable) options; +- (void) handleOpenUrl: (NSURL *_Nonnull)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation; + +@end + +static NSString * _Nullable const AF_BRIDGE_SET = @"bridge is set"; diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h.meta new file mode 100644 index 0000000..ad63349 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.h.meta @@ -0,0 +1,81 @@ +fileFormatVersion: 2 +guid: 8544dc3b3c7bb40d397b2de568df1058 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + AndroidSharedLibraryType: Executable + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m new file mode 100644 index 0000000..c4e7278 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m @@ -0,0 +1,86 @@ +// +// NSObject+AppsFlyerAttribution.m +// UnityFramework +// +// Created by Margot Guetta on 11/04/2021. +// + +#import +#import "AppsFlyerAttribution.h" + +@implementation AppsFlyerAttribution + ++ (id)shared { + static AppsFlyerAttribution *shared = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shared = [[self alloc] init]; + }); + return shared; +} + +- (id)init { + if (self = [super init]) { + self.options = nil; + self.restorationHandler = nil; + self.url = nil; + self.userActivity = nil; + self.annotation = nil; + self.sourceApplication = nil; + self.isBridgeReady = NO; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(receiveBridgeReadyNotification:) + name:AF_BRIDGE_SET + object:nil]; + } + return self; +} + +- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler{ + if(self.isBridgeReady == YES){ + [[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler]; + }else{ + [AppsFlyerAttribution shared].userActivity = userActivity; + [AppsFlyerAttribution shared].restorationHandler = restorationHandler; + } +} + +- (void) handleOpenUrl:(NSURL *)url options:(NSDictionary *)options{ + if(self.isBridgeReady == YES){ + [[AppsFlyerLib shared] handleOpenUrl:url options:options]; + }else{ + [AppsFlyerAttribution shared].url = url; + [AppsFlyerAttribution shared].options = options; + } +} + +- (void) handleOpenUrl:(NSURL *)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{ + if(self.isBridgeReady == YES){ + [[AppsFlyerLib shared] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation]; + }else{ + [AppsFlyerAttribution shared].url = url; + [AppsFlyerAttribution shared].sourceApplication = sourceApplication; + [AppsFlyerAttribution shared].annotation = annotation; + } + +} + +- (void) receiveBridgeReadyNotification:(NSNotification *) notification +{ + NSLog (@"AppsFlyer Debug: handle deep link"); + if(self.url && self.sourceApplication){ + [[AppsFlyerLib shared] handleOpenURL:self.url sourceApplication:self.sourceApplication withAnnotation:self.annotation]; + self.url = nil; + self.sourceApplication = nil; + self.annotation = nil; + }else if(self.options && self.url){ + [[AppsFlyerLib shared] handleOpenUrl:self.url options:self.options]; + self.options = nil; + self.url = nil; + }else if(self.userActivity){ + [[AppsFlyerLib shared] continueUserActivity:self.userActivity restorationHandler:nil]; + self.userActivity = nil; + self.restorationHandler = nil; + } +} +@end diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m.meta new file mode 100644 index 0000000..9f071e6 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyerAttribution.m.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 1060e47d7b9e2453ba575f0b455b2bf8 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h new file mode 100644 index 0000000..cf73afe --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h @@ -0,0 +1,71 @@ +// +// AppsFlyeriOSWarpper.h +// Unity-iPhone +// +// Created by Jonathan Wesfield on 24/07/2019. +// + +#import "AFUnityUtils.mm" +#import "UnityAppController.h" +#import "AppsFlyerAttribution.h" +#if __has_include() +#import +#else +#import "AppsFlyerLib.h" +#endif +#if __has_include() +#import +#else +#import "PurchaseConnector.h" +#endif +#import + +// Add StoreKit 2 support +#if __has_include() +#import +#endif + +@interface AppsFlyeriOSWarpper : NSObject + ++ (BOOL) didCallStart; ++ (void) setDidCallStart:(BOOL)val; + +// Add StoreKit 2 methods +- (void)setStoreKitVersion:(int)storeKitVersion; +- (void)logConsumableTransaction:(id)transaction; + +@end + + +static AppsFlyeriOSWarpper *_AppsFlyerdelegate; +static const int kPushNotificationSize = 32; + +static NSString* ConversionDataCallbackObject = @"AppsFlyerObject"; + +static const char* VALIDATE_CALLBACK = "didFinishValidateReceipt"; +static const char* VALIDATE_ERROR_CALLBACK = "didFinishValidateReceiptWithError"; +static const char* GCD_CALLBACK = "onConversionDataSuccess"; +static const char* GCD_ERROR_CALLBACK = "onConversionDataFail"; +static const char* OAOA_CALLBACK = "onAppOpenAttribution"; +static const char* OAOA_ERROR_CALLBACK = "onAppOpenAttributionFailure"; +static const char* GENERATE_LINK_CALLBACK = "onInviteLinkGenerated"; +static const char* OPEN_STORE_LINK_CALLBACK = "onOpenStoreLinkGenerated"; +static const char* START_REQUEST_CALLBACK = "requestResponseReceived"; +static const char* IN_APP_RESPONSE_CALLBACK = "inAppResponseReceived"; +static const char* ON_DEEPLINKING = "onDeepLinking"; +static const char* VALIDATE_AND_LOG_V2_CALLBACK = "onValidateAndLogComplete"; +static const char* VALIDATE_AND_LOG_V2_ERROR_CALLBACK = "onValidateAndLogFailure"; + + +static NSString* validateObjectName = @""; +static NSString* openStoreObjectName = @""; +static NSString* generateInviteObjectName = @""; +static NSString* validateAndLogObjectName = @""; +static NSString* startRequestObjectName = @""; +static NSString* inAppRequestObjectName = @""; +static NSString* onDeeplinkingObjectName = @""; + +static const char* PURCHASE_REVENUE_VALIDATION_CALLBACK = "didReceivePurchaseRevenueValidationInfo"; +static const char* PURCHASE_REVENUE_ERROR_CALLBACK = "didReceivePurchaseRevenueError"; + +static NSString* onPurchaseValidationObjectName = @""; diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h.meta new file mode 100644 index 0000000..0638ac9 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.h.meta @@ -0,0 +1,81 @@ +fileFormatVersion: 2 +guid: 147104b04b5794eaa92b4195cc328e13 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + AndroidSharedLibraryType: Executable + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm new file mode 100644 index 0000000..41a71a3 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm @@ -0,0 +1,620 @@ +// +// AppsFlyeriOSWarpper.mm +// Unity-iPhone +// +// Created by Jonathan Wesfield on 24/07/2019. +// + +#import "AppsFlyeriOSWrapper.h" +#import + +#import +#import "UnityFramework/UnityFramework-Swift.h" + +#if __has_include() +#import +#elif __has_include("PurchaseConnector-Swift.h") +#import "PurchaseConnector-Swift.h" +#endif + +#if __has_include() +#import +#elif __has_include("UnityFramework-Swift.h") +#import "UnityFramework-Swift.h" +#endif + +static void unityCallBack(NSString* objectName, const char* method, const char* msg) { + if(objectName){ + UnitySendMessage([objectName UTF8String], method, msg); + } +} + +extern "C" { + + const void _startSDK(bool shouldCallback, const char* objectName) { + [[AppsFlyerLib shared] setPluginInfoWith: AFSDKPluginUnity + pluginVersion:@"6.17.72" + additionalParams:nil]; + startRequestObjectName = stringFromChar(objectName); + AppsFlyeriOSWarpper.didCallStart = YES; + [AppsFlyerAttribution shared].isBridgeReady = YES; + [[NSNotificationCenter defaultCenter] postNotificationName:AF_BRIDGE_SET object: [AppsFlyerAttribution shared]]; + [[AppsFlyerLib shared] startWithCompletionHandler:^(NSDictionary *dictionary, NSError *error) { + if(shouldCallback){ + if (error) { + NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]}; + unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(callbackDictionary)); + return; + } + if (dictionary) { + unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(dictionary)); + return; + } + } + }]; + } + + const void _setCustomerUserID (const char* customerUserID) { + [[AppsFlyerLib shared] setCustomerUserID:stringFromChar(customerUserID)]; + } + + const void _setAdditionalData (const char* customData) { + [[AppsFlyerLib shared] setAdditionalData:dictionaryFromJson(customData)]; + } + + const void _setAppsFlyerDevKey (const char* appsFlyerDevKey) { + [AppsFlyerLib shared].appsFlyerDevKey = stringFromChar(appsFlyerDevKey); + } + + const void _setAppleAppID (const char* appleAppID) { + [AppsFlyerLib shared].appleAppID = stringFromChar(appleAppID); + } + + const void _setCurrencyCode (const char* currencyCode) { + [[AppsFlyerLib shared] setCurrencyCode:stringFromChar(currencyCode)]; + } + + const void _setDisableCollectAppleAdSupport (bool disableAdvertisingIdentifier) { + [AppsFlyerLib shared].disableAdvertisingIdentifier = disableAdvertisingIdentifier; + } + + const void _setIsDebug (bool isDebug) { + [AppsFlyerLib shared].isDebug = isDebug; + } + + const void _setShouldCollectDeviceName (bool shouldCollectDeviceName) { + [AppsFlyerLib shared].shouldCollectDeviceName = shouldCollectDeviceName; + } + + const void _setAppInviteOneLinkID (const char* appInviteOneLinkID) { + [[AppsFlyerLib shared] setAppInviteOneLink:stringFromChar(appInviteOneLinkID)]; + } + + const void _setDeepLinkTimeout (long deepLinkTimeout) { + [AppsFlyerLib shared].deepLinkTimeout = deepLinkTimeout; + } + + const void _anonymizeUser (bool anonymizeUser) { + [AppsFlyerLib shared].anonymizeUser = anonymizeUser; + } + + const void _enableTCFDataCollection (bool shouldCollectTcfData) { + [[AppsFlyerLib shared] enableTCFDataCollection:shouldCollectTcfData]; + } + + const void _setConsentData(const char* isUserSubjectToGDPR, const char* hasConsentForDataUsage, const char* hasConsentForAdsPersonalization, const char* hasConsentForAdStorage) { + + NSNumber *gdpr = intFromNullableBool(isUserSubjectToGDPR); + NSNumber *dataUsage = intFromNullableBool(hasConsentForDataUsage); + NSNumber *adsPersonalization = intFromNullableBool(hasConsentForAdsPersonalization); + NSNumber *adStorage = intFromNullableBool(hasConsentForAdStorage); + + AppsFlyerConsent *consentData = [[AppsFlyerConsent alloc] initWithIsUserSubjectToGDPR:gdpr + hasConsentForDataUsage:dataUsage + hasConsentForAdsPersonalization:adsPersonalization + hasConsentForAdStorage:adStorage]; + + [[AppsFlyerLib shared] setConsentData:consentData]; + } + + const void _logAdRevenue(const char* monetizationNetwork, int mediationNetworkInt, const char* currencyIso4217Code, double eventRevenue, const char* additionalParameters) { + AppsFlyerAdRevenueMediationNetworkType mediationNetwork = mediationNetworkTypeFromInt(mediationNetworkInt); + NSNumber *number = [NSNumber numberWithDouble:eventRevenue]; + AFAdRevenueData *adRevenue = [[AFAdRevenueData alloc] initWithMonetizationNetwork:stringFromChar(monetizationNetwork) mediationNetwork:mediationNetwork currencyIso4217Code:stringFromChar(currencyIso4217Code) eventRevenue:number]; + [[AppsFlyerLib shared] logAdRevenue: adRevenue additionalParameters:dictionaryFromJson(additionalParameters)]; + } + + const void _setDisableCollectIAd (bool disableCollectASA) { + [AppsFlyerLib shared].disableCollectASA = disableCollectASA; + } + + const void _setUseReceiptValidationSandbox (bool useReceiptValidationSandbox) { + [AppsFlyerLib shared].useReceiptValidationSandbox = useReceiptValidationSandbox; + } + + const void _setUseUninstallSandbox (bool useUninstallSandbox) { + [AppsFlyerLib shared].useUninstallSandbox = useUninstallSandbox; + } + + const void _setResolveDeepLinkURLs (int length, const char **resolveDeepLinkURLs) { + if(length > 0 && resolveDeepLinkURLs) { + [[AppsFlyerLib shared] setResolveDeepLinkURLs:NSArrayFromCArray(length, resolveDeepLinkURLs)]; + } + } + + const void _setOneLinkCustomDomains (int length, const char **oneLinkCustomDomains) { + if(length > 0 && oneLinkCustomDomains) { + [[AppsFlyerLib shared] setOneLinkCustomDomains:NSArrayFromCArray(length, oneLinkCustomDomains)]; + } + } + + const void _afSendEvent (const char* eventName, const char* eventValues, bool shouldCallback, const char* objectName) { + inAppRequestObjectName = stringFromChar(objectName); + [[AppsFlyerLib shared] logEventWithEventName:stringFromChar(eventName) eventValues:dictionaryFromJson(eventValues) completionHandler:^(NSDictionary *dictionary, NSError *error) { + if(shouldCallback){ + if (error) { + NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]}; + unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(callbackDictionary)); + return; + } + if (dictionary) { + unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(dictionary)); + return; + } + } + }]; + } + + const void _recordLocation (double longitude, double latitude) { + [[AppsFlyerLib shared] logLocation:longitude latitude:latitude]; + } + + const char* _getAppsFlyerId () { + return getCString([[[AppsFlyerLib shared] getAppsFlyerUID] UTF8String]); + } + + const void _registerUninstall (unsigned char* deviceToken) { + if(deviceToken){ + NSData* tokenData = [NSData dataWithBytes:(const void *)deviceToken length:sizeof(unsigned char)*kPushNotificationSize]; + [[AppsFlyerLib shared] registerUninstall:tokenData]; + } + } + + const void _handlePushNotification (const char* pushPayload) { + [[AppsFlyerLib shared] handlePushNotification:dictionaryFromJson(pushPayload)]; + } + + const char* _getSDKVersion () { + return getCString([[[AppsFlyerLib shared] getSDKVersion] UTF8String]); + } + + const void _setHost (const char* host, const char* hostPrefix) { + [[AppsFlyerLib shared] setHost:stringFromChar(host) withHostPrefix:stringFromChar(hostPrefix)]; + } + + const void _setMinTimeBetweenSessions (int minTimeBetweenSessions) { + [AppsFlyerLib shared].minTimeBetweenSessions = minTimeBetweenSessions; + } + + const void _stopSDK (bool isStopped) { + [AppsFlyerLib shared].isStopped = isStopped; + } + + const BOOL _isSDKStopped () { + return [AppsFlyerLib shared].isStopped; + } + + const void _handleOpenUrl(const char *url, const char *sourceApplication, const char *annotation) { + [[AppsFlyerLib shared] handleOpenURL:[NSURL URLWithString:stringFromChar(url)] sourceApplication:stringFromChar(sourceApplication) withAnnotation:stringFromChar(annotation)]; } + + const void _recordCrossPromoteImpression (const char* appID, const char* campaign, const char* parameters) { + [AppsFlyerCrossPromotionHelper logCrossPromoteImpression:stringFromChar(appID) campaign:stringFromChar(campaign) parameters:dictionaryFromJson(parameters)]; } + + const void _attributeAndOpenStore (const char* appID, const char* campaign, const char* parameters, const char* objectName) { + + openStoreObjectName = stringFromChar(objectName); + + [AppsFlyerCrossPromotionHelper + logAndOpenStore:stringFromChar(appID) + campaign:stringFromChar(campaign) + parameters:dictionaryFromJson(parameters) + openStore:^(NSURLSession * _Nonnull urlSession, NSURL * _Nonnull clickURL) { + unityCallBack(openStoreObjectName, OPEN_STORE_LINK_CALLBACK, [clickURL.absoluteString UTF8String]); + }]; + } + + const void _generateUserInviteLink (const char* parameters, const char* objectName) { + + generateInviteObjectName = stringFromChar(objectName); + + [AppsFlyerShareInviteHelper generateInviteUrlWithLinkGenerator:^AppsFlyerLinkGenerator * _Nonnull(AppsFlyerLinkGenerator * _Nonnull generator) { + return generatorFromDictionary(dictionaryFromJson(parameters), generator); + } completionHandler:^(NSURL * _Nullable url) { + unityCallBack(generateInviteObjectName, GENERATE_LINK_CALLBACK, [url.absoluteString UTF8String]); + }]; + } + + const void _recordInvite (const char* channel, const char* parameters) { + [AppsFlyerShareInviteHelper logInvite:stringFromChar(channel) parameters:dictionaryFromJson(parameters)]; + } + + const void _setUserEmails (int emailCryptTypeInt , int length, const char **userEmails) { + if(length > 0 && userEmails) { + [[AppsFlyerLib shared] setUserEmails:NSArrayFromCArray(length, userEmails) withCryptType:emailCryptTypeFromInt(emailCryptTypeInt)]; + } + } + + const void _setPhoneNumber (const char* phoneNumber) { + [[AppsFlyerLib shared] setPhoneNumber:stringFromChar(phoneNumber)]; + } + + const void _setSharingFilterForAllPartners () { + [[AppsFlyerLib shared] setSharingFilterForAllPartners]; + } + + const void _setSharingFilter (int length, const char **partners) { + if(length > 0 && partners) { + [[AppsFlyerLib shared] setSharingFilter:NSArrayFromCArray(length, partners)]; + } + } + + const void _setSharingFilterForPartners (int length, const char **partners) { + if(length > 0 && partners) { + [[AppsFlyerLib shared] setSharingFilterForPartners:NSArrayFromCArray(length, partners)]; + } else { + [[AppsFlyerLib shared] setSharingFilterForPartners:nil]; + } + } + + const void _validateAndSendInAppPurchase (const char* productIdentifier, const char* price, const char* currency, const char* transactionId, const char* additionalParameters, const char* objectName) { + + validateObjectName = stringFromChar(objectName); + + [[AppsFlyerLib shared] + validateAndLogInAppPurchase:stringFromChar(productIdentifier) + price:stringFromChar(price) + currency:stringFromChar(currency) + transactionId:stringFromChar(transactionId) + additionalParameters:dictionaryFromJson(additionalParameters) + success:^(NSDictionary *result){ + unityCallBack(validateObjectName, VALIDATE_CALLBACK, stringFromdictionary(result)); + } failure:^(NSError *error, id response) { + if(response && [response isKindOfClass:[NSDictionary class]]) { + NSDictionary* value = (NSDictionary*)response; + unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, stringFromdictionary(value)); + } else { + unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, error ? [[error localizedDescription] UTF8String] : "error"); + } + }]; + } + + const void _validateAndSendInAppPurchaseV2 (const char* product, const char* transactionId, int purchaseType, const char* purchaseAdditionalDetails, const char* objectName) { + + validateAndLogObjectName = stringFromChar(objectName); + AFSDKPurchaseDetails *details = [[AFSDKPurchaseDetails alloc] initWithProductId:stringFromChar(product) transactionId:stringFromChar(transactionId) purchaseType:(AFSDKPurchaseType)purchaseType]; + + [[AppsFlyerLib shared] + validateAndLogInAppPurchase:details + purchaseAdditionalDetails:dictionaryFromJson(purchaseAdditionalDetails) + completion:^(NSDictionary * _Nullable response, NSError * _Nullable error) { + if (error) { + unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_ERROR_CALLBACK, stringFromdictionary(dictionaryFromNSError(error))); + } else { + // Check if the response indicates validation failure + BOOL isValidationFailure = NO; + if (response && [response isKindOfClass:[NSDictionary class]]) { + NSDictionary *resultDict = response[@"result"]; + if (resultDict && [resultDict isKindOfClass:[NSDictionary class]]) { + NSDictionary *responseForProduct = resultDict.allValues.firstObject; + if (responseForProduct && [responseForProduct isKindOfClass:[NSDictionary class]]) { + BOOL validationResult = [responseForProduct[@"result"] boolValue]; + if (!validationResult) { + isValidationFailure = YES; + } + } + } + } + + if (isValidationFailure) { + unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_ERROR_CALLBACK, stringFromdictionary(response)); + } else { + unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_CALLBACK, stringFromdictionary(response)); + } + } + }]; + + } + + const void _getConversionData(const char* objectName) { + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + ConversionDataCallbackObject = stringFromChar(objectName); + [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate]; + } + + const void _waitForATTUserAuthorizationWithTimeoutInterval (int timeoutInterval) { + [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval]; + } + + const void _disableSKAdNetwork (bool isDisabled) { + [AppsFlyerLib shared].disableSKAdNetwork = isDisabled; + } + + const void _addPushNotificationDeepLinkPath (int length, const char **paths) { + if(length > 0 && paths) { + [[AppsFlyerLib shared] addPushNotificationDeepLinkPath:NSArrayFromCArray(length, paths)]; + } + } + + const void _subscribeForDeepLink (const char* objectName) { + + onDeeplinkingObjectName = stringFromChar(objectName); + + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + [[AppsFlyerLib shared] setDeepLinkDelegate:_AppsFlyerdelegate]; + } + + const void _setCurrentDeviceLanguage(const char* language) { + [[AppsFlyerLib shared] setCurrentDeviceLanguage:stringFromChar(language)]; + } + + const void _setPartnerData(const char* partnerId, const char* partnerInfo) { + [[AppsFlyerLib shared] setPartnerDataWithPartnerId: stringFromChar(partnerId) partnerInfo:dictionaryFromJson(partnerInfo)]; + } + + const void _disableIDFVCollection(bool isDisabled) { + [AppsFlyerLib shared].disableIDFVCollection = isDisabled; + } + + // Purchase connector + const void _startObservingTransactions() { + [[PurchaseConnector shared] startObservingTransactions]; + } + + const void _stopObservingTransactions() { + [[PurchaseConnector shared] stopObservingTransactions]; + } + + const void _setIsSandbox(bool isSandBox) { + [[PurchaseConnector shared] setIsSandbox:isSandBox]; + } + + const void _setPurchaseRevenueDelegate() { + if (_AppsFlyerdelegate== nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + [[PurchaseConnector shared] setPurchaseRevenueDelegate:_AppsFlyerdelegate]; + } + + const void _setAutoLogPurchaseRevenue(int option) { + [[PurchaseConnector shared] setAutoLogPurchaseRevenue:option]; + + } + + const void _initPurchaseConnector(const char* objectName) { + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + onPurchaseValidationObjectName = stringFromChar(objectName); + } + + const void _setPurchaseRevenueDataSource(const char* objectName) { + if (_AppsFlyerdelegate == nil) { + _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init]; + } + + if (strstr(objectName, "StoreKit2") != NULL) { + + // Force protocol conformance + Protocol *sk2Protocol = @protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2); + class_addProtocol([_AppsFlyerdelegate class], sk2Protocol); + + if (![_AppsFlyerdelegate conformsToProtocol:@protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2)]) { + NSLog(@"[AppsFlyer] Warning: SK2 protocol not conformed!"); + } + } + + [PurchaseConnector shared].purchaseRevenueDataSource = _AppsFlyerdelegate; + } + + const void _setStoreKitVersion(int storeKitVersion) { + [[PurchaseConnector shared] setStoreKitVersion:(AFSDKStoreKitVersion)storeKitVersion]; + } + + const void _logConsumableTransaction(const char* transactionId) { + if (@available(iOS 15.0, *)) { + NSString *transactionIdStr = [NSString stringWithUTF8String:transactionId]; + [AFUnityStoreKit2Bridge fetchAFSDKTransactionSK2WithTransactionId:transactionIdStr completion:^(AFSDKTransactionSK2 *afTransaction) { + if (afTransaction) { + [[PurchaseConnector shared] logConsumableTransaction:afTransaction]; + } else { + NSLog(@"No AFSDKTransactionSK2 found for id %@", transactionIdStr); + } + }]; + } + } + + #ifdef __cplusplus + extern "C" { + #endif + + typedef const char *(*UnityPurchaseCallback)(const char *, const char *); + + UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallback = NULL; + UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallbackSK2 = NULL; + + __attribute__((visibility("default"))) + void RegisterUnityPurchaseRevenueParamsCallback(UnityPurchaseCallback callback) { + UnityPurchasesGetAdditionalParamsCallback = callback; + } + + __attribute__((visibility("default"))) + void RegisterUnityPurchaseRevenueParamsCallbackSK2(UnityPurchaseCallback callback) { + UnityPurchasesGetAdditionalParamsCallbackSK2 = callback; + } + + + #ifdef __cplusplus + } + #endif +} + +@implementation AppsFlyeriOSWarpper + +static BOOL didCallStart; ++ (BOOL) didCallStart +{ @synchronized(self) { return didCallStart; } } ++ (void) setDidCallStart:(BOOL)val +{ @synchronized(self) { didCallStart = val; } } + +- (void)onConversionDataSuccess:(NSDictionary *)installData { + unityCallBack(ConversionDataCallbackObject, GCD_CALLBACK, stringFromdictionary(installData)); +} + +- (void)onConversionDataFail:(NSError *)error { + unityCallBack(ConversionDataCallbackObject, GCD_ERROR_CALLBACK, [[error localizedDescription] UTF8String]); +} + +- (void)onAppOpenAttribution:(NSDictionary *)attributionData { + unityCallBack(ConversionDataCallbackObject, OAOA_CALLBACK, stringFromdictionary(attributionData)); +} + +- (void)onAppOpenAttributionFailure:(NSError *)error { + unityCallBack(ConversionDataCallbackObject, OAOA_ERROR_CALLBACK, [[error localizedDescription] UTF8String]); +} + +- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result{ + + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + + [dict setValue:stringFromDeepLinkResultError(result) forKey:@"error"]; + [dict setValue:stringFromDeepLinkResultStatus(result.status) forKey:@"status"]; + + if(result && result.deepLink){ + [dict setValue:result.deepLink.description forKey:@"deepLink"]; + [dict setValue:@(result.deepLink.isDeferred) forKey:@"is_deferred"]; + } + + unityCallBack(onDeeplinkingObjectName, ON_DEEPLINKING, stringFromdictionary(dict)); +} + +// Purchase Connector +- (void)didReceivePurchaseRevenueValidationInfo:(NSDictionary *)validationInfo error:(NSError *)error { + if (error != nil) { + unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_ERROR_CALLBACK, [[error localizedDescription] UTF8String]); + } else { + unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_VALIDATION_CALLBACK, stringFromdictionary(validationInfo)); + } +} + +- (NSDictionary *)purchaseRevenueAdditionalParametersForProducts:(NSSet *)products + transactions:(NSSet *)transactions { + + NSMutableArray *productsArray = [NSMutableArray array]; + for (SKProduct *product in products) { + [productsArray addObject:@{ + @"productIdentifier": product.productIdentifier ?: @"", + @"localizedTitle": product.localizedTitle ?: @"", + @"localizedDescription": product.localizedDescription ?: @"", + @"price": [product.price stringValue] ?: @"" + }]; + } + + NSMutableArray *transactionsArray = [NSMutableArray array]; + for (SKPaymentTransaction *txn in transactions) { + [transactionsArray addObject:@{ + @"transactionIdentifier": txn.transactionIdentifier ?: @"", + @"transactionState": @(txn.transactionState), + @"transactionDate": txn.transactionDate ? [@(txn.transactionDate.timeIntervalSince1970) stringValue] : @"" + }]; + } + + NSDictionary *input = @{ + @"products": productsArray, + @"transactions": transactionsArray + }; + + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error]; + if (error || !jsonData) { + NSLog(@"[AppsFlyer] Failed to serialize Unity purchase data: %@", error); + return @{}; + } + + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + if (!jsonString || !UnityPurchasesGetAdditionalParamsCallback) { + NSLog(@"[AppsFlyer] Unity callback not registered"); + return @{}; + } + + const char *resultCStr = UnityPurchasesGetAdditionalParamsCallback([jsonString UTF8String], ""); + if (!resultCStr) { + NSLog(@"[AppsFlyer] Unity callback returned null"); + return @{}; + } + + NSString *resultJson = [NSString stringWithUTF8String:resultCStr]; + NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error]; + + if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) { + NSLog(@"[AppsFlyer] Failed to parse Unity response: %@", error); + return @{}; + } + + return parsedResult; +} + +#pragma mark - AppsFlyerPurchaseRevenueDataSourceStoreKit2 +- (NSDictionary *)purchaseRevenueAdditionalParametersStoreKit2ForProducts:(NSSet *)products transactions:(NSSet *)transactions { + if (@available(iOS 15.0, *)) { + NSArray *productInfoArray = [AFUnityStoreKit2Bridge extractSK2ProductInfo:[products allObjects]]; + NSArray *transactionInfoArray = [AFUnityStoreKit2Bridge extractSK2TransactionInfo:[transactions allObjects]]; + + NSDictionary *input = @{ + @"products": productInfoArray, + @"transactions": transactionInfoArray + }; + + if (UnityPurchasesGetAdditionalParamsCallbackSK2) { + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error]; + if (error || !jsonData) { + NSLog(@"[AppsFlyer] Failed to serialize Unity purchase data: %@", error); + return @{}; + } + + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + + const char *resultCStr = UnityPurchasesGetAdditionalParamsCallbackSK2([jsonString UTF8String], ""); + if (!resultCStr) { + NSLog(@"[AppsFlyer] Unity callback returned null"); + return @{}; + } + + NSString *resultJson = [NSString stringWithUTF8String:resultCStr]; + + NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error]; + + if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) { + NSLog(@"[AppsFlyer] Failed to parse Unity response: %@", error); + return @{}; + } + + return parsedResult; + } else { + NSLog(@"[AppsFlyer] SK2 - Unity callback is NOT registered"); + } + } else { + NSLog(@"[AppsFlyer] SK2 - iOS version not supported"); + } + return @{}; +} + +@end + + diff --git a/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm.meta b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm.meta new file mode 100644 index 0000000..3799161 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Plugins/iOS/AppsFlyeriOSWrapper.mm.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 2bff3788f3d8747fe9679bd3818e1d76 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime.meta new file mode 100644 index 0000000..3cb1ede --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf987ffd15f7b284b9c9748237652329 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs new file mode 100644 index 0000000..64d53de --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + public enum MediationNetwork : ulong + { + GoogleAdMob = 1, + IronSource = 2, + ApplovinMax = 3, + Fyber = 4, + Appodeal = 5, + Admost = 6, + Topon = 7, + Tradplus = 8, + Yandex = 9, + ChartBoost = 10, + Unity = 11, + ToponPte = 12, + Custom = 13, + DirectMonetization = 14 + } + + public static class AdRevenueScheme + { + /** + * code ISO 3166-1 format + */ + public const string COUNTRY = "country"; + + /** + * ID of the ad unit for the impression + */ + public const string AD_UNIT = "ad_unit"; + + /** + * Format of the ad + */ + public const string AD_TYPE = "ad_type"; + + /** + * ID of the ad placement for the impression + */ + public const string PLACEMENT = "placement"; + } + + /// + // Data class representing ad revenue information. + // + // @property monetizationNetwork The name of the network that monetized the ad. + // @property mediationNetwork An instance of MediationNetwork representing the mediation service used. + // @property currencyIso4217Code The ISO 4217 currency code describing the currency of the revenue. + // @property eventRevenue The amount of revenue generated by the ad. + /// + public class AFAdRevenueData + { + public string monetizationNetwork { get; private set; } + public MediationNetwork mediationNetwork { get; private set; } + public string currencyIso4217Code { get; private set; } + public double eventRevenue { get; private set; } + + public AFAdRevenueData(string monetization, MediationNetwork mediation, string currency, double revenue) + { + monetizationNetwork = monetization; + mediationNetwork = mediation; + currencyIso4217Code = currency; + eventRevenue = revenue; + } + } + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs.meta new file mode 100644 index 0000000..3106aae --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFAdRevenueData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49e1906ae949e4bfea400bd1da9f7e39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs new file mode 100644 index 0000000..1f6d1fe --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs @@ -0,0 +1,72 @@ +using UnityEngine; +using System.Collections; + +public class AFInAppEvents { + /** + * Event Type + * */ + public const string LEVEL_ACHIEVED = "af_level_achieved"; + public const string ADD_PAYMENT_INFO = "af_add_payment_info"; + public const string ADD_TO_CART = "af_add_to_cart"; + public const string ADD_TO_WISH_LIST = "af_add_to_wishlist"; + public const string COMPLETE_REGISTRATION = "af_complete_registration"; + public const string TUTORIAL_COMPLETION = "af_tutorial_completion"; + public const string INITIATED_CHECKOUT = "af_initiated_checkout"; + public const string PURCHASE = "af_purchase"; + public const string RATE = "af_rate"; + public const string SEARCH = "af_search"; + public const string SPENT_CREDIT = "af_spent_credits"; + public const string ACHIEVEMENT_UNLOCKED = "af_achievement_unlocked"; + public const string CONTENT_VIEW = "af_content_view"; + public const string TRAVEL_BOOKING = "af_travel_booking"; + public const string SHARE = "af_share"; + public const string INVITE = "af_invite"; + public const string LOGIN = "af_login"; + public const string RE_ENGAGE = "af_re_engage"; + public const string UPDATE = "af_update"; + public const string OPENED_FROM_PUSH_NOTIFICATION = "af_opened_from_push_notification"; + public const string LOCATION_CHANGED = "af_location_changed"; + public const string LOCATION_COORDINATES = "af_location_coordinates"; + public const string ORDER_ID = "af_order_id"; + /** + * Event Parameter Name + * **/ + public const string LEVEL = "af_level"; + public const string SCORE = "af_score"; + public const string SUCCESS = "af_success"; + public const string PRICE = "af_price"; + public const string CONTENT_TYPE = "af_content_type"; + public const string CONTENT_ID = "af_content_id"; + public const string CONTENT_LIST = "af_content_list"; + public const string CURRENCY = "af_currency"; + public const string QUANTITY = "af_quantity"; + public const string REGSITRATION_METHOD = "af_registration_method"; + public const string PAYMENT_INFO_AVAILIBLE = "af_payment_info_available"; + public const string MAX_RATING_VALUE = "af_max_rating_value"; + public const string RATING_VALUE = "af_rating_value"; + public const string SEARCH_STRING = "af_search_string"; + public const string DATE_A = "af_date_a"; + public const string DATE_B = "af_date_b"; + public const string DESTINATION_A = "af_destination_a"; + public const string DESTINATION_B = "af_destination_b"; + public const string DESCRIPTION = "af_description"; + public const string CLASS = "af_class"; + public const string EVENT_START = "af_event_start"; + public const string EVENT_END = "af_event_end"; + public const string LATITUDE = "af_lat"; + public const string LONGTITUDE = "af_long"; + public const string CUSTOMER_USER_ID = "af_customer_user_id"; + public const string VALIDATED = "af_validated"; + public const string REVENUE = "af_revenue"; + public const string RECEIPT_ID = "af_receipt_id"; + public const string PARAM_1 = "af_param_1"; + public const string PARAM_2 = "af_param_2"; + public const string PARAM_3 = "af_param_3"; + public const string PARAM_4 = "af_param_4"; + public const string PARAM_5 = "af_param_5"; + public const string PARAM_6 = "af_param_6"; + public const string PARAM_7 = "af_param_7"; + public const string PARAM_8 = "af_param_8"; + public const string PARAM_9 = "af_param_9"; + public const string PARAM_10 = "af_param_10"; +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs.meta new file mode 100644 index 0000000..b31364e --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFInAppEvents.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4075c6cf6f3d94b9a9f37f826e6a0e6f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs new file mode 100644 index 0000000..d02bf2f --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2013 Calvin Rien + * + * Based on the JSON parser by Patrick van Bergen + * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + * + * Simplified it so that it doesn't throw exceptions + * and can be used in Unity iPhone with maximum code stripping. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace AFMiniJSON { + // Example usage: + // + // using UnityEngine; + // using System.Collections; + // using System.Collections.Generic; + // using MiniJSON; + // + // public class MiniJSONTest : MonoBehaviour { + // void Start () { + // var jsonString = "{ \"array\": [1.44,2,3], " + + // "\"object\": {\"key1\":\"value1\", \"key2\":256}, " + + // "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " + + // "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " + + // "\"int\": 65536, " + + // "\"float\": 3.1415926, " + + // "\"bool\": true, " + + // "\"null\": null }"; + // + // var dict = Json.Deserialize(jsonString) as Dictionary; + // + // Debug.Log("deserialized: " + dict.GetType()); + // Debug.Log("dict['array'][0]: " + ((List) dict["array"])[0]); + // Debug.Log("dict['string']: " + (string) dict["string"]); + // Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles + // Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs + // Debug.Log("dict['unicode']: " + (string) dict["unicode"]); + // + // var str = Json.Serialize(dict); + // + // Debug.Log("serialized: " + str); + // } + // } + + /// + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary. + /// All numbers are parsed to doubles. + /// + public static class Json { + /// + /// Parses the string json into a value + /// + /// A JSON string. + /// An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false + public static object Deserialize(string json) { + // save the string for debug information + if (json == null) { + return null; + } + + return Parser.Parse(json); + } + + sealed class Parser : IDisposable { + const string WORD_BREAK = "{}[],:\""; + + public static bool IsWordBreak(char c) { + return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1; + } + + enum TOKEN { + NONE, + CURLY_OPEN, + CURLY_CLOSE, + SQUARED_OPEN, + SQUARED_CLOSE, + COLON, + COMMA, + STRING, + NUMBER, + TRUE, + FALSE, + NULL + }; + + StringReader json; + + Parser(string jsonString) { + json = new StringReader(jsonString); + } + + public static object Parse(string jsonString) { + using (var instance = new Parser(jsonString)) { + return instance.ParseValue(); + } + } + + public void Dispose() { + json.Dispose(); + json = null; + } + + Dictionary ParseObject() { + Dictionary table = new Dictionary(); + + // ditch opening brace + json.Read(); + + // { + while (true) { + switch (NextToken) { + case TOKEN.NONE: + return null; + case TOKEN.COMMA: + continue; + case TOKEN.CURLY_CLOSE: + return table; + default: + // name + string name = ParseString(); + if (name == null) { + return null; + } + + // : + if (NextToken != TOKEN.COLON) { + return null; + } + // ditch the colon + json.Read(); + + // value + table[name] = ParseValue(); + break; + } + } + } + + List ParseArray() { + List array = new List(); + + // ditch opening bracket + json.Read(); + + // [ + var parsing = true; + while (parsing) { + TOKEN nextToken = NextToken; + + switch (nextToken) { + case TOKEN.NONE: + return null; + case TOKEN.COMMA: + continue; + case TOKEN.SQUARED_CLOSE: + parsing = false; + break; + default: + object value = ParseByToken(nextToken); + + array.Add(value); + break; + } + } + + return array; + } + + object ParseValue() { + TOKEN nextToken = NextToken; + return ParseByToken(nextToken); + } + + object ParseByToken(TOKEN token) { + switch (token) { + case TOKEN.STRING: + return ParseString(); + case TOKEN.NUMBER: + return ParseNumber(); + case TOKEN.CURLY_OPEN: + return ParseObject(); + case TOKEN.SQUARED_OPEN: + return ParseArray(); + case TOKEN.TRUE: + return true; + case TOKEN.FALSE: + return false; + case TOKEN.NULL: + return null; + default: + return null; + } + } + + string ParseString() { + StringBuilder s = new StringBuilder(); + char c; + + // ditch opening quote + json.Read(); + + bool parsing = true; + while (parsing) { + + if (json.Peek() == -1) { + parsing = false; + break; + } + + c = NextChar; + switch (c) { + case '"': + parsing = false; + break; + case '\\': + if (json.Peek() == -1) { + parsing = false; + break; + } + + c = NextChar; + switch (c) { + case '"': + case '\\': + case '/': + s.Append(c); + break; + case 'b': + s.Append('\b'); + break; + case 'f': + s.Append('\f'); + break; + case 'n': + s.Append('\n'); + break; + case 'r': + s.Append('\r'); + break; + case 't': + s.Append('\t'); + break; + case 'u': + var hex = new char[4]; + + for (int i=0; i< 4; i++) { + hex[i] = NextChar; + } + + s.Append((char) Convert.ToInt32(new string(hex), 16)); + break; + } + break; + default: + s.Append(c); + break; + } + } + + return s.ToString(); + } + + object ParseNumber() { + string number = NextWord; + + if (number.IndexOf('.') == -1) { + long parsedInt; + Int64.TryParse(number, out parsedInt); + return parsedInt; + } + + double parsedDouble; + Double.TryParse(number, out parsedDouble); + return parsedDouble; + } + + void EatWhitespace() { + while (Char.IsWhiteSpace(PeekChar)) { + json.Read(); + + if (json.Peek() == -1) { + break; + } + } + } + + char PeekChar { + get { + return Convert.ToChar(json.Peek()); + } + } + + char NextChar { + get { + return Convert.ToChar(json.Read()); + } + } + + string NextWord { + get { + StringBuilder word = new StringBuilder(); + + while (!IsWordBreak(PeekChar)) { + word.Append(NextChar); + + if (json.Peek() == -1) { + break; + } + } + + return word.ToString(); + } + } + + TOKEN NextToken { + get { + EatWhitespace(); + + if (json.Peek() == -1) { + return TOKEN.NONE; + } + + switch (PeekChar) { + case '{': + return TOKEN.CURLY_OPEN; + case '}': + json.Read(); + return TOKEN.CURLY_CLOSE; + case '[': + return TOKEN.SQUARED_OPEN; + case ']': + json.Read(); + return TOKEN.SQUARED_CLOSE; + case ',': + json.Read(); + return TOKEN.COMMA; + case '"': + return TOKEN.STRING; + case ':': + return TOKEN.COLON; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TOKEN.NUMBER; + } + + switch (NextWord) { + case "false": + return TOKEN.FALSE; + case "true": + return TOKEN.TRUE; + case "null": + return TOKEN.NULL; + } + + return TOKEN.NONE; + } + } + } + + /// + /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string + /// + /// A Dictionary<string, object> / List<object> + /// A JSON encoded string, or null if object 'json' is not serializable + public static string Serialize(object obj) { + return Serializer.Serialize(obj); + } + + sealed class Serializer { + StringBuilder builder; + + Serializer() { + builder = new StringBuilder(); + } + + public static string Serialize(object obj) { + var instance = new Serializer(); + + instance.SerializeValue(obj); + + return instance.builder.ToString(); + } + + void SerializeValue(object value) { + IList asList; + IDictionary asDict; + string asStr; + + if (value == null) { + builder.Append("null"); + } else if ((asStr = value as string) != null) { + SerializeString(asStr); + } else if (value is bool) { + builder.Append((bool) value ? "true" : "false"); + } else if ((asList = value as IList) != null) { + SerializeArray(asList); + } else if ((asDict = value as IDictionary) != null) { + SerializeObject(asDict); + } else if (value is char) { + SerializeString(new string((char) value, 1)); + } else { + SerializeOther(value); + } + } + + void SerializeObject(IDictionary obj) { + bool first = true; + + builder.Append('{'); + + foreach (object e in obj.Keys) { + if (!first) { + builder.Append(','); + } + + SerializeString(e.ToString()); + builder.Append(':'); + + SerializeValue(obj[e]); + + first = false; + } + + builder.Append('}'); + } + + void SerializeArray(IList anArray) { + builder.Append('['); + + bool first = true; + + foreach (object obj in anArray) { + if (!first) { + builder.Append(','); + } + + SerializeValue(obj); + + first = false; + } + + builder.Append(']'); + } + + void SerializeString(string str) { + builder.Append('\"'); + + char[] charArray = str.ToCharArray(); + foreach (var c in charArray) { + switch (c) { + case '"': + builder.Append("\\\""); + break; + case '\\': + builder.Append("\\\\"); + break; + case '\b': + builder.Append("\\b"); + break; + case '\f': + builder.Append("\\f"); + break; + case '\n': + builder.Append("\\n"); + break; + case '\r': + builder.Append("\\r"); + break; + case '\t': + builder.Append("\\t"); + break; + default: + int codepoint = Convert.ToInt32(c); + if ((codepoint >= 32) && (codepoint <= 126)) { + builder.Append(c); + } else { + builder.Append("\\u"); + builder.Append(codepoint.ToString("x4")); + } + break; + } + } + + builder.Append('\"'); + } + + void SerializeOther(object value) { + // NOTE: decimals lose precision during serialization. + // They always have, I'm just letting you know. + // Previously floats and doubles lost precision too. + if (value is float) { + builder.Append(((float) value).ToString("R")); + } else if (value is int + || value is uint + || value is long + || value is sbyte + || value is byte + || value is short + || value is ushort + || value is ulong) { + builder.Append(value); + } else if (value is double + || value is decimal) { + builder.Append(Convert.ToDouble(value).ToString("R")); + } else { + SerializeString(value.ToString()); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs.meta new file mode 100644 index 0000000..11ec5c9 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFMiniJSON.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc3d1c806d507463e9b560eb09d8eb0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs new file mode 100644 index 0000000..d149885 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + public enum AFPurchaseType + { + Subscription = 0, + OneTimePurchase = 1 + } + + /// + /// Purchase details class matching Android SDK AFPurchaseDetails + /// + public class AFPurchaseDetailsAndroid + { + public AFPurchaseType purchaseType { get; private set; } + public string purchaseToken { get; private set; } + public string productId { get; private set; } + + public AFPurchaseDetailsAndroid(AFPurchaseType type, String purchaseToken, String productId) + { + this.purchaseType = type; + this.purchaseToken = purchaseToken; + this.productId = productId; + } + + } + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs.meta new file mode 100644 index 0000000..6d0024d --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFPurchaseDetailsAndroid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d71b3864006f94ac08938b2ebdc940bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs new file mode 100644 index 0000000..0dcde3a --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + /// + /// Purchase type enum matching iOS SDK AFSDKPurchaseType + /// + public enum AFSDKPurchaseType + { + Subscription, + OneTimePurchase + } + + /// + /// Purchase details class matching iOS SDK AFSDKPurchaseDetails + /// + public class AFSDKPurchaseDetailsIOS + { + public string productId { get; private set; } + public string transactionId { get; private set; } + public AFSDKPurchaseType purchaseType { get; private set; } + + private AFSDKPurchaseDetailsIOS(string productId, string transactionId, AFSDKPurchaseType purchaseType) + { + this.productId = productId; + this.transactionId = transactionId; + this.purchaseType = purchaseType; + } + + public static AFSDKPurchaseDetailsIOS Init(string productId, string transactionId, AFSDKPurchaseType purchaseType) + { + return new AFSDKPurchaseDetailsIOS(productId, transactionId, purchaseType); + } + } + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs.meta new file mode 100644 index 0000000..f33ebcc --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKPurchaseDetailsIOS.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44bb6c4472701416080eb050732075ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs new file mode 100644 index 0000000..e877fbd --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + public enum AFSDKValidateAndLogStatus + { + AFSDKValidateAndLogStatusSuccess, + AFSDKValidateAndLogStatusFailure, + AFSDKValidateAndLogStatusError + } + + + /// + // + /// + public class AFSDKValidateAndLogResult + { + public AFSDKValidateAndLogStatus status { get; private set; } + public Dictionary result { get; private set; } + public Dictionary errorData { get; private set; } + public string error { get; private set; } + + private AFSDKValidateAndLogResult(AFSDKValidateAndLogStatus status, Dictionary result, Dictionary errorData, string error) + { + this.status = status; + this.result = result; + this.errorData = errorData; + this.error = error; + } + + public static AFSDKValidateAndLogResult Init(AFSDKValidateAndLogStatus status, Dictionary result, Dictionary errorData, string error) + { + return new AFSDKValidateAndLogResult(status, result, errorData, error); + } + } + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs.meta new file mode 100644 index 0000000..63d4835 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AFSDKValidateAndLogResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2df1c6f1eab2e4849bf2762a8d78933f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef new file mode 100644 index 0000000..381ee00 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef @@ -0,0 +1,13 @@ +{ + "name": "AppsFlyer", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef.meta new file mode 100644 index 0000000..380f36a --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2a37df438292d4903b4e5159c5de3bf9 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs new file mode 100644 index 0000000..8259f5e --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs @@ -0,0 +1,1099 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace AppsFlyerSDK +{ + public class AppsFlyer : MonoBehaviour + { + public static readonly string kAppsFlyerPluginVersion = "6.17.72"; + public static string CallBackObjectName = null; + private static EventHandler onRequestResponse; + private static EventHandler onInAppResponse; + private static EventHandler onDeepLinkReceived; + public static IAppsFlyerNativeBridge instance = null; + public delegate void unityCallBack(string message); + + + /// + /// Initialize the AppsFlyer SDK with your devKey and appID. + /// The dev key is required on all platforms, and the appID is required for iOS. + /// If you app is for Android only pass null for the appID. + /// + /// AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard. + /// Your app's Apple ID. + /// + /// + /// AppsFlyer.initSDK("K2***********99", "41*****44""); + /// + /// + public static void initSDK(string devKey, string appID) + { + initSDK(devKey, appID, null); + } + + /// + /// Initialize the AppsFlyer SDK with your devKey and appID. + /// The dev key is required on all platforms, and the appID is required for iOS. + /// If you app is for Android only pass null for the appID. + /// + /// AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard. + /// Your app's Apple ID. + /// pass the script of the game object being used. + /// + /// + /// AppsFlyer.initSDK("K2***********99", 41*****44, this); + /// + /// + public static void initSDK(string devKey, string appID, MonoBehaviour gameObject) + { + + if (gameObject != null) + { +#if UNITY_STANDALONE_OSX + CallBackObjectName = gameObject.GetType().ToString(); +#else + CallBackObjectName = gameObject.name; +#endif + } + +#if UNITY_IOS || UNITY_STANDALONE_OSX + if (instance == null || !instance.isInit) + { + instance = new AppsFlyeriOS(devKey, appID, gameObject); + instance.isInit = true; + } +#elif UNITY_ANDROID + if (instance == null || !instance.isInit) + { + AppsFlyerAndroid appsFlyerAndroid = new AppsFlyerAndroid(); + appsFlyerAndroid.initSDK(devKey, gameObject); + instance = appsFlyerAndroid; + instance.isInit = true; + + } +#elif UNITY_WSA_10_0 + AppsFlyerWindows.InitSDK(devKey, appID, gameObject); + if (gameObject != null) + { + AppsFlyerWindows.GetConversionData(gameObject.name); + } +#else + +#endif + } + + + /// + /// Once this API is invoked, our SDK will start. + /// Once the API is called a sessions will be immediately sent, and all background forground transitions will send a session. + /// + public static void startSDK() + { +#if UNITY_WSA_10_0 + AppsFlyerWindows.Start(); + +#else + if (instance != null) + { + instance.startSDK(onRequestResponse != null, CallBackObjectName); + } +#endif + } + + + + + + + /// + /// Send an In-App Event. + /// In-App Events provide insight on what is happening in your app. + /// + /// Event Name as String. + /// Event Values as Dictionary. + public static void sendEvent(string eventName, Dictionary eventValues) + { +#if UNITY_WSA_10_0 && !UNITY_EDITOR + AppsFlyerWindows.LogEvent(eventName, eventValues); +#else + if (instance != null) + { + instance.sendEvent(eventName, eventValues, onInAppResponse != null, CallBackObjectName); + } +#endif + } + /// + /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning. + /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance. + /// This can be achieved with the stopSDK API. + /// + /// should sdk be stopped. + public static void stopSDK(bool isSDKStopped) + { + if (instance != null) + { + instance.stopSDK(isSDKStopped); + } + } + + // + /// Was the stopSDK(boolean) API set to true. + /// + /// boolean isSDKStopped. + public static bool isSDKStopped() + { + if (instance != null) + { + return instance.isSDKStopped(); + } + + return false; + } + + /// + /// Get the AppsFlyer SDK version used in app. + /// + /// The current SDK version. + public static string getSdkVersion() + { + if (instance != null) + { + return instance.getSdkVersion(); + } + + return ""; + + } + + /// + /// Enables Debug logs for the AppsFlyer SDK. + /// Should only be set to true in development / debug. + /// + /// shouldEnable boolean. + public static void setIsDebug(bool shouldEnable) + { + if (instance != null) + { + instance.setIsDebug(shouldEnable); + } else { +#if UNITY_IOS || UNITY_STANDALONE_OSX + instance = new AppsFlyeriOS(); + instance.setIsDebug(shouldEnable); +#elif UNITY_ANDROID + instance = new AppsFlyerAndroid(); + instance.setIsDebug(shouldEnable); +#else + +#endif + } + + } + + /// + /// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs. + /// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs. + /// + /// Customer ID for client. + public static void setCustomerUserId(string id) + { +#if UNITY_WSA_10_0 && !UNITY_EDITOR + AppsFlyerWindows.SetCustomerUserId(id); +#else + if (instance != null) + { + instance.setCustomerUserId(id); + } +#endif + } + + /// + /// Set the OneLink ID that should be used for User-Invite-API. + /// The link that is generated for the user invite will use this OneLink as the base link. + /// + /// OneLink ID obtained from the AppsFlyer Dashboard. + public static void setAppInviteOneLinkID(string oneLinkId) + { + + if (instance != null) + { + instance.setAppInviteOneLinkID(oneLinkId); + } + + + } + + /// + /// Set the deepLink timeout value that should be used for DDL. + /// + /// deepLink timeout in milliseconds. + public static void setDeepLinkTimeout(long deepLinkTimeout) + { + + if (instance != null) + { + instance.setDeepLinkTimeout(deepLinkTimeout); + } + + + } + + /// + /// Set additional data to be sent to AppsFlyer. + /// + /// additional data Dictionary. + public static void setAdditionalData(Dictionary customData) + { + + if (instance != null) + { + instance.setAdditionalData(customData); + } + + + } + + /// + /// Advertisers can wrap AppsFlyer OneLink within another Universal Link. + /// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer. + /// + /// Array of urls. + public static void setResolveDeepLinkURLs(params string[] urls) + { + + if (instance != null) + { + instance.setResolveDeepLinkURLs(urls); + } + + + } + + + /// + /// Advertisers can use this method to set vanity onelink domains. + /// + /// Array of domains. + public static void setOneLinkCustomDomain(params string[] domains) + { + + if (instance != null) + { + instance.setOneLinkCustomDomain(domains); + } + else + { +#if UNITY_IOS || UNITY_STANDALONE_OSX + instance = new AppsFlyeriOS(); +#elif UNITY_ANDROID + instance = new AppsFlyerAndroid(); +#else + +#endif + + + + } + } + + /// + /// Setting user local currency code for in-app purchases. + /// The currency code should be a 3 character ISO 4217 code. (default is USD). + /// You can set the currency code for all events by calling the following method. + /// + /// 3 character ISO 4217 code. + public static void setCurrencyCode(string currencyCode) + { + + if (instance != null) + { + instance.setCurrencyCode(currencyCode); + } else { +#if UNITY_IOS || UNITY_STANDALONE_OSX + instance = new AppsFlyeriOS(); + instance.setCurrencyCode(currencyCode); +#elif UNITY_ANDROID + instance = new AppsFlyerAndroid(); + instance.setCurrencyCode(currencyCode); +#else +#endif + } + } + + /// + /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application. + /// + /// instance of AppsFlyerConsent. + public static void setConsentData(AppsFlyerConsent appsFlyerConsent) + { + if (instance != null) + { + instance.setConsentData(appsFlyerConsent); + } + } + + /// + /// Logs ad revenue data along with additional parameters if provided. + /// + /// instance of AFAdRevenueData containing ad revenue information. + /// An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters. + public static void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary additionalParameters) + { + if (instance != null) + { + instance.logAdRevenue(adRevenueData, additionalParameters); + } + } + + /// + /// Manually record the location of the user. + /// + /// latitude as double. + /// longitude as double. + public static void recordLocation(double latitude, double longitude) + { + + if (instance != null) + { + instance.recordLocation(latitude, longitude); + } + + + } + + /// + /// Anonymize user Data. + /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions. + /// Default is false. + /// + /// shouldAnonymizeUser boolean. + public static void anonymizeUser(bool shouldAnonymizeUser) + { + + if (instance != null) + { + instance.anonymizeUser(shouldAnonymizeUser); + } + + + } + + /// + /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data. + /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it. + /// + /// should start TCF Data collection boolean. + public static void enableTCFDataCollection(bool shouldCollectTcfData) + { + if (instance != null) + { + instance.enableTCFDataCollection(shouldCollectTcfData); + } + } + + /// + /// Get AppsFlyer's unique device ID which is created for every new install of an app. + /// + /// AppsFlyer's unique device ID. + public static string getAppsFlyerId() + { +#if UNITY_WSA_10_0 && !UNITY_EDITOR + return AppsFlyerWindows.GetAppsFlyerId(); +#else + if (instance != null) + { + return instance.getAppsFlyerId(); + } +#endif + return string.Empty; + + } + + /// + /// Set a custom value for the minimum required time between sessions. + /// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions. + /// + /// minimum time between 2 separate sessions in seconds. + public static void setMinTimeBetweenSessions(int seconds) + { + + if (instance != null) + { + instance.setMinTimeBetweenSessions(seconds); + } + + + } + + /// + /// Set a custom host. + /// + /// Host prefix. + /// Host name. + public static void setHost(string hostPrefixName, string hostName) + { + + if (instance != null) + { + instance.setHost(hostPrefixName, hostName); + } else { +#if UNITY_IOS || UNITY_STANDALONE_OSX + instance = new AppsFlyeriOS(); + instance.setHost(hostPrefixName, hostName); +#elif UNITY_ANDROID + instance = new AppsFlyerAndroid(); + instance.setHost(hostPrefixName, hostName); +#else +#endif + } + } + + /// + /// Set the user emails and encrypt them. + /// cryptMethod Encryption method: + /// EmailCryptType.EmailCryptTypeMD5 + /// EmailCryptType.EmailCryptTypeSHA1 + /// EmailCryptType.EmailCryptTypeSHA256 + /// EmailCryptType.EmailCryptTypeNone + /// + /// Encryption method. + /// User emails. + public static void setUserEmails(EmailCryptType cryptType, params string[] userEmails) + { + + if (instance != null) + { + instance.setUserEmails(cryptType, userEmails); + } + + } + + public static void updateServerUninstallToken(string token) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.updateServerUninstallToken(token); + } + } + + /// + /// Set the user phone number. + /// + /// phoneNumber string + public static void setPhoneNumber(string phoneNumber) + { + + if (instance != null) + { + instance.setPhoneNumber(phoneNumber); + } + + } + + public static void setImeiData(string aImei) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setImeiData(aImei); + } + } + + /// + /// Used by advertisers to exclude all networks/integrated partners from getting data. + /// + [Obsolete("Please use setSharingFilterForPartners api")] + public static void setSharingFilterForAllPartners() + { + + if (instance != null) + { + instance.setSharingFilterForAllPartners(); + } + + + } + + public static void setAndroidIdData(string aAndroidId) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setAndroidIdData(aAndroidId); + } + } + + public static void waitForCustomerUserId(bool wait) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.waitForCustomerUserId(wait); + } + } + + /// + /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data. + /// + /// partners to exclude from getting data + [Obsolete("Please use setSharingFilterForPartners api")] + public static void setSharingFilter(params string[] partners) + { + + if (instance != null) + { + instance.setSharingFilter(partners); + } + + + } + + public static void setCustomerIdAndStartSDK(string id) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setCustomerIdAndStartSDK(id); + } + } + + /// + /// Lets you configure how which partners should the SDK exclude from data-sharing. + /// + /// partners to exclude from getting data + public static void setSharingFilterForPartners(params string[] partners) + { +#if UNITY_IOS || UNITY_STANDALONE_OSX + AppsFlyeriOS.setSharingFilterForPartners(partners); +#elif UNITY_ANDROID + AppsFlyerAndroid.setSharingFilterForPartners(partners); +#else + +#endif + } + + public static string getOutOfStore() + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + return appsFlyerAndroidInstance.getOutOfStore(); + } + return string.Empty; + } + + public static void setOutOfStore(string sourceName) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setOutOfStore(sourceName); + } + } + + /// + /// Register a Conversion Data Listener. + /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level. + /// By doing this you can serve users with personalized content or send them to specific activities within the app, + /// which can greatly enhance their engagement with your app. + /// + /// + /// + /// AppsFlyer.getConversionData(this.name); + /// + /// + public static void getConversionData(string objectName) + { +#if UNITY_WSA_10_0 && !UNITY_EDITOR + AppsFlyerWindows.GetConversionData(""); +#else + if (instance != null) + { + instance.getConversionData(objectName); + } +#endif + + } + + public static void setCollectAndroidID(bool isCollect) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setCollectAndroidID(isCollect); + } + } + + public static void setIsUpdate(bool isUpdate) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setIsUpdate(isUpdate); + } + } + + public static void setCollectIMEI(bool isCollect) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setCollectIMEI(isCollect); + } + } + + public static void setDisableCollectAppleAdSupport(bool disable) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setDisableCollectAppleAdSupport(disable); + } + } + + public static void setShouldCollectDeviceName(bool shouldCollectDeviceName) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setShouldCollectDeviceName(shouldCollectDeviceName); + } + } + + + /// + /// Use the following API to attribute the click and launch the app store's app page. + /// + /// promoted App ID + /// cross promotion campaign + /// additional user params + /// + /// + /// Dictionary parameters = new Dictionary(); + /// parameters.Add("af_sub1", "val"); + /// parameters.Add("custom_param", "val2"); + /// AppsFlyer.attributeAndOpenStore("123456789", "test campaign", parameters, this); + /// + /// + public static void attributeAndOpenStore(string appID, string campaign, Dictionary userParams, MonoBehaviour gameObject) + { + + if (instance != null) + { + instance.attributeAndOpenStore(appID, campaign, userParams, gameObject); + } + + } + + public static void setPreinstallAttribution(string mediaSource, string campaign, string siteId) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setPreinstallAttribution(mediaSource, campaign, siteId); + } + } + + public static void setDisableCollectIAd(bool disableCollectIAd) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setDisableCollectIAd(disableCollectIAd); + } + } + + public static bool isPreInstalledApp() + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + return appsFlyerAndroidInstance.isPreInstalledApp(); + } + return false; + } + + public static void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setUseReceiptValidationSandbox(useReceiptValidationSandbox); + } + } + + /// + /// To attribute an impression use the following API call. + /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard. + /// + /// promoted App ID. + /// cross promotion campaign. + /// parameters Dictionary. + public static void recordCrossPromoteImpression(string appID, string campaign, Dictionary parameters) + { + + if (instance != null) + { + instance.recordCrossPromoteImpression(appID, campaign, parameters); + } + + } + + public static void setUseUninstallSandbox(bool useUninstallSandbox) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setUseUninstallSandbox(useUninstallSandbox); + } + } + + public static string getAttributionId() + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + return appsFlyerAndroidInstance.getAttributionId(); + } + return string.Empty; + } + + public static void handlePushNotifications() + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.handlePushNotifications(); + } + } + + public static void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary additionalParameters, MonoBehaviour gameObject) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.validateAndSendInAppPurchase(productIdentifier, price, currency, transactionId, additionalParameters, gameObject); + } + } + + // V2 + public static void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.validateAndSendInAppPurchase(details, purchaseAdditionalDetails, gameObject); + } + } + + public static void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary additionalParameters, MonoBehaviour gameObject) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.validateAndSendInAppPurchase(publicKey, signature,purchaseData, price, currency, additionalParameters, gameObject); + } + } + + // V2 + public static void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.validateAndSendInAppPurchase(details, purchaseAdditionalDetails, gameObject); + } + } + + public static void handleOpenUrl(string url, string sourceApplication, string annotation) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.handleOpenUrl(url, sourceApplication, annotation); + } + } + + public static void registerUninstall(byte[] deviceToken) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.registerUninstall(deviceToken); + } + } + + public static void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.waitForATTUserAuthorizationWithTimeoutInterval(timeoutInterval); + } + } + + public static void setCurrentDeviceLanguage(string language) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.setCurrentDeviceLanguage(language); + } + } + + /// + /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click. + /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution- + /// + /// parameters Dictionary. + public static void generateUserInviteLink(Dictionary parameters, MonoBehaviour gameObject) + { + + if (instance != null) + { + instance.generateUserInviteLink(parameters, gameObject); + } + + } + + public static void disableSKAdNetwork(bool isDisabled) + { + if (instance != null && instance is IAppsFlyerIOSBridge) + { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.disableSKAdNetwork(isDisabled); + } else { +#if UNITY_IOS || UNITY_STANDALONE_OSX + instance = new AppsFlyeriOS(); + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.disableSKAdNetwork(isDisabled); +#else +#endif + } + } + + public static void setCollectOaid(bool isCollect) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setCollectOaid(isCollect); + } + } + + + /// + /// Use this method if you’re integrating your app with push providers + /// that don’t use the default push notification JSON schema the SDK expects. + /// See docs for more info. + /// + /// array of nested json path + public static void addPushNotificationDeepLinkPath(params string[] paths) + { + + if (instance != null) + { + instance.addPushNotificationDeepLinkPath(paths); + } + + } + + public static void setDisableAdvertisingIdentifiers(bool disable) + { + if (instance != null && instance is IAppsFlyerAndroidBridge) + { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setDisableAdvertisingIdentifiers(disable); + } + } + + /// + /// Subscribe for unified deeplink API. + /// This is called automatically from OnDeepLinkReceived. + /// CallBackObjectName is set in the init method. + /// + public static void subscribeForDeepLink() + { + + if (instance != null) + { + instance.subscribeForDeepLink(CallBackObjectName); + } + + } + + /// + /// Allows sending custom data for partner integration purposes. + /// partnerId : id of the partner + /// partnerInfo: customer data + /// + public static void setPartnerData(string partnerId, Dictionary partnerInfo) + { + if (instance != null) + { + instance.setPartnerData(partnerId, partnerInfo); + } + + } + + /// + /// Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device. + /// + public static void setDisableNetworkData(bool disable) { + if (instance != null && instance is IAppsFlyerAndroidBridge) { + IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance; + appsFlyerAndroidInstance.setDisableNetworkData(disable); + } + } + + + /// + /// Use to disable app vendor identifier (IDFV) collection, 'true' to disable. + /// + public static void disableIDFVCollection(bool isDisabled) + { +#if UNITY_IOS || UNITY_STANDALONE_OSX + if (instance == null) { + instance = new AppsFlyeriOS(); + } + if (instance != null && instance is IAppsFlyerIOSBridge) { + IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance; + appsFlyeriOSInstance.disableIDFVCollection(isDisabled); + } +#else +#endif + } + + /// + /// Start callback event. + /// + public static event EventHandler OnRequestResponse + { + add + { + onRequestResponse += value; + } + remove + { + onRequestResponse -= value; + } + } + + /// + /// In-App callback event. + /// + public static event EventHandler OnInAppResponse + { + add + { + onInAppResponse += value; + } + remove + { + onInAppResponse -= value; + } + } + + /// + /// Unified DeepLink Event + /// + public static event EventHandler OnDeepLinkReceived + { + add + { + onDeepLinkReceived += value; + subscribeForDeepLink(); + } + remove + { + onDeepLinkReceived -= value; + } + } + + /// + /// Used to accept start callback from UnitySendMessage on native side. + /// + public void inAppResponseReceived(string response) + { + if (onInAppResponse != null) + { + onInAppResponse.Invoke(null, parseRequestCallback(response)); + } + } + + /// + /// Used to accept in-app callback from UnitySendMessage on native side. + /// + public void requestResponseReceived(string response) + { + if (onRequestResponse != null) + { + onRequestResponse.Invoke(null, parseRequestCallback(response)); + } + } + + /// + /// Used to accept deeplink callback from UnitySendMessage on native side. + /// + public void onDeepLinking(string response) + { + + DeepLinkEventsArgs args = new DeepLinkEventsArgs(response); + + if (onDeepLinkReceived != null) + { + onDeepLinkReceived.Invoke(null, args); + } + } + + private static AppsFlyerRequestEventArgs parseRequestCallback(string response) + { + int responseCode = 0; + string errorDescription = ""; + + try + { + Dictionary dictionary = CallbackStringToDictionary(response); + var errorResponse = dictionary.ContainsKey("errorDescription") ? dictionary["errorDescription"] : ""; + errorDescription = (string)errorResponse; + responseCode = (int)(long) dictionary["statusCode"]; + } + catch (Exception e) + { + AFLog("parseRequestCallback", String.Format("{0} Exception caught.", e)); + } + + return new AppsFlyerRequestEventArgs(responseCode, errorDescription); + } + + /// + /// Helper method to convert json strings to dictionary. + /// + /// json string + /// dictionary representing the input json string. + public static Dictionary CallbackStringToDictionary(string str) + { + return AFMiniJSON.Json.Deserialize(str) as Dictionary; + } + + /// + /// Helper method to log AppsFlyer events and callbacks. + /// + /// method name + /// message to log + public static void AFLog(string methodName, string str) + { + Debug.Log(string.Format("AppsFlyer_Unity_v{0} {1} called with {2}", kAppsFlyerPluginVersion, methodName, str)); + } + } + + public enum EmailCryptType + { + // None + EmailCryptTypeNone = 0, + // SHA256 + EmailCryptTypeSHA256 = 1, + } + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs.meta new file mode 100644 index 0000000..48d98d5 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45161025a517d427381d3d06153a5ad3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs new file mode 100644 index 0000000..695b4a2 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs @@ -0,0 +1,851 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace AppsFlyerSDK +{ + +#if UNITY_ANDROID + public class AppsFlyerAndroid : IAppsFlyerAndroidBridge + { + public bool isInit { get; set; } + + private static AndroidJavaClass appsFlyerAndroid = new AndroidJavaClass("com.appsflyer.unity.AppsFlyerAndroidWrapper"); + + public AppsFlyerAndroid() { } + + /// + /// Use this method to init the sdk for the application. + /// Call this method before startSDK. + /// + /// AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard. + /// The current game object. This is used to get the conversion data callbacks. Pass null if you do not need the callbacks. + public void initSDK(string devkey, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("initSDK", devkey, gameObject ? gameObject.name : null); +#endif + } + + /// + /// Use this method to start the sdk for the application. + /// The AppsFlyer's Dev-Key must be provided. + /// + /// AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard. + public void startSDK(bool onRequestResponse, string CallBackObjectName) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("startTracking", onRequestResponse, CallBackObjectName); +#endif + } + + /// + /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning. + /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance. + /// This can be achieved with the stopSDK API. + /// + /// boolean should SDK be stopped. + public void stopSDK(bool isSDKStopped) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("stopTracking", isSDKStopped); +#endif + } + + /// + /// Get the AppsFlyer SDK version used in app. + /// + /// AppsFlyer SDK version. + public string getSdkVersion() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getSdkVersion"); +#else + return ""; +#endif + } + + /// + /// Manually pass the Firebase / GCM Device Token for Uninstall measurement. + /// + /// Firebase Device Token. + public void updateServerUninstallToken(string token) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("updateServerUninstallToken", token); +#endif + } + + /// + /// Enables Debug logs for the AppsFlyer SDK. + /// Should only be set to true in development / debug. + /// + /// shouldEnable boolean. + public void setIsDebug(bool shouldEnable) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setIsDebug", shouldEnable); +#endif + } + + /// + /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4) + /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS). + /// Use this API to explicitly send IMEI to AppsFlyer. + /// + /// device's IMEI. + public void setImeiData(string aImei) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setImeiData", aImei); +#endif + } + + /// + /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat(4.4) + /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS). + /// Use this API to explicitly send Android ID to AppsFlyer. + /// + /// device's Android ID. + public void setAndroidIdData(string aAndroidId) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setAndroidIdData", aAndroidId); +#endif + } + + /// + /// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs. + /// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs. + /// + /// Customer ID for client. + public void setCustomerUserId(string id) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCustomerUserId", id); +#endif + } + + /// + /// It is possible to delay the SDK Initialization until the customerUserID is set. + /// This feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided. + /// If this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided. + /// + /// wait boolean. + public void waitForCustomerUserId(bool wait) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("waitForCustomerUserId", wait); +#endif + } + + /// + /// Use this API to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal activity. + /// + /// Customer ID for client. + public void setCustomerIdAndStartSDK(string id) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCustomerIdAndTrack", id); +#endif + } + + /// + /// Get the current AF_STORE value. + /// + /// AF_Store value. + public string getOutOfStore() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getOutOfStore"); +#else + return ""; +#endif + } + + /// + /// Manually set the AF_STORE value. + /// + /// value to be set. + public void setOutOfStore(string sourceName) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setOutOfStore", sourceName); +#endif + } + + /// + /// Set the OneLink ID that should be used for User-Invites. + /// The link that is generated for the user invite will use this OneLink as the base link. + /// + /// OneLink ID obtained from the AppsFlyer Dashboard. + public void setAppInviteOneLinkID(string oneLinkId) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setAppInviteOneLinkID", oneLinkId); +#endif + } + + /// + /// Set additional data to be sent to AppsFlyer. + /// + /// additional data Dictionary. + public void setAdditionalData(Dictionary customData) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setAdditionalData", convertDictionaryToJavaMap(customData)); +#endif + } + + //// + /// Set the deepLink timeout value that should be used for DDL. + /// + /// deepLink timeout in milliseconds. + public void setDeepLinkTimeout(long deepLinkTimeout) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setDeepLinkTimeout", deepLinkTimeout); +#endif + } + + /// + /// Set the user emails. + /// + /// User emails. + public void setUserEmails(params string[] userEmails) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setUserEmails", (object)userEmails); +#endif + } + + + /// + /// Set the user phone number. + /// + /// User phoneNumber. + public void setPhoneNumber(string phoneNumber){ +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setPhoneNumber", phoneNumber); +#endif + } + + /// + /// Set the user emails and encrypt them. + /// cryptMethod Encryption method: + /// EmailCryptType.EmailCryptTypeMD5 + /// EmailCryptType.EmailCryptTypeSHA1 + /// EmailCryptType.EmailCryptTypeSHA256 + /// EmailCryptType.EmailCryptTypeNone + /// + /// Encryption method. + /// User emails. + public void setUserEmails(EmailCryptType cryptMethod, params string[] emails) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setUserEmails", getEmailType(cryptMethod), (object)emails); +#endif + } + + /// + /// Opt-out of collection of Android ID. + /// If the app does NOT contain Google Play Services, Android ID is collected by the SDK. + /// However, apps with Google play services should avoid Android ID collection as this is in violation of the Google Play policy. + /// + /// boolean, false to opt-out. + public void setCollectAndroidID(bool isCollect) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCollectAndroidID", isCollect); +#endif + } + + /// + /// Opt-out of collection of IMEI. + /// If the app does NOT contain Google Play Services, device IMEI is collected by the SDK. + /// However, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy. + /// + /// boolean, false to opt-out. + public void setCollectIMEI(bool isCollect) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCollectIMEI", isCollect); +#endif + } + + /// + /// Advertisers can wrap AppsFlyer OneLink within another Universal Link. + /// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer. + /// + /// Array of urls. + public void setResolveDeepLinkURLs(params string[] urls) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setResolveDeepLinkURLs", (object)urls); +#endif + } + + + /// + /// Advertisers can use this method to set vanity onelink domains. + /// + /// Array of domains. + public void setOneLinkCustomDomain(params string[] domains) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setOneLinkCustomDomain", (object)domains); +#endif + } + + /// + /// Manually set that the application was updated. + /// + /// isUpdate boolean value. + public void setIsUpdate(bool isUpdate) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setIsUpdate", isUpdate); +#endif + } + + /// + /// Setting user local currency code for in-app purchases. + /// The currency code should be a 3 character ISO 4217 code. (default is USD). + /// You can set the currency code for all events by calling the following method. + /// + /// 3 character ISO 4217 code. + public void setCurrencyCode(string currencyCode) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCurrencyCode", currencyCode); +#endif + } + + /// + /// Manually record the location of the user. + /// + /// latitude as double. + /// longitude as double. + public void recordLocation(double latitude, double longitude) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("trackLocation", latitude, longitude); +#endif + } + + /// + /// Send an In-App Event. + /// In-App Events provide insight on what is happening in your app. + /// + /// Event Name as String. + /// Event Values as Dictionary. + public void sendEvent(string eventName, Dictionary eventValues) + { + sendEvent(eventName, eventValues, false, AppsFlyer.CallBackObjectName); + } + + public void sendEvent(string eventName, Dictionary eventValues, bool shouldCallback, string callBackObjectName) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("trackEvent", eventName, convertDictionaryToJavaMap(eventValues), shouldCallback, callBackObjectName); +#endif + } + + /// + /// Anonymize user Data. + /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions. + /// Default is false. + /// + /// isDisabled boolean. + public void anonymizeUser(bool isDisabled) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setDeviceTrackingDisabled", isDisabled); +#endif + } + + /// + /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data. + /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it. + /// + /// should start TCF Data collection boolean. + public void enableTCFDataCollection(bool shouldCollectTcfData) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("enableTCFDataCollection", shouldCollectTcfData); +#endif + } + + /// + /// Enable the collection of Facebook Deferred AppLinks. + /// Requires Facebook SDK and Facebook app on target/client device. + /// This API must be invoked prior to initializing the AppsFlyer SDK in order to function properly. + /// + /// should Facebook's deferred app links be processed by the AppsFlyer SDK. + public void enableFacebookDeferredApplinks(bool isEnabled) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("enableFacebookDeferredApplinks", isEnabled); +#endif + } + + /// + /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application. + /// call this method when GDPR user is true + /// + /// hasConsentForDataUsage boolean. + /// hasConsentForAdsPersonalization boolean. + public void setConsentData(AppsFlyerConsent appsFlyerConsent) + { +#if !UNITY_EDITOR + string isUserSubjectToGDPR = appsFlyerConsent.isUserSubjectToGDPR?.ToString().ToLower() ?? "null"; + string hasConsentForDataUsage = appsFlyerConsent.hasConsentForDataUsage?.ToString().ToLower() ?? "null"; + string hasConsentForAdsPersonalization = appsFlyerConsent.hasConsentForAdsPersonalization?.ToString().ToLower() ?? "null"; + string hasConsentForAdStorage = appsFlyerConsent.hasConsentForAdStorage?.ToString().ToLower() ?? "null"; + + appsFlyerAndroid.CallStatic("setConsentData", isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization, hasConsentForAdStorage); +#endif + } + + /// + /// Logs ad revenue data along with additional parameters if provided. + /// instance of AFAdRevenueData containing ad revenue information. + /// An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters. + public void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary additionalParameters) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("logAdRevenue", adRevenueData.monetizationNetwork, getMediationNetwork(adRevenueData.mediationNetwork), adRevenueData.currencyIso4217Code, adRevenueData.eventRevenue, convertDictionaryToJavaMap(additionalParameters)); +#endif + } + + /// + /// Restrict reengagement via deep-link to once per each unique deep-link. + /// Otherwise deep re-occurring deep-links will be permitted for non-singleTask Activities and deep-linking via AppsFlyer deep-links. + /// The default value is false. + /// + /// doConsume boolean. + public void setConsumeAFDeepLinks(bool doConsume) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setConsumeAFDeepLinks", doConsume); +#endif + } + + /// + /// Specify the manufacturer or media source name to which the preinstall is attributed. + /// + /// Manufacturer or media source name for preinstall attribution. + /// Campaign name for preinstall attribution. + /// Site ID for preinstall attribution. + public void setPreinstallAttribution(string mediaSource, string campaign, string siteId) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setPreinstallAttribution", mediaSource, campaign, siteId); +#endif + } + + /// + /// Boolean indicator for preinstall by Manufacturer. + /// + /// boolean isPreInstalledApp. + public bool isPreInstalledApp() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("isPreInstalledApp"); +#else + return false; +#endif + } + + /// + /// Get the Facebook attribution ID, if one exists. + /// + /// string Facebook attribution ID. + public string getAttributionId() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getAttributionId"); +#else + return ""; +#endif + } + + /// + /// Get AppsFlyer's unique device ID is created for every new install of an app. + /// + /// AppsFlyer's unique device ID. + public string getAppsFlyerId() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getAppsFlyerId"); +#else + return ""; +#endif + } + + /// + /// API for server verification of in-app purchases. + /// An af_purchase event with the relevant values will be automatically sent if the validation is successful. + /// + /// License Key obtained from the Google Play Console. + /// data.INAPP_DATA_SIGNATURE from onActivityResult(int requestCode, int resultCode, Intent data) + /// data.INAPP_PURCHASE_DATA from onActivityResult(int requestCode, int resultCode, Intent data) + /// Purchase price, should be derived from skuDetails.getStringArrayList("DETAILS_LIST") + /// Purchase currency, should be derived from skuDetails.getStringArrayList("DETAILS_LIST") + /// additionalParameters Freehand parameters to be sent with the purchase (if validated). + public void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary additionalParameters, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("validateAndTrackInAppPurchase", publicKey, signature, purchaseData, price, currency, convertDictionaryToJavaMap(additionalParameters), gameObject ? gameObject.name : null); +#endif + } + + /// + /// API for server verification of in-app purchases. + /// An af_purchase event with the relevant values will be automatically sent if the validation is successful. + /// + /// AFPurchaseDetailsAndroid instance. + /// purchaseAdditionalDetails Freehand parameters to be sent with the purchase (if validated). + public void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("validateAndTrackInAppPurchaseV2", (int)details.purchaseType, details.purchaseToken, details.productId, convertDictionaryToJavaMap(purchaseAdditionalDetails), gameObject ? gameObject.name : null); +#endif + } + + /// + /// Was the stopSDK(boolean) API set to true. + /// + /// boolean isSDKStopped. + public bool isSDKStopped() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("isTrackingStopped"); +#else + return false; +#endif + } + + /// + /// Set a custom value for the minimum required time between sessions. + /// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions. + /// + /// minimum time between 2 separate sessions in seconds. + public void setMinTimeBetweenSessions(int seconds) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setMinTimeBetweenSessions", seconds); +#endif + } + + /// + /// Set a custom host. + /// + /// Host prefix. + /// Host name. + public void setHost(string hostPrefixName, string hostName) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setHost", hostPrefixName, hostName); +#endif + } + + /// + /// Get the host name. + /// Default value is "appsflyer.com". + /// + /// Host name. + public string getHostName() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getHostName"); +#else + return ""; +#endif + } + + /// + /// Get the custom host prefix. + /// + /// Host prefix. + public string getHostPrefix() + { +#if !UNITY_EDITOR + return appsFlyerAndroid.CallStatic("getHostPrefix"); +#else + return ""; +#endif + } + + /// + /// Used by advertisers to exclude all networks/integrated partners from getting data. + /// + public void setSharingFilterForAllPartners() + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setSharingFilterForAllPartners"); +#endif + } + + /// + /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data. + /// + /// partners to exclude from getting data + public void setSharingFilter(params string[] partners) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setSharingFilter", (object)partners); +#endif + } + + /// + /// Lets you configure how which partners should the SDK exclude from data-sharing. + /// + /// partners to exclude from getting data + public static void setSharingFilterForPartners(params string[] partners) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setSharingFilterForPartners", (object)partners); +#endif + } + + /// + /// Register a Conversion Data Listener. + /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level. + /// By doing this you can serve users with personalized content or send them to specific activities within the app, + /// which can greatly enhance their engagement with your app. + /// + public void getConversionData(string objectName) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("getConversionData", objectName); +#endif + } + + /// + /// Register a validation listener for the validateAndSendInAppPurchase API. + /// + public void initInAppPurchaseValidatorListener(MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("initInAppPurchaseValidatorListener", gameObject ? gameObject.name : null); +#endif + } + + /// + /// setCollectOaid + /// You must include the appsflyer oaid library for this api to work. + /// + /// isCollect oaid - set fasle to opt out + public void setCollectOaid(bool isCollect) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setCollectOaid", isCollect); +#endif + } + + /// + /// Use the following API to attribute the click and launch the app store's app page. + /// + /// promoted App ID + /// cross promotion campaign + /// additional user params + public void attributeAndOpenStore(string promoted_app_id, string campaign, Dictionary userParams, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("attributeAndOpenStore", promoted_app_id, campaign, convertDictionaryToJavaMap(userParams)); +#endif + } + + /// + /// To attribute an impression use the following API call. + /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard. + /// + /// promoted App ID. + /// cross promotion campaign. + /// parameters Dictionary. + public void recordCrossPromoteImpression(string appID, string campaign, Dictionary parameters) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("recordCrossPromoteImpression", appID, campaign, convertDictionaryToJavaMap(parameters)); +#endif + } + + /// + /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click. + /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution- + /// + /// parameters Dictionary. + public void generateUserInviteLink(Dictionary parameters, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("createOneLinkInviteListener", convertDictionaryToJavaMap(parameters), gameObject ? gameObject.name : null); +#endif + } + + /// + /// To measure push notifications as part of a retargeting campaign. + /// + public void handlePushNotifications(){ +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("handlePushNotifications"); +#endif + } + + /// + /// Use this method if you’re integrating your app with push providers + /// that don’t use the default push notification JSON schema the SDK expects. + /// See docs for more info. + /// + /// array of nested json path + public void addPushNotificationDeepLinkPath(params string[] paths) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("addPushNotificationDeepLinkPath", (object)paths); +#endif + } + + /// + /// subscribe to unified deep link callbacks + /// + public void subscribeForDeepLink(string objectName){ +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("subscribeForDeepLink", objectName); +#endif + } + + /// + /// Disables collection of various Advertising IDs by the SDK. This includes Google Advertising ID (GAID), OAID and Amazon Advertising ID (AAID) + /// + /// disable boolean. + public void setDisableAdvertisingIdentifiers(bool disable) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setDisableAdvertisingIdentifiers", disable); +#endif + } + + /// + /// Allows sending custom data for partner integration purposes. + /// + public void setPartnerData(string partnerId, Dictionary partnerInfo) + { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setPartnerData", partnerId, convertDictionaryToJavaMap(partnerInfo)); +#endif + } + + /// + /// Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device. + /// + public void setDisableNetworkData(bool disable) { +#if !UNITY_EDITOR + appsFlyerAndroid.CallStatic("setDisableNetworkData", disable); +#endif + } + + /// + /// Internal Helper Method. + /// + private static AndroidJavaObject getEmailType(EmailCryptType cryptType) + { + AndroidJavaClass emailsCryptTypeEnum = new AndroidJavaClass("com.appsflyer.AppsFlyerProperties$EmailsCryptType"); + AndroidJavaObject emailsCryptType; + + switch (cryptType) + { + case EmailCryptType.EmailCryptTypeSHA256: + emailsCryptType = emailsCryptTypeEnum.GetStatic("SHA256"); + break; + default: + emailsCryptType = emailsCryptTypeEnum.GetStatic("NONE"); + break; + } + + return emailsCryptType; + } + + /// + /// Internal Helper Method. + /// + private static AndroidJavaObject getMediationNetwork(MediationNetwork mediationNetwork) + { + AndroidJavaClass mediationNetworkEnumClass = new AndroidJavaClass("com.appsflyer.MediationNetwork"); + AndroidJavaObject mediationNetworkObject; + + switch (mediationNetwork) + { + case MediationNetwork.IronSource: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("IRONSOURCE"); + break; + case MediationNetwork.ApplovinMax: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("APPLOVIN_MAX"); + break; + case MediationNetwork.GoogleAdMob: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("GOOGLE_ADMOB"); + break; + case MediationNetwork.Fyber: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("FYBER"); + break; + case MediationNetwork.Appodeal: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("APPODEAL"); + break; + case MediationNetwork.Admost: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("ADMOST"); + break; + case MediationNetwork.Topon: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("TOPON"); + break; + case MediationNetwork.Tradplus: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("TRADPLUS"); + break; + case MediationNetwork.Yandex: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("YANDEX"); + break; + case MediationNetwork.ChartBoost: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("CHARTBOOST"); + break; + case MediationNetwork.Unity: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("UNITY"); + break; + case MediationNetwork.ToponPte: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("TOPON_PTE"); + break; + case MediationNetwork.Custom: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("CUSTOM_MEDIATION"); + break; + case MediationNetwork.DirectMonetization: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("DIRECT_MONETIZATION_NETWORK"); + break; + default: + mediationNetworkObject = mediationNetworkEnumClass.GetStatic("NONE"); + break; + } + return mediationNetworkObject; + } + + /// + /// Internal Helper Method. + /// + private static AndroidJavaObject convertDictionaryToJavaMap(Dictionary dictionary) + { + AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap"); + IntPtr putMethod = AndroidJNIHelper.GetMethodID(map.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + jvalue[] val; + if (dictionary != null) + { + foreach (var entry in dictionary) + { + val = AndroidJNIHelper.CreateJNIArgArray(new object[] { entry.Key, entry.Value }); + AndroidJNI.CallObjectMethod(map.GetRawObject(), putMethod,val); + AndroidJNI.DeleteLocalRef(val[0].l); + AndroidJNI.DeleteLocalRef(val[1].l); + } + } + + return map; + } + } +#endif + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs.meta new file mode 100644 index 0000000..d7ce722 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerAndroid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 172d18dd98e7e4ed3b30110568b0fae4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs new file mode 100644 index 0000000..feb448d --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + /// + // Data class representing a user's consent for data processing in accordance with GDPR and DMA + // (Digital Markets Act) compliance, specifically regarding advertising preferences. + + // This class should be used to notify and record the user's applicability + // under GDPR, their general consent to data usage, and their consent to personalized + // advertisements based on user data. + + /// ## Properties: + /// - `isUserSubjectToGDPR` (optional) - Indicates whether GDPR regulations apply to the user. + /// This may also serve as a general compliance flag for other regional regulations. + /// - `hasConsentForDataUsage` (optional) - Indicates whether the user consents to the processing + /// of their data for advertising purposes. + /// - `hasConsentForAdsPersonalization` (optional) - Indicates whether the user consents to the + /// use of their data for personalized advertising. + /// - `hasConsentForAdStorage` (optional) - Indicates whether the user consents to ad-related storage access. + /// + /// **Usage Example:** + /// ```csharp + /// var consent = new AppsFlyerConsent( + /// isUserSubjectToGDPR: true, + /// hasConsentForDataUsage: true, + /// hasConsentForAdsPersonalization: false, + /// hasConsentForAdStorage: true + /// ); + /// **Deprecated APIs:** + /// - `ForGDPRUser(...)` and `ForNonGDPRUser(...)` should no longer be used. + /// - Use `new AppsFlyerConsent(...)` instead with relevant consent fields. + /// + /// + public class AppsFlyerConsent + { + public bool? isUserSubjectToGDPR { get; private set; } + public bool? hasConsentForDataUsage { get; private set; } + public bool? hasConsentForAdsPersonalization { get; private set; } + public bool? hasConsentForAdStorage { get; private set; } + + public AppsFlyerConsent( bool? isUserSubjectToGDPR = null, bool? hasConsentForDataUsage = null, bool? hasConsentForAdsPersonalization = null, bool? hasConsentForAdStorage = null) + { + this.isUserSubjectToGDPR = isUserSubjectToGDPR; + this.hasConsentForDataUsage = hasConsentForDataUsage; + this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization; + this.hasConsentForAdStorage = hasConsentForAdStorage; + } + + [Obsolete("Use the new constructor with optional booleans instead.")] + private AppsFlyerConsent(bool isGDPR, bool hasForDataUsage, bool hasForAdsPersonalization) + { + isUserSubjectToGDPR = isGDPR; + hasConsentForDataUsage = hasForDataUsage; + hasConsentForAdsPersonalization = hasForAdsPersonalization; + } + + [Obsolete("Use new AppsFlyerConsent(...) instead.")] + public static AppsFlyerConsent ForGDPRUser(bool hasConsentForDataUsage, bool hasConsentForAdsPersonalization) + { + return new AppsFlyerConsent(true, hasConsentForDataUsage, hasConsentForAdsPersonalization); + } + + [Obsolete("Use new AppsFlyerConsent(...) instead.")] + public static AppsFlyerConsent ForNonGDPRUser() + { + return new AppsFlyerConsent(false); + } + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs.meta new file mode 100644 index 0000000..5a881de --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerConsent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a97c986fe4ee0461badf7042e08db3f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs new file mode 100644 index 0000000..511db67 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; + +namespace AppsFlyerSDK +{ + + /// + /// Event args for AppsFlyer requests. + /// Used for sessions and in-app events. + /// Used to handle post request logic. + /// + /// Examples: + /// statusCode / errorDescription + /// + /// 200 - null + /// + /// 10 - "Event timeout. Check 'minTimeBetweenSessions' param" + /// 11 - "Skipping event because 'isStopTracking' enabled" + /// 40 - Network error: Error description comes from Android + /// 41 - "No dev key" + /// 50 - "Status code failure" + actual response code from the server + /// + /// + public class AppsFlyerRequestEventArgs : EventArgs + { + public AppsFlyerRequestEventArgs(int code, string description) + { + statusCode = code; + errorDescription = description; + } + + public int statusCode { get; } + public string errorDescription { get; } + } + + /// + /// Event args for OnDeepLinkReceived. + /// Used to handle deep linking results. + /// + public class DeepLinkEventsArgs : EventArgs + { + + /// + /// DeepLink dictionary to get additional parameters + /// + public Dictionary deepLink; + + /// + /// DeepLink status: FOUND, NOT_FOUND, ERROR + /// + public DeepLinkStatus status { get; } + + /// + /// DeepLink error: TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED + /// + public DeepLinkError error { get; } + + public string getMatchType() + { + return getDeepLinkParameter("match_type"); + } + + public string getDeepLinkValue() + { + return getDeepLinkParameter("deep_link_value"); + } + + public string getClickHttpReferrer() + { + return getDeepLinkParameter("click_http_referrer"); + } + + public string getMediaSource() + { + return getDeepLinkParameter("media_source"); + } + + public string getCampaign() + { + return getDeepLinkParameter("campaign"); + } + + public string getCampaignId() + { + return getDeepLinkParameter("campaign_id"); + } + + public string getAfSub1() + { + return getDeepLinkParameter("af_sub1"); + } + + public string getAfSub2() + { + return getDeepLinkParameter("af_sub2"); + } + + public string getAfSub3() + { + return getDeepLinkParameter("af_sub3"); + } + + public string getAfSub4() + { + return getDeepLinkParameter("af_sub4"); + } + + public string getAfSub5() + { + return getDeepLinkParameter("af_sub5"); + } + + public bool isDeferred() + { + if (deepLink != null && deepLink.ContainsKey("is_deferred")) + { + try + { + return (bool)deepLink["is_deferred"]; + } + catch (Exception e) + { + AppsFlyer.AFLog("DeepLinkEventsArgs.isDeferred", String.Format("{0} Exception caught.", e)); + } + } + return false; + } + + public Dictionary getDeepLinkDictionary() + { + return deepLink; + } + + public DeepLinkEventsArgs(string str) + { + try + { + Dictionary dictionary = AppsFlyer.CallbackStringToDictionary(str); + + string status = ""; + string error = ""; + + + if (dictionary.ContainsKey("status") && dictionary["status"] != null) + { + status = dictionary["status"].ToString(); + } + + if (dictionary.ContainsKey("error") && dictionary["error"] != null) + { + error = dictionary["error"].ToString(); + } + + if (dictionary.ContainsKey("deepLink") && dictionary["deepLink"] != null) + { + this.deepLink = AppsFlyer.CallbackStringToDictionary(dictionary["deepLink"].ToString()); + } + if (dictionary.ContainsKey("is_deferred")) + { + this.deepLink["is_deferred"] = dictionary["is_deferred"]; + } + + switch (status) + { + case "FOUND": + this.status = DeepLinkStatus.FOUND; + break; + case "NOT_FOUND": + this.status = DeepLinkStatus.NOT_FOUND; + break; + default: + this.status = DeepLinkStatus.ERROR; + break; + } + + switch (error) + { + case "TIMEOUT": + this.error = DeepLinkError.TIMEOUT; + break; + case "NETWORK": + this.error = DeepLinkError.NETWORK; + break; + case "HTTP_STATUS_CODE": + this.error = DeepLinkError.HTTP_STATUS_CODE; + break; + default: + this.error = DeepLinkError.UNEXPECTED; + break; + } + + } + catch (Exception e) + { + AppsFlyer.AFLog("DeepLinkEventsArgs.parseDeepLink", String.Format("{0} Exception caught.", e)); + } + } + + private string getDeepLinkParameter(string name) + { + if (deepLink != null && deepLink.ContainsKey(name) && deepLink[name] != null) + { + return deepLink[name].ToString(); + } + + return null; + } + + } + + public enum DeepLinkStatus { + FOUND, NOT_FOUND, ERROR + } + + public enum DeepLinkError { + TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED + } +} diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs.meta new file mode 100644 index 0000000..056bce2 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0fc241ad5a9b43a7b461a6147dbc74c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab new file mode 100644 index 0000000..f3bbb45 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab @@ -0,0 +1,49 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7315102894599890749 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6207133488976360133} + - component: {fileID: 4405976200006927252} + m_Layer: 0 + m_Name: AppsFlyerObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6207133488976360133 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7315102894599890749} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4405976200006927252 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7315102894599890749} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a2ec6ba1ee8b48749524f015ed572a6, type: 3} + m_Name: + m_EditorClassIdentifier: + devKey: + appID: + isDebug: 0 + getConversionData: 0 diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab.meta new file mode 100644 index 0000000..1acd1cf --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObject.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0bfe3b149145747cc92dc53bb4df4e9b +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs new file mode 100644 index 0000000..266a848 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs @@ -0,0 +1,70 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using AppsFlyerSDK; + +// This class is intended to be used the the AppsFlyerObject.prefab + +public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData +{ + + // These fields are set from the editor so do not modify! + //******************************// + public string devKey; + public string appID; + public string UWPAppID; + public string macOSAppID; + public bool isDebug; + public bool getConversionData; + //******************************// + + + void Start() + { + // These fields are set from the editor so do not modify! + //******************************// + AppsFlyer.setIsDebug(isDebug); +#if UNITY_WSA_10_0 && !UNITY_EDITOR + AppsFlyer.initSDK(devKey, UWPAppID, getConversionData ? this : null); +#elif UNITY_STANDALONE_OSX && !UNITY_EDITOR + AppsFlyer.initSDK(devKey, macOSAppID, getConversionData ? this : null); +#else + AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null); +#endif + //******************************/ + + AppsFlyer.startSDK(); + } + + + void Update() + { + + } + + // Mark AppsFlyer CallBacks + public void onConversionDataSuccess(string conversionData) + { + AppsFlyer.AFLog("didReceiveConversionData", conversionData); + Dictionary conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData); + // add deferred deeplink logic here + } + + public void onConversionDataFail(string error) + { + AppsFlyer.AFLog("didReceiveConversionDataWithError", error); + } + + public void onAppOpenAttribution(string attributionData) + { + AppsFlyer.AFLog("onAppOpenAttribution", attributionData); + Dictionary attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData); + // add direct deeplink logic here + } + + public void onAppOpenAttributionFailure(string error) + { + AppsFlyer.AFLog("onAppOpenAttributionFailure", error); + } + +} diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs.meta new file mode 100644 index 0000000..65ccedc --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerObjectScript.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a2ec6ba1ee8b48749524f015ed572a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs new file mode 100644 index 0000000..ee43009 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs @@ -0,0 +1,426 @@ +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; +using System; + +namespace AppsFlyerSDK +{ + + public interface IAppsFlyerPurchaseRevenueDataSource + { + Dictionary PurchaseRevenueAdditionalParametersForProducts(HashSet products, HashSet transactions); + } + + public interface IAppsFlyerPurchaseRevenueDataSourceStoreKit2 + { + Dictionary PurchaseRevenueAdditionalParametersStoreKit2ForProducts(HashSet products, HashSet transactions); + } + + public class AppsFlyerPurchaseRevenueBridge : MonoBehaviour + { + #if UNITY_IOS && !UNITY_EDITOR +[DllImport("__Internal")] +private static extern void RegisterUnityPurchaseRevenueParamsCallback(Func callback); + +[DllImport("__Internal")] +private static extern void RegisterUnityPurchaseRevenueParamsCallbackSK2(Func callback); +#endif + + private static IAppsFlyerPurchaseRevenueDataSource _dataSource; + private static IAppsFlyerPurchaseRevenueDataSourceStoreKit2 _dataSourceSK2; + + public static void RegisterDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource) + { + _dataSource = dataSource; + #if UNITY_IOS && !UNITY_EDITOR + RegisterUnityPurchaseRevenueParamsCallback(GetAdditionalParameters); + #elif UNITY_ANDROID && !UNITY_EDITOR + using (AndroidJavaClass jc = new AndroidJavaClass("com.appsflyer.unity.PurchaseRevenueBridge")) + { + jc.CallStatic("setUnityBridge", new UnityPurchaseRevenueBridgeProxy()); + } + #endif + } + + public static void RegisterDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSource) + { + #if UNITY_IOS && !UNITY_EDITOR + _dataSourceSK2 = dataSource; + RegisterUnityPurchaseRevenueParamsCallbackSK2(GetAdditionalParametersSK2); + #endif + } + + public static Dictionary GetAdditionalParametersForAndroid(HashSet products, HashSet transactions) + { + return _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions) + ?? new Dictionary(); + } + + #if UNITY_IOS && !UNITY_EDITOR + [AOT.MonoPInvokeCallback(typeof(Func))] + public static string GetAdditionalParameters(string productsJson, string transactionsJson) + { + try + { + HashSet products = new HashSet(); + HashSet transactions = new HashSet(); + + if (!string.IsNullOrEmpty(productsJson)) + { + var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary; + if (dict != null) + { + if (dict.TryGetValue("products", out var productsObj) && productsObj is List productList) + products = new HashSet(productList); + + if (dict.TryGetValue("transactions", out var transactionsObj) && transactionsObj is List transactionList) + transactions = new HashSet(transactionList); + } + } + + var parameters = _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions) + ?? new Dictionary(); + return AFMiniJSON.Json.Serialize(parameters); + } + catch (Exception e) + { + Debug.LogError($"[AppsFlyer] Exception in GetAdditionalParameters: {e}"); + return "{}"; + } + } + #endif + + #if UNITY_IOS && !UNITY_EDITOR + [AOT.MonoPInvokeCallback(typeof(Func))] + public static string GetAdditionalParametersSK2(string productsJson, string transactionsJson) + { + try + { + HashSet products = new HashSet(); + HashSet transactions = new HashSet(); + + if (!string.IsNullOrEmpty(productsJson)) + { + var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary; + if (dict != null && dict.TryGetValue("products", out var productsObj) && productsObj is List productList) + products = new HashSet(productList); + } + if (!string.IsNullOrEmpty(transactionsJson)) + { + var dict = AFMiniJSON.Json.Deserialize(transactionsJson) as Dictionary; + if (dict != null && dict.TryGetValue("transactions", out var transactionsObj) && transactionsObj is List transactionList) + transactions = new HashSet(transactionList); + } + + var parameters = _dataSourceSK2?.PurchaseRevenueAdditionalParametersStoreKit2ForProducts(products, transactions) + ?? new Dictionary(); + return AFMiniJSON.Json.Serialize(parameters); + } + catch (Exception e) + { + Debug.LogError($"[AppsFlyer] Exception in GetAdditionalParametersSK2: {e}"); + return "{}"; + } + } + #endif + } + + public class UnityPurchaseRevenueBridgeProxy : AndroidJavaProxy + { + public UnityPurchaseRevenueBridgeProxy() : base("com.appsflyer.unity.PurchaseRevenueBridge$UnityPurchaseRevenueBridge") { } + + public string getAdditionalParameters(string productsJson, string transactionsJson) + { + try + { + // Create empty sets if JSON is null or empty + HashSet products = new HashSet(); + HashSet transactions = new HashSet(); + + // Only try to parse if we have valid JSON + if (!string.IsNullOrEmpty(productsJson)) + { + try + { + // First try to parse as a simple array + var parsedProducts = AFMiniJSON.Json.Deserialize(productsJson); + if (parsedProducts is List productList) + { + products = new HashSet(productList); + } + else if (parsedProducts is Dictionary dict) + { + if (dict.ContainsKey("events") && dict["events"] is List eventsList) + { + products = new HashSet(eventsList); + } + else + { + // If it's a dictionary but doesn't have events, add the whole dict + products.Add(dict); + } + } + } + catch (Exception e) + { + Debug.LogError($"Error parsing products JSON: {e.Message}\nJSON: {productsJson}"); + } + } + + if (!string.IsNullOrEmpty(transactionsJson)) + { + try + { + // First try to parse as a simple array + var parsedTransactions = AFMiniJSON.Json.Deserialize(transactionsJson); + if (parsedTransactions is List transactionList) + { + transactions = new HashSet(transactionList); + } + else if (parsedTransactions is Dictionary dict) + { + if (dict.ContainsKey("events") && dict["events"] is List eventsList) + { + transactions = new HashSet(eventsList); + } + else + { + // If it's a dictionary but doesn't have events, add the whole dict + transactions.Add(dict); + } + } + } + catch (Exception e) + { + Debug.LogError($"Error parsing transactions JSON: {e.Message}\nJSON: {transactionsJson}"); + } + } + + var parameters = AppsFlyerPurchaseRevenueBridge.GetAdditionalParametersForAndroid(products, transactions); + return AFMiniJSON.Json.Serialize(parameters); + } + catch (Exception e) + { + Debug.LogError($"Error in getAdditionalParameters: {e.Message}\nProducts JSON: {productsJson}\nTransactions JSON: {transactionsJson}"); + return "{}"; + } + } + } + + + public class AppsFlyerPurchaseConnector : MonoBehaviour { + + private static AppsFlyerPurchaseConnector instance; + private Dictionary pendingParameters; + private Action> pendingCallback; + + public static AppsFlyerPurchaseConnector Instance + { + get + { + if (instance == null) + { + GameObject go = new GameObject("AppsFlyerPurchaseConnector"); + instance = go.AddComponent(); + DontDestroyOnLoad(go); + } + return instance; + } + } + + private void Awake() + { + if (instance == null) + { + instance = this; + DontDestroyOnLoad(gameObject); + } + else + { + Destroy(gameObject); + } + } + +#if UNITY_ANDROID && !UNITY_EDITOR + private static AndroidJavaClass appsFlyerAndroidConnector = new AndroidJavaClass("com.appsflyer.unity.AppsFlyerAndroidWrapper"); +#endif + + public static void init(MonoBehaviour unityObject, Store s) { +#if UNITY_IOS && !UNITY_EDITOR + _initPurchaseConnector(unityObject.name); +#elif UNITY_ANDROID && !UNITY_EDITOR + int store = mapStoreToInt(s); + appsFlyerAndroidConnector.CallStatic("initPurchaseConnector", unityObject ? unityObject.name : null, store); +#endif + } + + public static void build() { +#if UNITY_IOS && !UNITY_EDITOR + //not for iOS +#elif UNITY_ANDROID && !UNITY_EDITOR + appsFlyerAndroidConnector.CallStatic("build"); + +#else +#endif + } + + public static void startObservingTransactions() { +#if UNITY_IOS && !UNITY_EDITOR + _startObservingTransactions(); +#elif UNITY_ANDROID && !UNITY_EDITOR + appsFlyerAndroidConnector.CallStatic("startObservingTransactions"); +#else +#endif + } + + public static void stopObservingTransactions() { +#if UNITY_IOS && !UNITY_EDITOR + _stopObservingTransactions(); +#elif UNITY_ANDROID && !UNITY_EDITOR + appsFlyerAndroidConnector.CallStatic("stopObservingTransactions"); +#else +#endif + } + + public static void setIsSandbox(bool isSandbox) { +#if UNITY_IOS && !UNITY_EDITOR + _setIsSandbox(isSandbox); +#elif UNITY_ANDROID && !UNITY_EDITOR + appsFlyerAndroidConnector.CallStatic("setIsSandbox", isSandbox); +#else +#endif + } + + public static void setPurchaseRevenueValidationListeners(bool enableCallbacks) { +#if UNITY_IOS && !UNITY_EDITOR + _setPurchaseRevenueDelegate(); +#elif UNITY_ANDROID && !UNITY_EDITOR + appsFlyerAndroidConnector.CallStatic("setPurchaseRevenueValidationListeners", enableCallbacks); +#else +#endif + } + + public static void setAutoLogPurchaseRevenue(params AppsFlyerAutoLogPurchaseRevenueOptions[] autoLogPurchaseRevenueOptions) { +#if UNITY_IOS && !UNITY_EDITOR + int option = 0; + foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) { + option = option | (int)op; + } + _setAutoLogPurchaseRevenue(option); +#elif UNITY_ANDROID && !UNITY_EDITOR + if (autoLogPurchaseRevenueOptions.Length == 0) { + return; + } + foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) { + switch(op) { + case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsDisabled: + break; + case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions: + appsFlyerAndroidConnector.CallStatic("setAutoLogSubscriptions", true); + break; + case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases: + appsFlyerAndroidConnector.CallStatic("setAutoLogInApps", true); + break; + default: + break; + } + } +#else +#endif + } + + public static void setPurchaseRevenueDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource) + { +#if UNITY_IOS && !UNITY_EDITOR + + if (dataSource != null) + { + _setPurchaseRevenueDataSource(dataSource.GetType().Name); + AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource); + } +#elif UNITY_ANDROID && !UNITY_EDITOR + if (dataSource != null) + { + AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource); + } +#endif + } + + + public static void setPurchaseRevenueDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSourceSK2) + { +#if UNITY_IOS && !UNITY_EDITOR + if (dataSourceSK2 != null) + { + AppsFlyerPurchaseRevenueBridge.RegisterDataSourceStoreKit2(dataSourceSK2); + _setPurchaseRevenueDataSource("AppsFlyerObjectScript_StoreKit2"); + } +#endif + } + + + private static int mapStoreToInt(Store s) { + switch(s) { + case(Store.GOOGLE): + return 0; + default: + return -1; + } + } + + public static void setStoreKitVersion(StoreKitVersion storeKitVersion) { +#if UNITY_IOS && !UNITY_EDITOR + _setStoreKitVersion((int)storeKitVersion); +#elif UNITY_ANDROID && !UNITY_EDITOR + // Android doesn't use StoreKit +#else +#endif + } + + public static void logConsumableTransaction(string transactionJson) { +#if UNITY_IOS && !UNITY_EDITOR + _logConsumableTransaction(transactionJson); +#elif UNITY_ANDROID && !UNITY_EDITOR + // Android doesn't use StoreKit +#else +#endif + } + +#if UNITY_IOS && !UNITY_EDITOR + + [DllImport("__Internal")] + private static extern void _startObservingTransactions(); + [DllImport("__Internal")] + private static extern void _stopObservingTransactions(); + [DllImport("__Internal")] + private static extern void _setIsSandbox(bool isSandbox); + [DllImport("__Internal")] + private static extern void _setPurchaseRevenueDelegate(); + [DllImport("__Internal")] + private static extern void _setPurchaseRevenueDataSource(string dataSourceName); + [DllImport("__Internal")] + private static extern void _setAutoLogPurchaseRevenue(int option); + [DllImport("__Internal")] + private static extern void _initPurchaseConnector(string objectName); + [DllImport("__Internal")] + private static extern void _setStoreKitVersion(int storeKitVersion); + [DllImport("__Internal")] + private static extern void _logConsumableTransaction(string transactionJson); + +#endif + } + public enum Store { + GOOGLE = 0 + } + public enum AppsFlyerAutoLogPurchaseRevenueOptions + { + AppsFlyerAutoLogPurchaseRevenueOptionsDisabled = 0, + AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions = 1 << 0, + AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases = 1 << 1 + } + + public enum StoreKitVersion { + SK1 = 0, + SK2 = 1 + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs.meta new file mode 100644 index 0000000..dd85a75 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyerPurchaseConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0636ea07d370d437183f3762280c08ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs new file mode 100644 index 0000000..a9fd93b --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs @@ -0,0 +1,1021 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; +using System.Reflection; + + + +namespace AppsFlyerSDK +{ + +#if UNITY_IOS || UNITY_STANDALONE_OSX + + public class AppsFlyeriOS: IAppsFlyerIOSBridge + { + public bool isInit { get; set; } + + public AppsFlyeriOS() { } + + public AppsFlyeriOS(string devKey, string appID, MonoBehaviour gameObject) + { + setAppsFlyerDevKey(devKey); + setAppleAppID(appID); + if (gameObject != null) + { +#if UNITY_IOS + getConversionData(gameObject.name); +#elif UNITY_STANDALONE_OSX + getConversionData(gameObject.GetType().ToString()); +#endif + } + } + + + + /// + /// Start Session. + /// This will record a session and then record all background forground sessions during the lifecycle of the app. + /// +public void startSDK(bool shouldCallback, string CallBackObjectName) + { +#if UNITY_STANDALONE_OSX && !UNITY_EDITOR + _startSDK(shouldCallback, CallBackObjectName, getCallback); +#elif UNITY_IOS && !UNITY_EDITOR + _startSDK(shouldCallback, CallBackObjectName); +#endif + } + + /// + /// Send an In-App Event. + /// In-App Events provide insight on what is happening in your app. + /// + /// Name of event. + /// Contains dictionary of values for handling by backend. + public void sendEvent(string eventName, Dictionary eventValues) + { + sendEvent(eventName, eventValues, false, AppsFlyer.CallBackObjectName); + } + + public void sendEvent(string eventName, Dictionary eventValues, bool shouldCallback, string callBackObjectName) + { +#if !UNITY_EDITOR + _afSendEvent(eventName, AFMiniJSON.Json.Serialize(eventValues), shouldCallback, callBackObjectName); +#endif + } + + /// + /// Get the conversion data. + /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level. + /// By doing this you can serve users with personalized content or send them to specific activities within the app, + /// which can greatly enhance their engagement with your app. + /// + public void getConversionData(string objectName) + { +#if !UNITY_EDITOR + _getConversionData(objectName); +#endif + } + + /// + /// In case you use your own user ID in your app, you can set this property to that ID. + /// Enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs. + /// + /// Customer ID for client. + public void setCustomerUserId(string customerUserID) + { +#if !UNITY_EDITOR + _setCustomerUserID(customerUserID); +#endif + } + + /// + /// In case you use custom data and you want to receive it in the raw reports. + /// see [Setting additional custom data] (https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS#setting-additional-custom-data) for more information. + /// + /// additional data Dictionary. + public void setAdditionalData(Dictionary customData) + { +#if !UNITY_EDITOR + _setAdditionalData(AFMiniJSON.Json.Serialize(customData)); +#endif + } + + /// + /// Use this method to set your AppsFlyer's dev key. + /// + /// AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard. + public void setAppsFlyerDevKey(string appsFlyerDevKey) + { +#if !UNITY_EDITOR + _setAppsFlyerDevKey(appsFlyerDevKey); +#endif + } + + /// + /// Use this method to set your app's Apple ID(taken from the app's page on iTunes Connect). + /// + /// your app's Apple ID. + public void setAppleAppID(string appleAppID) + { +#if !UNITY_EDITOR + _setAppleAppID(appleAppID); +#endif + } + + /// + /// Setting user local currency code for in-app purchases. + /// The currency code should be a 3 character ISO 4217 code. (default is USD). + /// You can set the currency code for all events by calling the following method. + /// + /// 3 character ISO 4217 code. + public void setCurrencyCode(string currencyCode) + { +#if !UNITY_EDITOR + _setCurrencyCode(currencyCode); +#endif + } + + /// + /// AppsFlyer SDK collect Apple's `advertisingIdentifier` if the `AdSupport.framework` included in the SDK. + /// You can disable this behavior by setting the following property to true. + /// + /// boolean to disableCollectAppleAdSupport + public void setDisableCollectAppleAdSupport(bool disableCollectAppleAdSupport) + { +#if !UNITY_EDITOR + _setDisableCollectAppleAdSupport(disableCollectAppleAdSupport); +#endif + } + + /// + /// Enables Debug logs for the AppsFlyer SDK. + /// Should only be set to true in development / debug. + /// The default value is false. + /// + /// shouldEnable boolean.. + public void setIsDebug(bool isDebug) + { +#if !UNITY_EDITOR + _setIsDebug(isDebug); +#endif + } + + /// + /// Set this flag to true, to collect the current device name(e.g. "My iPhone"). Default value is false. + /// + /// boolean shouldCollectDeviceName. + [System.Obsolete("This is deprecated")] + public void setShouldCollectDeviceName(bool shouldCollectDeviceName) + { +#if !UNITY_EDITOR + _setShouldCollectDeviceName(shouldCollectDeviceName); +#endif + } + + /// + /// Set the OneLink ID that should be used for User-Invites. + /// The link that is generated for the user invite will use this OneLink as the base link. + /// + /// OneLink ID obtained from the AppsFlyer Dashboard. + public void setAppInviteOneLinkID(string appInviteOneLinkID) + { +#if !UNITY_EDITOR + _setAppInviteOneLinkID(appInviteOneLinkID); +#endif + } + + /// + /// Set the deepLink timeout value that should be used for DDL. + /// + /// deepLink timeout in milliseconds. + public void setDeepLinkTimeout(long deepLinkTimeout) + { +#if !UNITY_EDITOR + _setDeepLinkTimeout(deepLinkTimeout); +#endif + } + + /// + /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data. + /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it. + /// + /// should start TCF Data collection boolean. + public void enableTCFDataCollection(bool shouldCollectTcfData) + { +#if !UNITY_EDITOR + _enableTCFDataCollection(shouldCollectTcfData); +#endif + } + + /// + /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application. + /// + /// instance of AppsFlyerConsent. + public void setConsentData(AppsFlyerConsent appsFlyerConsent) + { +#if !UNITY_EDITOR + string isUserSubjectToGDPR = appsFlyerConsent.isUserSubjectToGDPR?.ToString().ToLower() ?? "null"; + string hasConsentForDataUsage = appsFlyerConsent.hasConsentForDataUsage?.ToString().ToLower() ?? "null"; + string hasConsentForAdsPersonalization = appsFlyerConsent.hasConsentForAdsPersonalization?.ToString().ToLower() ?? "null"; + string hasConsentForAdStorage = appsFlyerConsent.hasConsentForAdStorage?.ToString().ToLower() ?? "null"; + + _setConsentData(isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization, hasConsentForAdStorage); +#endif + } + + /// + /// Logs ad revenue data along with additional parameters if provided. + /// + /// instance of AFAdRevenueData containing ad revenue information. + /// An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters. + public void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary additionalParameters) + { +#if !UNITY_EDITOR + _logAdRevenue(adRevenueData.monetizationNetwork, adRevenueData.mediationNetwork, adRevenueData.currencyIso4217Code, adRevenueData.eventRevenue, AFMiniJSON.Json.Serialize(additionalParameters)); +#endif + } + + /// + /// Anonymize user Data. + /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions. + /// Default is false + /// + /// boolean shouldAnonymizeUser. + public void anonymizeUser(bool shouldAnonymizeUser) + { +#if !UNITY_EDITOR + _anonymizeUser(shouldAnonymizeUser); +#endif + } + + /// + /// Opt-out for Apple Search Ads attributions. + /// + /// boolean disableCollectIAd. + public void setDisableCollectIAd(bool disableCollectIAd) + { +#if !UNITY_EDITOR + _setDisableCollectIAd(disableCollectIAd); +#endif + } + + /// + /// In app purchase receipt validation Apple environment(production or sandbox). The default value is false. + /// + /// boolean useReceiptValidationSandbox. + public void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox) + { +#if !UNITY_EDITOR + _setUseReceiptValidationSandbox(useReceiptValidationSandbox); +#endif + } + + /// + /// Set this flag to test uninstall on Apple environment(production or sandbox). The default value is false. + /// + /// boolean useUninstallSandbox. + public void setUseUninstallSandbox(bool useUninstallSandbox) + { +#if !UNITY_EDITOR + _setUseUninstallSandbox(useUninstallSandbox); +#endif + } + + /// + /// For advertisers who wrap OneLink within another Universal Link. + /// An advertiser will be able to deeplink from a OneLink wrapped within another Universal Link and also record this retargeting conversion. + /// + /// Array of urls. + public void setResolveDeepLinkURLs(params string[] resolveDeepLinkURLs) + { +#if !UNITY_EDITOR + _setResolveDeepLinkURLs(resolveDeepLinkURLs.Length,resolveDeepLinkURLs); +#endif + } + + /// + /// For advertisers who use vanity OneLinks. + /// + /// Array of domains. + public void setOneLinkCustomDomain(params string[] oneLinkCustomDomains) + { +#if !UNITY_EDITOR + _setOneLinkCustomDomains(oneLinkCustomDomains.Length, oneLinkCustomDomains); +#endif + } + + /// + /// Set the user emails and encrypt them. + /// cryptMethod Encryption method: + /// EmailCryptType.EmailCryptTypeMD5 + /// EmailCryptType.EmailCryptTypeSHA1 + /// EmailCryptType.EmailCryptTypeSHA256 + /// EmailCryptType.EmailCryptTypeNone + /// + /// type Hash algoritm. + /// length of userEmails array. + /// userEmails The list of strings that hold mails.} + + public void setUserEmails(EmailCryptType cryptType, params string[] userEmails) + { +#if !UNITY_EDITOR + _setUserEmails(cryptType, userEmails.Length, userEmails); +#endif + } + + /// + /// Set the user phone number. + /// + /// User phoneNumber. + public void setPhoneNumber(string phoneNumber){ +#if !UNITY_EDITOR + _setPhoneNumber(phoneNumber); +#endif + } + + /// + /// To send and validate in app purchases you can call this method from the processPurchase method - please use v2. + /// + /// The product identifier. + /// The product price. + /// The product currency. + /// The purchase transaction Id. + /// The additional param, which you want to receive it in the raw reports. + public void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary additionalParameters, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + _validateAndSendInAppPurchase(productIdentifier, price, currency, transactionId, AFMiniJSON.Json.Serialize(additionalParameters), gameObject ? gameObject.name : null); +#endif + } + + /// + /// V2 + /// To send and validate in app purchases you can call this method from the processPurchase method. + /// + /// The AFSDKPurchaseDetailsIOS instance. + /// The additional params, which you want to receive it in the raw reports. + public void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + _validateAndSendInAppPurchaseV2(details.productId, details.transactionId, (int)details.purchaseType, AFMiniJSON.Json.Serialize(purchaseAdditionalDetails), gameObject ? gameObject.name : null); +#endif + } + + /// + /// To record location for geo-fencing. Does the same as code below. + /// + /// The location longitude. + /// The location latitude. + public void recordLocation(double longitude, double latitude) + { +#if !UNITY_EDITOR + _recordLocation(longitude, latitude); +#endif + } + + /// + /// Get AppsFlyer's unique device ID, which is created for every new install of an app. + /// + public string getAppsFlyerId() + { +#if !UNITY_EDITOR + return _getAppsFlyerId(); +#else + return ""; +#endif + } + + /// + /// Register uninstall - you should register for remote notification and provide AppsFlyer the push device token. + /// + /// deviceToken The `deviceToken` from `-application:didRegisterForRemoteNotificationsWithDeviceToken:`. + public void registerUninstall(byte[] deviceToken) + { +#if !UNITY_EDITOR + _registerUninstall(deviceToken); +#endif + } + + /// + /// Enable AppsFlyer to handle a push notification. + /// + /// pushPayload The `userInfo` from received remote notification. One of root keys should be @"af".. + public void handlePushNotification(Dictionary pushPayload) + { +#if !UNITY_EDITOR + _handlePushNotification(AFMiniJSON.Json.Serialize(pushPayload)); +#endif + } + + /// + /// Get SDK version. + /// + public string getSdkVersion() + { +#if !UNITY_EDITOR + return _getSDKVersion(); +#else + return ""; +#endif + } + + /// + /// This property accepts a string value representing the host name for all endpoints. + /// Can be used to Zero rate your application’s data usage.Contact your CSM for more information. + /// + /// Host Name. + /// Host prefix. + public void setHost(string hostPrefix, string host) + { +#if !UNITY_EDITOR + _setHost(host, hostPrefix); +#endif + } + + /// + /// This property is responsible for timeout between sessions in seconds. + /// Default value is 5 seconds. + /// + /// minimum time between 2 separate sessions in seconds. + public void setMinTimeBetweenSessions(int minTimeBetweenSessions) + { +#if !UNITY_EDITOR + _setMinTimeBetweenSessions(minTimeBetweenSessions); +#endif + } + + /// + /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning. + /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance. + /// This can be achieved with the stopSDK API. + /// + /// boolean isSDKStopped. + public void stopSDK(bool isSDKStopped) + { +#if !UNITY_EDITOR + _stopSDK(isSDKStopped); +#endif + } + + // + /// Was the stopSDK(boolean) API set to true. + /// + /// boolean isSDKStopped. + public bool isSDKStopped() + { +#if !UNITY_EDITOR + return _isSDKStopped(); +#else + return false; +#endif + } + + /// + /// In case you want to track deep linking manually call handleOpenUrl. + /// The continueUserActivity and onOpenURL are implemented in the AppsFlyerAppController.mm class, so + /// only use this method if the other methods do not cover your apps deeplinking needs. + /// + /// The URL to be passed to your AppDelegate. + /// The sourceApplication to be passed to your AppDelegate. + /// The annotation to be passed to your app delegate. + public void handleOpenUrl(string url, string sourceApplication, string annotation) + { +#if !UNITY_EDITOR + _handleOpenUrl(url, sourceApplication, annotation); +#endif + } + + /// + /// Used by advertisers to exclude all networks/integrated partners from getting data. + /// + public void setSharingFilterForAllPartners() + { +#if !UNITY_EDITOR + _setSharingFilterForAllPartners(); +#endif + } + + /// + /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data. + /// + /// partners to exclude from getting data + public void setSharingFilter(params string[] partners) + { +#if !UNITY_EDITOR + _setSharingFilter(partners.Length, partners); +#endif + } + + + /// + /// Lets you configure how which partners should the SDK exclude from data-sharing. + /// partners to exclude from getting data + public static void setSharingFilterForPartners(params string[] partners) + { +#if !UNITY_EDITOR + _setSharingFilterForPartners(partners.Length, partners); +#endif + } + + /// + /// To record an impression use the following API call. + /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard. + /// + /// promoted App ID. + /// cross promotion campaign. + /// parameters Dictionary. + public void recordCrossPromoteImpression(string appID, string campaign, Dictionary parameters) + { +#if !UNITY_EDITOR + _recordCrossPromoteImpression(appID, campaign, AFMiniJSON.Json.Serialize(parameters)); +#endif + } + + /// + /// Use the following API to attribute the click and launch the app store's app page. + /// + /// promoted App ID + /// cross promotion campaign + /// additional user params + public void attributeAndOpenStore(string appID, string campaign, Dictionary parameters, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + _attributeAndOpenStore(appID, campaign, AFMiniJSON.Json.Serialize(parameters), gameObject ? gameObject.name : null); +#endif + } + + /// + /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click. + /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution- + /// + /// parameters Dictionary. + public void generateUserInviteLink(Dictionary parameters, MonoBehaviour gameObject) + { +#if !UNITY_EDITOR + _generateUserInviteLink(AFMiniJSON.Json.Serialize(parameters), gameObject ? gameObject.name : null); +#endif + } + + /// + /// It is recommended to generate an in-app event after the invite is sent to record the invites from the senders' perspective. + /// This enables you to find the users that tend most to invite friends, and the media sources that get you these users. + /// + /// channel string. + /// parameters Dictionary.. + public void recordInvite(string channel, Dictionary parameters) + { +#if !UNITY_EDITOR + _recordInvite(channel, AFMiniJSON.Json.Serialize(parameters)); +#endif + } + + /// + /// Waits for request user authorization to access app-related data + /// + /// time to wait until session starts + public void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval) + { +#if !UNITY_EDITOR + _waitForATTUserAuthorizationWithTimeoutInterval(timeoutInterval); +#endif + } + + /// + /// + /// bool should diable + public void disableSKAdNetwork(bool isDisabled) + { +#if !UNITY_EDITOR + _disableSKAdNetwork(isDisabled); +#endif + } + + /// + /// Use this method if you’re integrating your app with push providers + /// that don’t use the default push notification JSON schema the SDK expects. + /// See docs for more info. + /// + /// array of nested json path + public void addPushNotificationDeepLinkPath(params string[] paths) + { +#if !UNITY_EDITOR + _addPushNotificationDeepLinkPath(paths.Length, paths); +#endif + } + + /// + /// subscribe to unified deep link callbacks + /// + public void subscribeForDeepLink(string objectName){ +#if !UNITY_EDITOR + _subscribeForDeepLink(objectName); +#endif + } + + /// + /// Set the language of the device. + /// + public void setCurrentDeviceLanguage(string language){ +#if !UNITY_EDITOR + _setCurrentDeviceLanguage(language); +#endif + } + + /// + /// Allows sending custom data for partner integration purposes. + /// + public void setPartnerData(string partnerId, Dictionary partnerInfo){ +#if !UNITY_EDITOR + _setPartnerData(partnerId, AFMiniJSON.Json.Serialize(partnerInfo)); +#endif + } + + /// + /// Use to disable app vendor identifier (IDFV) collection, 'true' to disable. + /// + public void disableIDFVCollection(bool isDisabled){ +#if !UNITY_EDITOR + _disableIDFVCollection(isDisabled); +#endif + } + + delegate void unityCallBack(string message); + + [AOT.MonoPInvokeCallback(typeof(unityCallBack))] + public static void getCallback(string gameObjectName, string callbackName, string message) + { + GameObject go = GameObject.Find("AppsFlyerObject"); + var afscript = go.GetComponent("AppsFlyerObjectScript") as AppsFlyerObjectScript; + Type type = typeof(AppsFlyerObjectScript); + MethodInfo info = type.GetMethod(callbackName); + info.Invoke(afscript, new[] { message }); + + } + + + /* + * AppsFlyer ios method mapping + */ + + +#if UNITY_IOS + [DllImport("__Internal")] + private static extern void _startSDK(bool shouldCallback, string objectName); +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] + private static extern void _startSDK(bool shouldCallback, string objectName, Action getCallback); + +#endif + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _getConversionData(string objectName); + + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setCustomerUserID(string customerUserID); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setAdditionalData(string customData); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setAppsFlyerDevKey(string appsFlyerDevKey); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setAppleAppID(string appleAppID); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setCurrencyCode(string currencyCode); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setDisableCollectAppleAdSupport(bool disableCollectAppleAdSupport); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setIsDebug(bool isDebug); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setShouldCollectDeviceName(bool shouldCollectDeviceName); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setAppInviteOneLinkID(string appInviteOneLinkID); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setDeepLinkTimeout(long deepLinkTimeout); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _anonymizeUser(bool shouldAnonymizeUser); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _enableTCFDataCollection(bool shouldCollectTcfData); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setConsentData(string isUserSubjectToGDPR, string hasConsentForDataUsage, string hasConsentForAdsPersonalization, string hasConsentForAdStorage); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _logAdRevenue(string monetizationNetwork, MediationNetwork mediationNetwork, string currencyIso4217Code, double eventRevenue, string additionalParameters); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setDisableCollectIAd(bool disableCollectIAd); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setUseReceiptValidationSandbox(bool useReceiptValidationSandbox); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setUseUninstallSandbox(bool useUninstallSandbox); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setResolveDeepLinkURLs(int length, params string[] resolveDeepLinkURLs); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setOneLinkCustomDomains(int length, params string[] oneLinkCustomDomains); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setUserEmails(EmailCryptType cryptType, int length, params string[] userEmails); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setPhoneNumber(string phoneNumber); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _afSendEvent(string eventName, string eventValues, bool shouldCallback, string objectName); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, string additionalParameters, string objectName); + + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _validateAndSendInAppPurchaseV2(string product, string transactionId, int purchaseType, string purchaseAdditionalDetails, string objectName); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _recordLocation(double longitude, double latitude); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern string _getAppsFlyerId(); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _registerUninstall(byte[] deviceToken); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _handlePushNotification(string pushPayload); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern string _getSDKVersion(); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setHost(string host, string hostPrefix); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setMinTimeBetweenSessions(int minTimeBetweenSessions); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _stopSDK(bool isStopSDK); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern bool _isSDKStopped(); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _handleOpenUrl(string url, string sourceApplication, string annotation); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setSharingFilterForAllPartners(); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setSharingFilter(int length, params string[] partners); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setSharingFilterForPartners(int length, params string[] partners); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _recordCrossPromoteImpression(string appID, string campaign, string parameters); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _attributeAndOpenStore(string appID, string campaign, string parameters, string gameObject); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _generateUserInviteLink(string parameters, string gameObject); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _recordInvite(string channel, string parameters); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _disableSKAdNetwork(bool isDisabled); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _addPushNotificationDeepLinkPath(int length, params string[] paths); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _subscribeForDeepLink(string objectName); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setCurrentDeviceLanguage(string language); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _setPartnerData(string partnerId, string partnerInfo); + +#if UNITY_IOS + [DllImport("__Internal")] +#elif UNITY_STANDALONE_OSX + [DllImport("AppsFlyerBundle")] +#endif + private static extern void _disableIDFVCollection(bool isDisabled); + + } + +#endif + + +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs.meta new file mode 100644 index 0000000..36b719f --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/AppsFlyeriOS.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b34371b3cc09641ebb007ffc4e9500f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs new file mode 100644 index 0000000..3a83bc3 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs @@ -0,0 +1,31 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace AppsFlyerSDK +{ + + public interface IAppsFlyerAndroidBridge : IAppsFlyerNativeBridge + { + void updateServerUninstallToken(string token); + void setImeiData(string imei); + void setAndroidIdData(string androidId); + void waitForCustomerUserId(bool wait); + void setCustomerIdAndStartSDK(string id); + string getOutOfStore(); + void setOutOfStore(string sourceName); + void setCollectAndroidID(bool isCollect); + void setCollectIMEI(bool isCollect); + void setIsUpdate(bool isUpdate); + void setPreinstallAttribution(string mediaSource, string campaign, string siteId); + bool isPreInstalledApp(); + string getAttributionId(); + void handlePushNotifications(); + void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary additionalParameters, MonoBehaviour gameObject); + void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject); + void setCollectOaid(bool isCollect); + void setDisableAdvertisingIdentifiers(bool disable); + void setDisableNetworkData(bool disable); + + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs.meta new file mode 100644 index 0000000..8157bc6 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerAndroidBridge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdf9d1bc41a8244b3bc2d249fb6cd7aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs new file mode 100644 index 0000000..454eaa6 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs @@ -0,0 +1,31 @@ +namespace AppsFlyerSDK +{ + public interface IAppsFlyerConversionData + { + /// + /// `conversionData` contains information about install. Organic/non-organic, etc. + /// https://support.appsflyer.com/hc/en-us/articles/360000726098-Conversion-Data-Scenarios#Introduction + /// + /// JSON string of the returned conversion data. + void onConversionDataSuccess(string conversionData); + + /// + /// Any errors that occurred during the conversion request. + /// + /// A string describing the error. + void onConversionDataFail(string error); + + /// + /// `attributionData` contains information about OneLink, deeplink. + /// https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-Deep-Linking-Guide#Intro + /// + /// JSON string of the returned deeplink data. + void onAppOpenAttribution(string attributionData); + + /// + /// Any errors that occurred during the attribution request. + /// + /// A string describing the error. + void onAppOpenAttributionFailure(string error); + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs.meta new file mode 100644 index 0000000..3133eaa --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerConversionData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2f1d4dadb7cb44628f25f1ffd8fc104 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs new file mode 100644 index 0000000..4de6fd4 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs @@ -0,0 +1,26 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace AppsFlyerSDK +{ + + public interface IAppsFlyerIOSBridge : IAppsFlyerNativeBridge + { + void setDisableCollectAppleAdSupport(bool disable); + void setShouldCollectDeviceName(bool shouldCollectDeviceName); + void setDisableCollectIAd(bool disableCollectIAd); + void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox); + void setUseUninstallSandbox(bool useUninstallSandbox); + void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary additionalParameters, MonoBehaviour gameObject); + void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary purchaseAdditionalDetails, MonoBehaviour gameObject); + void registerUninstall(byte[] deviceToken); + void handleOpenUrl(string url, string sourceApplication, string annotation); + void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval); + void setCurrentDeviceLanguage(string language); + void disableSKAdNetwork(bool isDisabled); + void disableIDFVCollection(bool isDisabled); + + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs.meta new file mode 100644 index 0000000..8e200ea --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerIOSBridge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6847fb337898040288c165e3667101a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs new file mode 100644 index 0000000..23a107c --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs @@ -0,0 +1,76 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace AppsFlyerSDK +{ + + public interface IAppsFlyerNativeBridge + { + bool isInit { get; set; } + + void startSDK(bool onRequestResponse, string CallBackObjectName); + + void sendEvent(string eventName, Dictionary eventValues, bool onInAppResponse, string CallBackObjectName); + + void stopSDK(bool isSDKStopped); + + bool isSDKStopped(); + + string getSdkVersion(); + + void setCustomerUserId(string id); + + void setAppInviteOneLinkID(string oneLinkId); + + void setAdditionalData(Dictionary customData); + + void setDeepLinkTimeout(long deepLinkTimeout); + + void setResolveDeepLinkURLs(params string[] urls); + + void setOneLinkCustomDomain(params string[] domains); + + void setCurrencyCode(string currencyCode); + + void recordLocation(double latitude, double longitude); + + void anonymizeUser(bool shouldAnonymizeUser); + + string getAppsFlyerId(); + + void enableTCFDataCollection(bool shouldCollectTcfData); + + void setConsentData(AppsFlyerConsent appsFlyerConsent); + + void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary additionalParameters); + + void setMinTimeBetweenSessions(int seconds); + + void setHost(string hostPrefixName, string hostName); + + void setPhoneNumber(string phoneNumber); + + void setSharingFilterForAllPartners(); + + void setSharingFilter(params string[] partners); + + void getConversionData(string objectName); + + void attributeAndOpenStore(string appID, string campaign, Dictionary userParams, MonoBehaviour gameObject); + + void recordCrossPromoteImpression(string appID, string campaign, Dictionary parameters); + + void generateUserInviteLink(Dictionary parameters, MonoBehaviour gameObject); + + void addPushNotificationDeepLinkPath(params string[] paths); + + void setUserEmails(EmailCryptType cryptType, params string[] userEmails); + + void subscribeForDeepLink(string objectName); + + void setIsDebug(bool shouldEnable); + + void setPartnerData(string partnerId, Dictionary partnerInfo); + } +} diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs.meta new file mode 100644 index 0000000..dd43257 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerNativeBridge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 409b8302434664a3785ce55d075e7f58 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs new file mode 100644 index 0000000..73591a3 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs @@ -0,0 +1,8 @@ +namespace AppsFlyerSDK +{ + public interface IAppsFlyerPurchaseValidation + { + void didReceivePurchaseRevenueValidationInfo(string validationInfo); + void didReceivePurchaseRevenueError(string error); + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs.meta new file mode 100644 index 0000000..3e453b7 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerPurchaseValidation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c60f499ae0d048b1be8ffd6878a184c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs new file mode 100644 index 0000000..aac109e --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs @@ -0,0 +1,26 @@ +namespace AppsFlyerSDK +{ + public interface IAppsFlyerUserInvite + { + /// + /// The success callback for generating OneLink URLs. + /// + /// A string of the newly created url. + void onInviteLinkGenerated(string link); + + /// + /// The error callback for generating OneLink URLs + /// + /// A string describing the error. + void onInviteLinkGeneratedFailure(string error); + + /// + /// (ios only) iOS allows you to utilize the StoreKit component to open + /// the App Store while remaining in the context of your app. + /// More details at https://support.appsflyer.com/hc/en-us/articles/115004481946-Cross-Promotion-Tracking#tracking-cross-promotion-impressions + /// + /// openStore callback Contains promoted `clickURL` + void onOpenStoreLinkGenerated(string link); + + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs.meta new file mode 100644 index 0000000..8530528 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerUserInvite.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a4cdfa023cb8497b94bb39720052fef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs new file mode 100644 index 0000000..a5c02cf --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs @@ -0,0 +1,19 @@ +namespace AppsFlyerSDK +{ + public interface IAppsFlyerValidateAndLog + { + /// + /// The success callback for validateAndSendInAppPurchase API. + /// For Android : the callback will return JSON string. + /// For iOS : the callback will return a JSON string from apples verifyReceipt API. + /// + /// + void onValidateAndLogComplete(string result); + + /// + /// The error callback for validateAndSendInAppPurchase API. + /// + /// A string describing the error. + void onValidateAndLogFailure(string error); + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs.meta new file mode 100644 index 0000000..459cc85 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateAndLog.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a5adb7eab3284dd39a76ec56c06457c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs new file mode 100644 index 0000000..90490e2 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs @@ -0,0 +1,19 @@ +namespace AppsFlyerSDK +{ + public interface IAppsFlyerValidateReceipt + { + /// + /// The success callback for validateAndSendInAppPurchase API. + /// For Android : the callback will return "Validate success". + /// For iOS : the callback will return a JSON string from apples verifyReceipt API. + /// + /// + void didFinishValidateReceipt(string result); + + /// + /// The error callback for validateAndSendInAppPurchase API. + /// + /// A string describing the error. + void didFinishValidateReceiptWithError(string error); + } +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs.meta new file mode 100644 index 0000000..38efa67 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/IAppsFlyerValidateReceipt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6385b1d184efa400a98515735e1f17bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs b/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs new file mode 100644 index 0000000..536190f --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs @@ -0,0 +1,184 @@ +#nullable enable + +using System.Collections; +using System.Collections.Generic; +using System; +using UnityEngine; + +[System.Serializable] +public class InAppPurchaseValidationResult : EventArgs +{ + public bool success; + public ProductPurchase? productPurchase; + public ValidationFailureData? failureData; + public string? token; +} + +[System.Serializable] +public class ProductPurchase +{ + public string? kind; + public string? purchaseTimeMillis; + public int purchaseState; + public int consumptionState; + public string? developerPayload; + public string? orderId; + public int purchaseType; + public int acknowledgementState; + public string? purchaseToken; + public string? productId; + public int quantity; + public string? obfuscatedExternalAccountId; + public string? obfuscatedExternalProfil; + public string? regionCode; +} + +[System.Serializable] +public class ValidationFailureData +{ + public int status; + public string? description; +} + +[System.Serializable] +public class SubscriptionValidationResult +{ + public bool success; + public SubscriptionPurchase? subscriptionPurchase; + public ValidationFailureData? failureData; + public string? token; +} + +[System.Serializable] +public class SubscriptionPurchase +{ + public string? acknowledgementState; + public CanceledStateContext? canceledStateContext; + public ExternalAccountIdentifiers? externalAccountIdentifiers; + public string? kind; + public string? latestOrderId; + public List? lineItems; + public string? linkedPurchaseToken; + public PausedStateContext? pausedStateContext; + public string? regionCode; + public string? startTime; + public SubscribeWithGoogleInfo? subscribeWithGoogleInfo; + public string? subscriptionState; + public TestPurchase? testPurchase; +} + +[System.Serializable] +public class CanceledStateContext +{ + public DeveloperInitiatedCancellation? developerInitiatedCancellation; + public ReplacementCancellation? replacementCancellation; + public SystemInitiatedCancellation? systemInitiatedCancellation; + public UserInitiatedCancellation? userInitiatedCancellation; + +} + +[System.Serializable] +public class ExternalAccountIdentifiers +{ + public string? externalAccountId; + public string? obfuscatedExternalAccountId; + public string? obfuscatedExternalProfileId; +} + +[System.Serializable] +public class SubscriptionPurchaseLineItem +{ + public AutoRenewingPlan? autoRenewingPlan; + public DeferredItemReplacement? deferredItemReplacement; + public string? expiryTime; + public OfferDetails? offerDetails; + public PrepaidPlan? prepaidPlan; + public string? productId; +} + +[System.Serializable] +public class PausedStateContext +{ + public string? autoResumeTime; +} + +[System.Serializable] +public class SubscribeWithGoogleInfo +{ + public string? emailAddress; + public string? familyName; + public string? givenName; + public string? profileId; + public string? profileName; +} + +[System.Serializable] +public class TestPurchase{} + +[System.Serializable] +public class DeveloperInitiatedCancellation{} + +[System.Serializable] +public class ReplacementCancellation{} + +[System.Serializable] +public class SystemInitiatedCancellation{} + +[System.Serializable] +public class UserInitiatedCancellation +{ + public CancelSurveyResult? cancelSurveyResult; + public string? cancelTime; +} + +[System.Serializable] +public class AutoRenewingPlan +{ + public string? autoRenewEnabled; + public SubscriptionItemPriceChangeDetails? priceChangeDetails; +} + +[System.Serializable] +public class DeferredItemReplacement +{ + public string? productId; +} + +[System.Serializable] +public class OfferDetails +{ + public List? offerTags; + public string? basePlanId; + public string? offerId; +} + +[System.Serializable] +public class PrepaidPlan +{ + public string? allowExtendAfterTime; +} + +[System.Serializable] +public class CancelSurveyResult +{ + public string? reason; + public string? reasonUserInput; +} + +[System.Serializable] +public class SubscriptionItemPriceChangeDetails +{ + public string? expectedNewPriceChargeTime; + public Money? newPrice; + public string? priceChangeMode; + public string? priceChangeState; +} + +[System.Serializable] + public class Money + { + public string? currencyCode; + public long nanos; + public long units; + } + \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs.meta b/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs.meta new file mode 100644 index 0000000..7fdbf37 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/Runtime/ProductPurchase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a1435104a69d4c8ebcc6f237cc29a54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.appsflyersdk/package.json b/Packages/com.bywaystudios.appsflyersdk/package.json new file mode 100644 index 0000000..b8fff9c --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/package.json @@ -0,0 +1,6 @@ +{ + "name": "com.bywaystudios.appsflyersdk", + "displayName": "AppsFlyerSDK", + "version": "6.17.72-exp.1", + "description": "AppsFlyer Unity SDK" +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.appsflyersdk/package.json.meta b/Packages/com.bywaystudios.appsflyersdk/package.json.meta new file mode 100644 index 0000000..ee01cd5 --- /dev/null +++ b/Packages/com.bywaystudios.appsflyersdk/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d7791105a72b1fb469d2a9f2e0663bd2 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json new file mode 100644 index 0000000..afd3d9a --- /dev/null +++ b/Packages/manifest.json @@ -0,0 +1,48 @@ +{ + "dependencies": { + "com.unity.asset-store-validation": "0.6.0", + "com.unity.collab-proxy": "2.10.2", + "com.unity.editorcoroutines": "1.0.1", + "com.unity.feature.development": "1.0.1", + "com.unity.ide.rider": "3.0.38", + "com.unity.ide.visualstudio": "2.0.25", + "com.unity.ide.vscode": "1.2.5", + "com.unity.nuget.newtonsoft-json": "3.2.2", + "com.unity.performance.profile-analyzer": "1.2.4", + "com.unity.settings-manager": "2.1.1", + "com.unity.test-framework": "1.1.33", + "com.unity.testtools.codecoverage": "1.2.7", + "com.unity.upm.develop": "0.5.3-exp.1", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json new file mode 100644 index 0000000..13dbf55 --- /dev/null +++ b/Packages/packages-lock.json @@ -0,0 +1,375 @@ +{ + "dependencies": { + "com.bywaystudios.appsflyersdk": { + "version": "file:com.bywaystudios.appsflyersdk", + "depth": 0, + "source": "embedded", + "dependencies": {} + }, + "com.unity.asset-store-validation": { + "version": "0.6.0", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.nuget.newtonsoft-json": "2.0.2" + }, + "url": "https://packages.unity.com" + }, + "com.unity.collab-proxy": { + "version": "2.10.2", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.editorcoroutines": { + "version": "1.0.1", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.ext.nunit": { + "version": "1.0.6", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.feature.development": { + "version": "1.0.1", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.ide.visualstudio": "2.0.22", + "com.unity.ide.rider": "3.0.36", + "com.unity.ide.vscode": "1.2.5", + "com.unity.editorcoroutines": "1.0.0", + "com.unity.performance.profile-analyzer": "1.2.3", + "com.unity.test-framework": "1.1.33", + "com.unity.testtools.codecoverage": "1.2.6" + } + }, + "com.unity.ide.rider": { + "version": "3.0.38", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.visualstudio": { + "version": "2.0.25", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.31" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.vscode": { + "version": "1.2.5", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.nuget.newtonsoft-json": { + "version": "3.2.2", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.performance.profile-analyzer": { + "version": "1.2.4", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.settings-manager": { + "version": "2.1.1", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.test-framework": { + "version": "1.1.33", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.testtools.codecoverage": { + "version": "1.2.7", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.0.16", + "com.unity.settings-manager": "1.0.1" + }, + "url": "https://packages.unity.com" + }, + "com.unity.upm.develop": { + "version": "0.5.3-exp.1", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.20", + "com.unity.nuget.newtonsoft-json": "2.0.2", + "com.unity.asset-store-validation": "0.1.3" + }, + "url": "https://packages.unity.com" + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..07ebfb0 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 1024 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..cdc1f3e --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_EnableUnifiedHeightmaps: 1 + m_DefaultMaxAngluarSpeed: 7 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..0147887 --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..1e44a0a --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,30 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 0 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref + m_ProjectGenerationRootNamespace: + m_CollabEditorSettings: + inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1 + m_EnterPlayModeOptionsEnabled: 0 + m_EnterPlayModeOptions: 3 + m_ShowLightmapResolutionOverlay: 1 + m_UseLegacyProbeSampleCount: 0 + m_SerializeInlineMappingsOnOneLine: 1 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..43369e3 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 + m_LogWhenShaderIsCompiled: 0 + m_AllowEnlightenSupportForUpgradedProject: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/MemorySettings.asset b/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..112a053 --- /dev/null +++ b/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreReleasePackages: 0 + m_EnablePackageDependencies: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -830 + m_OriginalInstanceId: -832 + m_LoadAssets: 0 diff --git a/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json new file mode 100644 index 0000000..3c7b4c1 --- /dev/null +++ b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json @@ -0,0 +1,5 @@ +{ + "m_Dictionary": { + "m_DictionaryValues": [] + } +} \ No newline at end of file diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..47880b1 --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 4 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/PresetManager.asset b/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..5727f4e --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,961 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 26 + productGUID: 50fdcc3116d56d449af11ea72d35a6e9 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: AppsFlyerSDKPackage + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1920 + defaultScreenHeight: 1080 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 1 + unsupportedMSAAFallback: 0 + m_SpriteBatchVertexThreshold: 300 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 1 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 + androidPredictiveBackSupport: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + audioSpatialExperience: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + dedicatedServerOptimizations: 0 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchNVNGraphicsFirmwareMemory: 32 + switchMaxWorkerMultiple: 8 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 1 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 + useHDRDisplay: 0 + hdrBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: + Standalone: 0 + VisionOS: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 22 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + strictShaderVariantMatching: 0 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSSimulatorArchitecture: 0 + iOSTargetOSVersionString: 12.0 + tvOSSdkVersion: 0 + tvOSSimulatorArchitecture: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 12.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + macOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + metalCompileShaderBinary: 0 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea + templatePackageId: com.unity.template.packagetemplate@1.0.0 + templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: iPhone + m_Icons: + - m_Textures: [] + m_Width: 180 + m_Height: 180 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 167 + m_Height: 167 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 152 + m_Height: 152 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 76 + m_Height: 76 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 87 + m_Height: 87 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 60 + m_Height: 60 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 20 + m_Height: 20 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 1024 + m_Height: 1024 + m_Kind: 4 + m_SubKind: App Store + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 1 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 1 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 1 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 1 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 1 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: + - m_BuildTarget: Android + m_EncodingQuality: 1 + - m_BuildTarget: iPhone + m_EncodingQuality: 1 + - m_BuildTarget: tvOS + m_EncodingQuality: 1 + m_BuildTargetGroupHDRCubemapEncodingQuality: + - m_BuildTarget: Android + m_EncodingQuality: 1 + - m_BuildTarget: iPhone + m_EncodingQuality: 1 + - m_BuildTarget: tvOS + m_EncodingQuality: 1 + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: + - m_BuildTarget: Android + m_Encoding: 1 + - m_BuildTarget: iPhone + m_Encoding: 1 + - m_BuildTarget: tvOS + m_Encoding: 1 + m_BuildTargetDefaultTextureCompressionFormat: + - m_BuildTarget: Android + m_Format: 3 + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchEnableFileSystemTrace: 0 + switchLTOSetting: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchCompilerFlags: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchDisableHTCSPlayerConnection: 0 + switchUseNewStyleFilepaths: 1 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + il2cppCodeGeneration: {} + managedStrippingLevel: + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + Stadia: 1 + VisionOS: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: AppsFlyerSDKPackage + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: AppsFlyerSDKPackage + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} + metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 1 + hmiLogStartupTiming: 0 + hmiCpuConfiguration: + apiCompatibilityLevel: 6 + activeInputHandler: 0 + windowsGamepadBackendHint: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..587f809 --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2022.3.62f3 +m_EditorVersionWithRevision: 2022.3.62f3 (96770f904ca7) diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..36c0dad --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,234 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Lumin: 5 + GameCoreScarlett: 5 + GameCoreXboxOne: 5 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PS5: 5 + Stadia: 5 + Standalone: 5 + WebGL: 3 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..a88bee0 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,36 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + m_PackageRequiringCoreStatsPresent: 0 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/ProjectSettings/VFXManager.asset b/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..3a95c98 --- /dev/null +++ b/ProjectSettings/VFXManager.asset @@ -0,0 +1,12 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_StripUpdateShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/ProjectSettings/VersionControlSettings.asset b/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 0000000..dca2881 --- /dev/null +++ b/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/XRSettings.asset b/ProjectSettings/XRSettings.asset new file mode 100644 index 0000000..482590c --- /dev/null +++ b/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file