diff --git a/Assets/AddressableAssetsData/AddressableAssetSettings.asset b/Assets/AddressableAssetsData/AddressableAssetSettings.asset index cf78e20..c90c28a 100644 --- a/Assets/AddressableAssetsData/AddressableAssetSettings.asset +++ b/Assets/AddressableAssetsData/AddressableAssetSettings.asset @@ -15,7 +15,7 @@ MonoBehaviour: m_DefaultGroup: ab759628f97301541855b12ebefe30d5 m_currentHash: serializedVersion: 2 - Hash: 92948e6e64f76e2ab7c9ad8968522f5b + Hash: 2e7ac85690eeca579afc57a4b462de21 m_OptimizeCatalogSize: 0 m_BuildRemoteCatalog: 1 m_CatalogRequestsTimeout: 0 diff --git a/Assets/AddressableAssetsData/Android/addressables_content_state.bin b/Assets/AddressableAssetsData/Android/addressables_content_state.bin index e895ba7..dd98780 100644 Binary files a/Assets/AddressableAssetsData/Android/addressables_content_state.bin and b/Assets/AddressableAssetsData/Android/addressables_content_state.bin differ diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames.meta b/Assets/GeneratedLocalRepo/GooglePlayGames.meta new file mode 100644 index 0000000..bd83b22 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5ec3b4a710c3ac4cb70edeba9fbf856 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games.meta new file mode 100644 index 0000000..d083439 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6275d42c28128a49a450f7708543546 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor.meta new file mode 100644 index 0000000..b19d404 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 315965287bbf43d4b88ec90948807dc8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository.meta new file mode 100644 index 0000000..2b400d0 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0127f844fb84e164db70282ab9a1f360 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta new file mode 100644 index 0000000..279b75f --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2f4e61d01d027ae4098130e206f91e7a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta new file mode 100644 index 0000000..496c4ab --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 61dedbaac98a7024fae4a814dd3996b7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta new file mode 100644 index 0000000..5faa26b --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb86a74bfb1c63941982552d7cabb4a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta new file mode 100644 index 0000000..8a504f6 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: df3f7c6574125a0448c8b54d59640ab0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta new file mode 100644 index 0000000..5d0ff0d --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 165366dd47118514188d2f8ff79b1b48 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar new file mode 100644 index 0000000..6b9fc56 Binary files /dev/null and b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar differ diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar.meta new file mode 100644 index 0000000..a5984a8 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar.meta @@ -0,0 +1,25 @@ +fileFormatVersion: 2 +guid: d34ff6261005cf44aa1fd70929cd17e0 +labels: +- gpsr +PluginImporter: + externalObjects: {} + serializedVersion: 3 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + Any: + enabled: 0 + settings: {} + Editor: + enabled: 1 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom new file mode 100644 index 0000000..b5c4440 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom @@ -0,0 +1,20 @@ + + + 4.0.0 + com.google.games + gpgs-plugin-support + 2.1.0 + aar + + + com.google.android.gms + play-services-games-v2 + 21.0.0 + + + com.google.android.gms + play-services-nearby + 18.5.0 + + + \ No newline at end of file diff --git a/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta new file mode 100644 index 0000000..73bb445 --- /dev/null +++ b/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9f2e9b9a7ff43104f84fd8bc87c57d58 +labels: +- gpsr +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GoogleMobileAds/link.xml.meta b/Assets/GoogleMobileAds/link.xml.meta index df24df5..fb460b1 100644 --- a/Assets/GoogleMobileAds/link.xml.meta +++ b/Assets/GoogleMobileAds/link.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3d56492ea0fa21446adb3064d83c2c8e +guid: 7ab68dd3fa82e4b4eb8e4795d6fbb273 labels: - gvh - gvh_version-9.5.0 diff --git a/Assets/GooglePlayGames.meta b/Assets/GooglePlayGames.meta new file mode 100644 index 0000000..fa3478e --- /dev/null +++ b/Assets/GooglePlayGames.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1f9e743e218055f47ac2ffe7c04dc1d5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games.meta b/Assets/GooglePlayGames/com.google.play.games.meta new file mode 100644 index 0000000..83f00d4 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 24d9eb3a0c4fc49e9b5e5b3600becdef +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor.meta b/Assets/GooglePlayGames/com.google.play.games/Editor.meta new file mode 100644 index 0000000..00da255 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 11083f74e79584f50ad394be94e2caec +folderAsset: yes +timeCreated: 1435699548 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs new file mode 100644 index 0000000..8413846 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs @@ -0,0 +1,460 @@ +// +// Copyright (C) Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +namespace GooglePlayGames.Editor +{ + using System; + using System.Collections; + using System.IO; + using System.Xml; + using UnityEditor; + using UnityEngine; + + /// + /// Google Play Game Services Setup dialog for Android. + /// + public class GPGSAndroidSetupUI : EditorWindow + { + /// + /// The configuration data from the play games console "resource data" + /// + private string mConfigData = string.Empty; + + /// + /// The name of the class to generate containing the resource constants. + /// + private string mClassName = "GPGSIds"; + + /// + /// The scroll position + /// + private Vector2 scroll; + + /// + /// The directory for the constants class. + /// + private string mConstantDirectory = "Assets"; + + /// + /// The web client identifier. + /// + private string mWebClientId = string.Empty; + + /// + /// Menus the item for GPGS android setup. + /// + [MenuItem("Window/Google Play Games/Setup/Android setup...", false, 1)] + public static void MenuItemFileGPGSAndroidSetup() + { + EditorWindow window = EditorWindow.GetWindow( + typeof(GPGSAndroidSetupUI), true, GPGSStrings.AndroidSetup.Title); + window.minSize = new Vector2(500, 400); + } + + [MenuItem("Window/Google Play Games/Setup/Android setup...", true)] + public static bool EnableAndroidMenuItem() + { +#if UNITY_ANDROID + return true; +#else + return false; +#endif + } + + /// + /// Performs setup using the Android resources downloaded XML file + /// from the play console. + /// + /// true, if setup was performed, false otherwise. + /// The web client id. + /// the directory to write the constants file to. + /// Fully qualified class name for the resource Ids. + /// Resource xml data. + /// Nearby svc identifier. + /// Indicates this app requires G+ + public static bool PerformSetup( + string clientId, + string classDirectory, + string className, + string resourceXmlData, + string nearbySvcId) + { + if (string.IsNullOrEmpty(resourceXmlData) && + !string.IsNullOrEmpty(nearbySvcId)) + { + return PerformSetup( + clientId, + GPGSProjectSettings.Instance.Get(GPGSUtil.APPIDKEY), + nearbySvcId); + } + + if (ParseResources(classDirectory, className, resourceXmlData)) + { + GPGSProjectSettings.Instance.Set(GPGSUtil.CLASSDIRECTORYKEY, classDirectory); + GPGSProjectSettings.Instance.Set(GPGSUtil.CLASSNAMEKEY, className); + GPGSProjectSettings.Instance.Set(GPGSUtil.ANDROIDRESOURCEKEY, resourceXmlData); + + // check the bundle id and set it if needed. + CheckBundleId(); + + GPGSUtil.CheckAndFixDependencies(); + GPGSUtil.CheckAndFixVersionedAssestsPaths(); + AssetDatabase.Refresh(); + + Google.VersionHandler.VerboseLoggingEnabled = true; + Google.VersionHandler.UpdateVersionedAssets(forceUpdate: true); + Google.VersionHandler.Enabled = true; + AssetDatabase.Refresh(); + + Google.VersionHandler.InvokeStaticMethod( + Google.VersionHandler.FindClass( + "Google.JarResolver", + "GooglePlayServices.PlayServicesResolver"), + "MenuResolve", null); + + return PerformSetup( + clientId, + GPGSProjectSettings.Instance.Get(GPGSUtil.APPIDKEY), + nearbySvcId); + } + + return false; + } + + /// + /// Provide static access to setup for facilitating automated builds. + /// + /// The oauth2 client id for the game. This is only + /// needed if the ID Token or access token are needed. + /// App identifier. + /// Optional nearby connection serviceId + /// Indicates that GooglePlus should be enabled + /// true if successful + public static bool PerformSetup(string webClientId, string appId, string nearbySvcId) + { + if (!string.IsNullOrEmpty(webClientId)) + { + if (!GPGSUtil.LooksLikeValidClientId(webClientId)) + { + GPGSUtil.Alert(GPGSStrings.Setup.ClientIdError); + return false; + } + + string serverAppId = webClientId.Split('-')[0]; + if (!serverAppId.Equals(appId)) + { + GPGSUtil.Alert(GPGSStrings.Setup.AppIdMismatch); + return false; + } + } + + // check for valid app id + if (!GPGSUtil.LooksLikeValidAppId(appId) && string.IsNullOrEmpty(nearbySvcId)) + { + GPGSUtil.Alert(GPGSStrings.Setup.AppIdError); + return false; + } + + if (nearbySvcId != null) + { +#if UNITY_ANDROID + if (!NearbyConnectionUI.PerformSetup(nearbySvcId, true)) + { + return false; + } +#endif + } + + GPGSProjectSettings.Instance.Set(GPGSUtil.APPIDKEY, appId); + GPGSProjectSettings.Instance.Set(GPGSUtil.WEBCLIENTIDKEY, webClientId); + GPGSProjectSettings.Instance.Save(); + GPGSUtil.UpdateGameInfo(); + + // check that Android SDK is there + if (!GPGSUtil.HasAndroidSdk()) + { + Debug.LogError("Android SDK not found."); + EditorUtility.DisplayDialog( + GPGSStrings.AndroidSetup.SdkNotFound, + GPGSStrings.AndroidSetup.SdkNotFoundBlurb, + GPGSStrings.Ok); + return false; + } + + // Generate AndroidManifest.xml + GPGSUtil.GenerateAndroidManifest(); + + // refresh assets, and we're done + AssetDatabase.Refresh(); + GPGSProjectSettings.Instance.Set(GPGSUtil.ANDROIDSETUPDONEKEY, true); + GPGSProjectSettings.Instance.Save(); + + return true; + } + + /// + /// Called when this object is enabled by Unity editor. + /// + public void OnEnable() + { + GPGSProjectSettings settings = GPGSProjectSettings.Instance; + mConstantDirectory = settings.Get(GPGSUtil.CLASSDIRECTORYKEY, mConstantDirectory); + mClassName = settings.Get(GPGSUtil.CLASSNAMEKEY, mClassName); + mConfigData = settings.Get(GPGSUtil.ANDROIDRESOURCEKEY); + mWebClientId = settings.Get(GPGSUtil.WEBCLIENTIDKEY); + } + + /// + /// Called when the GUI should be rendered. + /// + public void OnGUI() + { + GUI.skin.label.wordWrap = true; + GUILayout.BeginVertical(); + + GUIStyle link = new GUIStyle(GUI.skin.label); + link.normal.textColor = new Color(0f, 0f, 1f); + + GUILayout.Space(10); + GUILayout.Label(GPGSStrings.AndroidSetup.Blurb); + if (GUILayout.Button("Open Play Games Console", link, GUILayout.ExpandWidth(false))) + { + Application.OpenURL("https://play.google.com/apps/publish"); + } + + Rect last = GUILayoutUtility.GetLastRect(); + last.y += last.height - 2; + last.x += 3; + last.width -= 6; + last.height = 2; + + GUI.Box(last, string.Empty); + + GUILayout.Space(15); + GUILayout.Label("Constants class name", EditorStyles.boldLabel); + GUILayout.Label("Enter the fully qualified name of the class to create containing the constants"); + GUILayout.Space(10); + + mConstantDirectory = EditorGUILayout.TextField( + "Directory to save constants", + mConstantDirectory, + GUILayout.MinWidth(480)); + + mClassName = EditorGUILayout.TextField( + "Constants class name", + mClassName, + GUILayout.MinWidth(480)); + + GUILayout.Label("Resources Definition", EditorStyles.boldLabel); + GUILayout.Label("Paste in the Android Resources from the Play Console"); + GUILayout.Space(10); + + scroll = GUILayout.BeginScrollView(scroll); + mConfigData = EditorGUILayout.TextArea( + mConfigData, + GUILayout.MinWidth(475), + GUILayout.Height(Screen.height)); + GUILayout.EndScrollView(); + GUILayout.Space(10); + + // Client ID field + GUILayout.Label(GPGSStrings.Setup.WebClientIdTitle, EditorStyles.boldLabel); + GUILayout.Label(GPGSStrings.AndroidSetup.WebClientIdBlurb); + + mWebClientId = EditorGUILayout.TextField( + GPGSStrings.Setup.ClientId, + mWebClientId, + GUILayout.MinWidth(450)); + + GUILayout.Space(10); + + GUILayout.FlexibleSpace(); + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button(GPGSStrings.Setup.SetupButton, GUILayout.Width(100))) + { + // check that the classname entered is valid + try + { + if (GPGSUtil.LooksLikeValidPackageName(mClassName)) + { + DoSetup(); + return; + } + } + catch (Exception e) + { + GPGSUtil.Alert( + GPGSStrings.Error, + "Invalid classname: " + e.Message); + } + } + + if (GUILayout.Button("Cancel", GUILayout.Width(100))) + { + Close(); + } + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.Space(20); + GUILayout.EndVertical(); + } + + /// + /// Starts the setup process. + /// + public void DoSetup() + { + if (PerformSetup(mWebClientId, mConstantDirectory, mClassName, mConfigData, null)) + { + CheckBundleId(); + + EditorUtility.DisplayDialog( + GPGSStrings.Success, + GPGSStrings.AndroidSetup.SetupComplete, + GPGSStrings.Ok); + + GPGSProjectSettings.Instance.Set(GPGSUtil.ANDROIDSETUPDONEKEY, true); + Close(); + } + else + { + GPGSUtil.Alert( + GPGSStrings.Error, + "Invalid or missing XML resource data. Make sure the data is" + + " valid and contains the app_id element"); + } + } + + /// + /// Checks the bundle identifier. + /// + /// + /// Check the package id. If one is set the gpgs properties, + /// and the player settings are the default or empty, set it. + /// if the player settings is not the default, then prompt before + /// overwriting. + /// + public static void CheckBundleId() + { + string packageName = GPGSProjectSettings.Instance.Get( + GPGSUtil.ANDROIDBUNDLEIDKEY, string.Empty); + string currentId; +#if UNITY_5_6_OR_NEWER + currentId = PlayerSettings.GetApplicationIdentifier( + BuildTargetGroup.Android); +#else + currentId = PlayerSettings.bundleIdentifier; +#endif + if (!string.IsNullOrEmpty(packageName)) + { + if (string.IsNullOrEmpty(currentId) || + currentId == "com.Company.ProductName") + { +#if UNITY_5_6_OR_NEWER + PlayerSettings.SetApplicationIdentifier( + BuildTargetGroup.Android, packageName); +#else + PlayerSettings.bundleIdentifier = packageName; +#endif + } + else if (currentId != packageName) + { + if (EditorUtility.DisplayDialog( + "Set Bundle Identifier?", + "The server configuration is using " + + packageName + ", but the player settings is set to " + + currentId + ".\nSet the Bundle Identifier to " + + packageName + "?", + "OK", + "Cancel")) + { +#if UNITY_5_6_OR_NEWER + PlayerSettings.SetApplicationIdentifier( + BuildTargetGroup.Android, packageName); +#else + PlayerSettings.bundleIdentifier = packageName; +#endif + } + } + } + else + { + Debug.Log("NULL package!!"); + } + } + + /// + /// Parses the resources xml and set the properties. Also generates the + /// constants file. + /// + /// true, if resources was parsed, false otherwise. + /// Class directory. + /// Class name. + /// Res. the data to parse. + private static bool ParseResources(string classDirectory, string className, string res) + { + XmlTextReader reader = new XmlTextReader(new StringReader(res)); + bool inResource = false; + string lastProp = null; + Hashtable resourceKeys = new Hashtable(); + string appId = null; + while (reader.Read()) + { + if (reader.Name == "resources") + { + inResource = true; + } + + if (inResource && reader.Name == "string") + { + lastProp = reader.GetAttribute("name"); + } + else if (inResource && !string.IsNullOrEmpty(lastProp)) + { + if (reader.HasValue) + { + if (lastProp == "app_id") + { + appId = reader.Value; + GPGSProjectSettings.Instance.Set(GPGSUtil.APPIDKEY, appId); + } + else if (lastProp == "package_name") + { + GPGSProjectSettings.Instance.Set(GPGSUtil.ANDROIDBUNDLEIDKEY, reader.Value); + } + else + { + resourceKeys[lastProp] = reader.Value; + } + + lastProp = null; + } + } + } + + reader.Close(); + if (resourceKeys.Count > 0) + { + GPGSUtil.WriteResourceIds(classDirectory, className, resourceKeys); + } + + return appId != null; + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs.meta new file mode 100644 index 0000000..fabb847 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 41fe658b93aa24c709c540575965fdff +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs new file mode 100644 index 0000000..4d7c39d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs @@ -0,0 +1,53 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.Editor +{ + using UnityEngine; + using UnityEditor; + + public class GPGSDocsUI + { + [MenuItem("Window/Google Play Games/Documentation/Plugin Getting Started Guide...", false, 100)] + public static void MenuItemGettingStartedGuide() + { + Application.OpenURL(GPGSStrings.ExternalLinks.GettingStartedGuideURL); + } + + [MenuItem("Window/Google Play Games/Documentation/Google Play Games API...", false, 101)] + public static void MenuItemPlayGamesServicesAPI() + { + Application.OpenURL(GPGSStrings.ExternalLinks.PlayGamesServicesApiURL); + } + + [MenuItem("Window/Google Play Games/About/About the Plugin...", false, 300)] + public static void MenuItemAbout() + { + string msg = GPGSStrings.AboutText + + PluginVersion.VersionString + " (" + + string.Format("0x{0:X8}", GooglePlayGames.PluginVersion.VersionInt) + ")"; + EditorUtility.DisplayDialog(GPGSStrings.AboutTitle, msg, + GPGSStrings.Ok); + } + + [MenuItem("Window/Google Play Games/About/License...", false, 301)] + public static void MenuItemLicense() + { + EditorUtility.DisplayDialog(GPGSStrings.LicenseTitle, GPGSStrings.LicenseText, + GPGSStrings.Ok); + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs.meta new file mode 100644 index 0000000..28a45ef --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 73cbcab28a27446ff9e06e06a040814f +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs new file mode 100644 index 0000000..fb55c43 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs @@ -0,0 +1,42 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID +namespace GooglePlayGames.Editor +{ + using System.Collections.Generic; + using System.IO; + using UnityEditor.Callbacks; + using UnityEditor; + using UnityEngine; + + public static class GPGSPostBuild + { + [PostProcessBuild(99999)] + public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) + { + if (!GPGSProjectSettings.Instance.GetBool(GPGSUtil.ANDROIDSETUPDONEKEY, false)) + { + EditorUtility.DisplayDialog("Google Play Games not configured!", + "Warning!! Google Play Games was not configured, Game Services will not work correctly.", + "OK"); + } + + return; + } + } +} +#endif //UNITY_ANDROID \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs.meta new file mode 100644 index 0000000..2cc151f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 1a7b050a8e8214613893df7d81dcc13c +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs new file mode 100644 index 0000000..ea6ae5d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs @@ -0,0 +1,197 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Keep this file even on unsupported configurations. + +namespace GooglePlayGames.Editor +{ + using System.Collections.Generic; + using System.IO; +#if UNITY_2017_3_OR_NEWER + using UnityEngine.Networking; +#else + using UnityEngine; + +#endif + + public class GPGSProjectSettings + { + private static GPGSProjectSettings sInstance = null; + + public static GPGSProjectSettings Instance + { + get + { + if (sInstance == null) + { + sInstance = new GPGSProjectSettings(); + } + + return sInstance; + } + } + + private bool mDirty = false; + private readonly string mFile; + private Dictionary mDict = new Dictionary(); + + private GPGSProjectSettings() + { + mFile = GPGSUtil.SlashesToPlatformSeparator("ProjectSettings/GooglePlayGameSettings.txt"); + + StreamReader rd = null; + + // read the settings file, this list is all the locations it can be in order of precedence. + string[] fileLocations = + { + mFile, + GPGSUtil.SlashesToPlatformSeparator(Path.Combine(GPGSUtil.RootPath, "Editor/projsettings.txt")), + GPGSUtil.SlashesToPlatformSeparator("Assets/Editor/projsettings.txt") + }; + + foreach (string f in fileLocations) + { + if (File.Exists(f)) + { + // assign the reader and break out of the loop + rd = new StreamReader(f); + break; + } + } + + if (rd != null) + { + while (!rd.EndOfStream) + { + string line = rd.ReadLine(); + if (line == null || line.Trim().Length == 0) + { + break; + } + + line = line.Trim(); + string[] p = line.Split(new char[] {'='}, 2); + if (p.Length >= 2) + { + mDict[p[0].Trim()] = p[1].Trim(); + } + } + + rd.Close(); + } + } + + public string Get(string key, Dictionary overrides) + { + if (overrides.ContainsKey(key)) + { + return overrides[key]; + } + else if (mDict.ContainsKey(key)) + { +#if UNITY_2017_3_OR_NEWER + return UnityWebRequest.UnEscapeURL(mDict[key]); +#else + return WWW.UnEscapeURL(mDict[key]); +#endif + } + else + { + return string.Empty; + } + } + + public string Get(string key, string defaultValue) + { + if (mDict.ContainsKey(key)) + { +#if UNITY_2017_3_OR_NEWER + return UnityWebRequest.UnEscapeURL(mDict[key]); +#else + return WWW.UnEscapeURL(mDict[key]); +#endif + } + else + { + return defaultValue; + } + } + + public string Get(string key) + { + return Get(key, string.Empty); + } + + public bool GetBool(string key, bool defaultValue) + { + return Get(key, defaultValue ? "true" : "false").Equals("true"); + } + + public bool GetBool(string key) + { + return Get(key, "false").Equals("true"); + } + + public void Set(string key, string val) + { +#if UNITY_2017_3_OR_NEWER + string escaped = UnityWebRequest.EscapeURL(val); +#else + string escaped = WWW.EscapeURL(val); +#endif + mDict[key] = escaped; + mDirty = true; + } + + public void Set(string key, bool val) + { + Set(key, val ? "true" : "false"); + } + + public void Save() + { + // See if we are building the plugin, and don't write the settings file + string[] args = System.Environment.GetCommandLineArgs(); + foreach (string a in args) + { + if (a == "-g.building") + { + mDirty = false; + break; + } + } + + if (!mDirty) + { + return; + } + + StreamWriter wr = new StreamWriter(mFile, false); + foreach (string key in mDict.Keys) + { + wr.WriteLine(key + "=" + mDict[key]); + } + + wr.Close(); + mDirty = false; + } + + public static void Reload() + { + sInstance = new GPGSProjectSettings(); + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs.meta new file mode 100644 index 0000000..c2926e2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: cf234a050ba25433f9386e20578ccf19 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs new file mode 100644 index 0000000..268e882 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs @@ -0,0 +1,174 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Keep the strings all the time even if on an unsupported configuration. + +namespace GooglePlayGames.Editor +{ + public class GPGSStrings + { + public const string Error = "Error"; + public const string Ok = "OK"; + public const string Cancel = "Cancel"; + public const string Yes = "Yes"; + public const string No = "No"; + public const string Success = "Success"; + public const string Warning = "Warning"; + + public class PostInstall + { + public const string Title = "Google Play Games Plugin for Unity"; + + public const string Text = "The Google Play Games Plugin for Unity version $VERSION " + + "is now ready to use. If this is a new installation or if you have " + + "just upgraded from a previous version, please click the 'Google Play Games' " + + "menu and select 'Android Setup' to set up your project."; + } + + public class Setup + { + public const string AppIdTitle = "Google Play Games Application ID"; + public const string AppId = "Application ID"; + + public const string AppIdBlurb = "Enter your application ID below. This is the numeric\n" + + "identifier provided by the Developer Console (for example, 123456789012)."; + + public const string AppIdError = "The App Id does not appear to be valid. " + + "It must consist solely of digits, usually 10 or more."; + + public const string WebClientIdTitle = "Web App Client ID (Optional)"; + public const string ClientId = "Client ID"; + + public const string ClientIdError = "The Client ID does not appear to be valid. " + + "It should end in .apps.googleusercontent.com."; + + public const string AppIdMismatch = "Web app client ID not associated with this game!"; + + public const string NearbyServiceId = "Nearby Connection Service ID"; + + public const string NearbyServiceBlurb = "Enter the service id that identifies the " + + "nearby connections service scope"; + + public const string SetupButton = "Setup"; + } + + public class NearbyConnections + { + public const string Title = "Google Play Games - Nearby Connections Setup"; + + public const string Blurb = "To configure Nearby Connections in this project,\n" + + "please enter the information below and click on the Setup button."; + + public const string SetupComplete = "Nearby connections configured successfully."; + } + + public class AndroidSetup + { + public const string Title = "Google Play Games - Android Configuration"; + + public const string Blurb = "To configure Google Play Games in this project,\n" + + "go to the Play Game console, then enter the information below and click on the Setup button."; + + public const string WebClientIdBlurb = + "The web app client ID is needed to access the user's ID token and " + + "call other APIs onbehalf of the user." + + " It is not required for Game Services. Enter your oauth2 client ID below.\nTo obtain this " + + "ID, generate a web linked app in Developer Console. Example:\n" + + "123456789012-abcdefghijklm.apps.googleusercontent.com"; + + public const string PkgName = "Package name"; + + public const string PkgNameBlurb = "Enter your application's package name below.\n" + + "(for example, com.example.lorem.ipsum)."; + + public const string PackageNameError = "The package name does not appear to be valid. " + + "Enter a valid Android package name (for example, com.example.lorem.ipsum)."; + + public const string SdkNotFound = "Android SDK Not found"; + + public const string SdkNotFoundBlurb = "The Android SDK path was not found. " + + "Please configure it in the Unity preferences window (under External Tools)."; + + public const string LibProjNotFound = "Google Play Services Library Project Not Found"; + + public const string LibProjNotFoundBlurb = "Google Play Services library project " + + "could not be found your SDK installation. Make sure it is installed (open " + + "the SDK manager and go to Extras, and select Google Play Services)."; + + public const string SupportJarNotFound = "Android Support Library v4 Not Found"; + + public const string SupportJarNotFoundBlurb = "Android Support Library v4 " + + "could not be found your SDK installation. Make sure it is installed (open " + + "the SDK manager and go to Extras, and select 'Android Support Library')."; + + public const string LibProjVerNotFound = "The version of your copy of the Google Play " + + "Services Library Project could not be determined. Please make sure it is " + + "at least version {0}. Continue?"; + + public const string LibProjVerTooOld = "Your copy of the Google Play " + + "Services Library Project is out of date. Please launch the Android SDK manager " + + "and upgrade your Google Play Services bundle to the latest version (your version: " + + "{0}; required version: {1}). Proceeding may cause problems. Proceed anyway?"; + + public const string SetupComplete = "Google Play Games configured successfully."; + } + + public class ExternalLinks + { + public const string GettingStartedGuideURL = + "https://github.com/playgameservices/play-games-plugin-for-unity"; + + public const string PlayGamesServicesApiURL = + "https://developers.google.com/games/services"; + + public const string GooglePlayGamesAndroidSdkTitle = "Google Play Games Android SDK Download"; + + public const string GooglePlayGamesAndroidSdkBlurb = "The Google Play Games SDK for " + + "Android must be downloaded via the Android SDK Manager. Do you wish to " + + "start the SDK manager now?"; + + public const string GooglePlayGamesAndroidSdkInstructions = "The Android SDK manager " + + "will be launched. Install or upgrade the 'Google Play Services' package, " + + "which can be found under the 'Extras' " + + "category."; + + public const string GooglePlayGamesAndroidSdkManagerFailed = "Failed to find the " + + "Android SDK manager executable. Make sure the Android SDK is properly installed " + + "and that its path is correctly configured in the Unity preferences window " + + "(under External Tools)."; + } + + public const string AboutTitle = "Google Play Games Plugin for Unity"; + + public const string AboutText = "Copyright (C) 2014 Google Inc.\n\nThis is an open-source " + + "plugin that allows cross-platform integration with Google Play games services. " + + "For more information, visit the official site on Github:\n\n" + + "https://github.com/playgameservices/play-games-plugin-for-unity\n\nPlugin version: "; + + public const string LicenseTitle = "Google Play Games Plugin for Unity"; + + public const string LicenseText = "Copyright (C) 2014 Google Inc. All Rights Reserved.\n\n" + + "Licensed under the Apache License, Version 2.0 (the \"License\"); " + + "you may not use this file except in compliance with the License. " + + "You may obtain a copy of the License at\n\n" + + " http://www.apache.org/licenses/LICENSE-2.0\n\n" + + "Unless required by applicable law or agreed to in writing, software " + + "distributed under the License is distributed on an \"AS IS\" BASIS, " + + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. " + + "See the License for the specific language governing permissions and " + + "limitations under the License."; + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs.meta new file mode 100644 index 0000000..6c9710b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 992ecb564cf02408d9c5a1b44d958334 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs new file mode 100644 index 0000000..ada7ed1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs @@ -0,0 +1,61 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.Editor +{ + using System.IO; + using UnityEditor; + using UnityEngine; + + /// + /// GPGS upgrader handles performing and upgrade tasks. + /// + [InitializeOnLoad] + public class GPGSUpgrader + { + /// + /// Initializes static members of the class. + /// + static GPGSUpgrader() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; + Debug.Log("GPGSUpgrader start"); + + GPGSProjectSettings.Instance.Set(GPGSUtil.LASTUPGRADEKEY, PluginVersion.VersionKey); + GPGSProjectSettings.Instance.Set(GPGSUtil.PLUGINVERSIONKEY, + PluginVersion.VersionString); + GPGSProjectSettings.Instance.Save(); + + bool isChanged = false; + // Check that there is a AndroidManifest.xml file + if (!GPGSUtil.AndroidManifestExists()) + { + isChanged = true; + GPGSUtil.GenerateAndroidManifest(); + } + + if (isChanged) + { + AssetDatabase.Refresh(); + } + Debug.Log("GPGSUpgrader done"); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs.meta new file mode 100644 index 0000000..4b414fc --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 357a64420a0c44b61a0ed7ca22c7f10f +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs new file mode 100644 index 0000000..4eadb15 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs @@ -0,0 +1,798 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Keep this even on unsupported configurations. + +namespace GooglePlayGames.Editor +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Xml; + using UnityEditor; + using UnityEngine; + + /// + /// Utility class to perform various tasks in the editor. + /// + public static class GPGSUtil + { + /// Property key for project settings. + public const string SERVICEIDKEY = "App.NearbdServiceId"; + + /// Property key for project settings. + public const string APPIDKEY = "proj.AppId"; + + /// Property key for project settings. + public const string CLASSDIRECTORYKEY = "proj.classDir"; + + /// Property key for project settings. + public const string CLASSNAMEKEY = "proj.ConstantsClassName"; + + /// Property key for project settings. + public const string WEBCLIENTIDKEY = "and.ClientId"; + + /// Property key for project settings. + public const string ANDROIDRESOURCEKEY = "and.ResourceData"; + + /// Property key for project settings. + public const string ANDROIDSETUPDONEKEY = "android.SetupDone"; + + /// Property key for project settings. + public const string ANDROIDBUNDLEIDKEY = "and.BundleId"; + + /// Property key for plugin version. + public const string PLUGINVERSIONKEY = "proj.pluginVersion"; + + /// Property key for nearby settings done. + public const string NEARBYSETUPDONEKEY = "android.NearbySetupDone"; + + /// Property key for project settings. + public const string LASTUPGRADEKEY = "lastUpgrade"; + + /// Constant for token replacement + private const string SERVICEIDPLACEHOLDER = "__NEARBY_SERVICE_ID__"; + + private const string SERVICEID_ELEMENT_PLACEHOLDER = "__NEARBY_SERVICE_ELEMENT__"; + + private const string NEARBY_PERMISSIONS_PLACEHOLDER = "__NEARBY_PERMISSIONS__"; + + /// Constant for token replacement + private const string APPIDPLACEHOLDER = "__APP_ID__"; + + /// Constant for token replacement + private const string CLASSNAMEPLACEHOLDER = "__Class__"; + + /// Constant for token replacement + private const string WEBCLIENTIDPLACEHOLDER = "__WEB_CLIENTID__"; + + /// Constant for token replacement + private const string PLUGINVERSIONPLACEHOLDER = "__PLUGIN_VERSION__"; + + /// Constant for require google plus token replacement + private const string REQUIREGOOGLEPLUSPLACEHOLDER = "__REQUIRE_GOOGLE_PLUS__"; + + /// Property key for project settings. + private const string TOKENPERMISSIONKEY = "proj.tokenPermissions"; + + /// Constant for token replacement + private const string NAMESPACESTARTPLACEHOLDER = "__NameSpaceStart__"; + + /// Constant for token replacement + private const string NAMESPACEENDPLACEHOLDER = "__NameSpaceEnd__"; + + /// Constant for token replacement + private const string CONSTANTSPLACEHOLDER = "__Constant_Properties__"; + + /// + /// The game info file path, relative to the plugin root directory. This is a generated file. + /// + private const string GameInfoRelativePath = "Runtime/Scripts/GameInfo.cs"; + + /// + /// The manifest path, relative to the plugin root directory. + /// + /// The Games SDK requires additional metadata in the AndroidManifest.xml + /// file. + private const string ManifestRelativePath = + "../../Plugins/Android/GooglePlayGamesManifest.androidlib/AndroidManifest.xml"; + + private const string RootFolderName = "com.google.play.games"; + + /// + /// The root path of the Google Play Games plugin + /// + public static string RootPath + { + get + { + if (string.IsNullOrEmpty(mRootPath)) + { +#if UNITY_2018_4_OR_NEWER + // Search for root path in plugin locations for both Asset packages and UPM packages + string[] dirs = Directory.GetDirectories("Packages", RootFolderName, SearchOption.AllDirectories); + string[] dir1 = Directory.GetDirectories("Assets", RootFolderName, SearchOption.AllDirectories); + int dirsLength = dirs.Length; + Array.Resize(ref dirs, dirsLength + dir1.Length); + Array.Copy(dir1, 0, dirs, dirsLength, dir1.Length); +#else + string[] dirs = Directory.GetDirectories("Assets", RootFolderName, SearchOption.AllDirectories); +#endif + switch (dirs.Length) + { + case 0: + Alert("Plugin error: com.google.play.games folder was renamed"); + throw new Exception("com.google.play.games folder was renamed"); + + case 1: + mRootPath = SlashesToPlatformSeparator(dirs[0]); + break; + + default: + for (int i = 0; i < dirs.Length; i++) + { + if (File.Exists(SlashesToPlatformSeparator(Path.Combine(dirs[i], GameInfoRelativePath))) + ) + { + mRootPath = SlashesToPlatformSeparator(dirs[i]); + break; + } + } + + if (string.IsNullOrEmpty(mRootPath)) + { + Alert("Plugin error: com.google.play.games folder was renamed"); + throw new Exception("com.google.play.games folder was renamed"); + } + + break; + } + } + // UPM package root path is 'Library/PackageCache/com.google.play.games@.*/ + // where the suffix can be a version number if installed with URS + // or a hash if from disk or tarball + if (mRootPath.Contains(RootFolderName + '@')) + { + mRootPath = mRootPath.Replace("Packages", "Library/PackageCache"); + } + return mRootPath; + } + } + + /// + /// The game info file path. This is a generated file. + /// + private static string GameInfoPath + { + get { return SlashesToPlatformSeparator(Path.Combine(RootPath, GameInfoRelativePath)); } + } + + /// + /// The manifest path. + /// + /// The Games SDK requires additional metadata in the AndroidManifest.xml + /// file. + private static string ManifestPath + { + get { return SlashesToPlatformSeparator(Path.Combine(RootPath, ManifestRelativePath)); } + } + + /// + /// The root path of the Google Play Games plugin + /// + private static string mRootPath = ""; + + /// + /// The map of replacements for filling in code templates. The + /// key is the string that appears in the template as a placeholder, + /// the value is the key into the GPGSProjectSettings. + /// + private static Dictionary replacements = + new Dictionary() + { + // Put this element placeholder first, since it has embedded placeholder + {SERVICEID_ELEMENT_PLACEHOLDER, SERVICEID_ELEMENT_PLACEHOLDER}, + {SERVICEIDPLACEHOLDER, SERVICEIDKEY}, + {APPIDPLACEHOLDER, APPIDKEY}, + {CLASSNAMEPLACEHOLDER, CLASSNAMEKEY}, + {WEBCLIENTIDPLACEHOLDER, WEBCLIENTIDKEY}, + {PLUGINVERSIONPLACEHOLDER, PLUGINVERSIONKEY}, + // Causes the placeholder to be replaced with overridden value at runtime. + {NEARBY_PERMISSIONS_PLACEHOLDER, NEARBY_PERMISSIONS_PLACEHOLDER} + }; + + /// + /// Replaces / in file path to be the os specific separator. + /// + /// The path. + /// Path with correct separators. + public static string SlashesToPlatformSeparator(string path) + { + return path.Replace("/", System.IO.Path.DirectorySeparatorChar.ToString()); + } + + /// + /// Reads the file. + /// + /// The file contents. The slashes are corrected. + /// File path. + public static string ReadFile(string filePath) + { + filePath = SlashesToPlatformSeparator(filePath); + if (!File.Exists(filePath)) + { + Alert("Plugin error: file not found: " + filePath); + return null; + } + + StreamReader sr = new StreamReader(filePath); + string body = sr.ReadToEnd(); + sr.Close(); + return body; + } + + /// + /// Reads the editor template. + /// + /// The editor template contents. + /// Name of the template in the editor directory. + public static string ReadEditorTemplate(string name) + { + return ReadFile( + Path.Combine(RootPath, string.Format("Editor{0}{1}.txt", Path.DirectorySeparatorChar, name))); + } + + /// + /// Writes the file. + /// + /// File path - the slashes will be corrected. + /// Body of the file to write. + public static void WriteFile(string file, string body) + { + file = SlashesToPlatformSeparator(file); + DirectoryInfo dir = Directory.GetParent(file); + dir.Create(); + using (var wr = new StreamWriter(file, false)) + { + wr.Write(body); + } + } + + /// + /// Validates the string to be a valid nearby service id. + /// + /// true, if like valid service identifier was looksed, false otherwise. + /// string to test. + public static bool LooksLikeValidServiceId(string s) + { + if (s.Length < 3) + { + return false; + } + + foreach (char c in s) + { + if (!char.IsLetterOrDigit(c) && c != '.') + { + return false; + } + } + + return true; + } + + /// + /// Looks the like valid app identifier. + /// + /// true, if valid app identifier, false otherwise. + /// the string to test. + public static bool LooksLikeValidAppId(string s) + { + if (s.Length < 5) + { + return false; + } + + foreach (char c in s) + { + if (c < '0' || c > '9') + { + return false; + } + } + + return true; + } + + /// + /// Looks the like valid client identifier. + /// + /// true, if valid client identifier, false otherwise. + /// the string to test. + public static bool LooksLikeValidClientId(string s) + { + return s.EndsWith(".googleusercontent.com"); + } + + /// + /// Looks the like a valid bundle identifier. + /// + /// true, if valid bundle identifier, false otherwise. + /// the string to test. + public static bool LooksLikeValidBundleId(string s) + { + return s.Length > 3; + } + + /// + /// Looks like a valid package. + /// + /// true, if valid package name, false otherwise. + /// the string to test. + public static bool LooksLikeValidPackageName(string s) + { + if (string.IsNullOrEmpty(s)) + { + throw new Exception("cannot be empty"); + } + + string[] parts = s.Split(new char[] {'.'}); + foreach (string p in parts) + { + char[] bytes = p.ToCharArray(); + for (int i = 0; i < bytes.Length; i++) + { + if (i == 0 && !char.IsLetter(bytes[i])) + { + throw new Exception("each part must start with a letter"); + } + else if (char.IsWhiteSpace(bytes[i])) + { + throw new Exception("cannot contain spaces"); + } + else if (!char.IsLetterOrDigit(bytes[i]) && bytes[i] != '_') + { + throw new Exception("must be alphanumeric or _"); + } + } + } + + return parts.Length >= 1; + } + + /// + /// Determines if is setup done. + /// + /// true if is setup done; otherwise, false. + public static bool IsSetupDone() + { + bool doneSetup = true; +#if UNITY_ANDROID + doneSetup = GPGSProjectSettings.Instance.GetBool(ANDROIDSETUPDONEKEY, false); + // check gameinfo + if (File.Exists(GameInfoPath)) + { + string contents = ReadFile(GameInfoPath); + if (contents.Contains(APPIDPLACEHOLDER)) + { + Debug.Log("GameInfo not initialized with AppId. " + + "Run Window > Google Play Games > Setup > Android Setup..."); + return false; + } + } + else + { + Debug.Log("GameInfo.cs does not exist. Run Window > Google Play Games > Setup > Android Setup..."); + return false; + } +#endif + + return doneSetup; + } + + /// + /// Makes legal identifier from string. + /// Returns a legal C# identifier from the given string. The transformations are: + /// - spaces => underscore _ + /// - punctuation => empty string + /// - leading numbers are prefixed with underscore. + /// + /// the id + /// Key to convert to an identifier. + public static string MakeIdentifier(string key) + { + string s; + string retval = string.Empty; + if (string.IsNullOrEmpty(key)) + { + return "_"; + } + + s = key.Trim().Replace(' ', '_'); + + foreach (char c in s) + { + if (char.IsLetterOrDigit(c) || c == '_') + { + retval += c; + } + } + + return retval; + } + + /// + /// Displays an error dialog. + /// + /// the message + public static void Alert(string s) + { + Alert(GPGSStrings.Error, s); + } + + /// + /// Displays a dialog with the given title and message. + /// + /// the title. + /// the message. + public static void Alert(string title, string message) + { + EditorUtility.DisplayDialog(title, message, GPGSStrings.Ok); + } + + /// + /// Gets the android sdk path. + /// + /// The android sdk path. + public static string GetAndroidSdkPath() + { + string sdkPath = EditorPrefs.GetString("AndroidSdkRoot"); +#if UNITY_2019_1_OR_NEWER + // Unity 2019.x added installation of the Android SDK in the AndroidPlayer directory + // so fallback to searching for it there. + if (string.IsNullOrEmpty(sdkPath) || EditorPrefs.GetBool("SdkUseEmbedded")) + { + string androidPlayerDir = BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None); + if (!string.IsNullOrEmpty(androidPlayerDir)) + { + string androidPlayerSdkDir = Path.Combine(androidPlayerDir, "SDK"); + if (Directory.Exists(androidPlayerSdkDir)) + { + sdkPath = androidPlayerSdkDir; + } + } + } +#endif + if (sdkPath != null && (sdkPath.EndsWith("/") || sdkPath.EndsWith("\\"))) + { + sdkPath = sdkPath.Substring(0, sdkPath.Length - 1); + } + + return sdkPath; + } + + /// + /// Determines if the android sdk exists. + /// + /// true if android sdk exists; otherwise, false. + public static bool HasAndroidSdk() + { + string sdkPath = GetAndroidSdkPath(); + return sdkPath != null && sdkPath.Trim() != string.Empty && System.IO.Directory.Exists(sdkPath); + } + + /// + /// Gets the unity major version. + /// + /// The unity major version. + public static int GetUnityMajorVersion() + { +#if UNITY_5 + string majorVersion = Application.unityVersion.Split('.')[0]; + int ver; + if (!int.TryParse(majorVersion, out ver)) + { + ver = 0; + } + + return ver; +#elif UNITY_4_6 + return 4; +#else + return 0; +#endif + } + + /// + /// Checks for the android manifest file exsistance. + /// + /// true, if the file exists false otherwise. + public static bool AndroidManifestExists() + { + string destFilename = ManifestPath; + + return File.Exists(destFilename); + } + + /// + /// Generates the android manifest. + /// + public static void GenerateAndroidManifest() + { + string destFilename = ManifestPath; + + // Generate AndroidManifest.xml + string manifestBody = GPGSUtil.ReadEditorTemplate("template-AndroidManifest"); + + Dictionary overrideValues = + new Dictionary(); + + if (!string.IsNullOrEmpty(GPGSProjectSettings.Instance.Get(SERVICEIDKEY))) + { + overrideValues[NEARBY_PERMISSIONS_PLACEHOLDER] = + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n"; + overrideValues[SERVICEID_ELEMENT_PLACEHOLDER] = + " \n" + + " \n"; + } + else + { + overrideValues[NEARBY_PERMISSIONS_PLACEHOLDER] = ""; + overrideValues[SERVICEID_ELEMENT_PLACEHOLDER] = ""; + } + + foreach (KeyValuePair ent in replacements) + { + string value = + GPGSProjectSettings.Instance.Get(ent.Value, overrideValues); + manifestBody = manifestBody.Replace(ent.Key, value); + } + + GPGSUtil.WriteFile(destFilename, manifestBody); + GPGSUtil.UpdateGameInfo(); + } + + /// + /// Writes the resource identifiers file. This file contains the + /// resource ids copied (downloaded?) from the play game app console. + /// + /// Class directory. + /// Class name. + /// Resource keys. + public static void WriteResourceIds(string classDirectory, string className, Hashtable resourceKeys) + { + string constantsValues = string.Empty; + string[] parts = className.Split('.'); + string dirName = classDirectory; + if (string.IsNullOrEmpty(dirName)) + { + dirName = "Assets"; + } + + string nameSpace = string.Empty; + for (int i = 0; i < parts.Length - 1; i++) + { + dirName += "/" + parts[i]; + if (nameSpace != string.Empty) + { + nameSpace += "."; + } + + nameSpace += parts[i]; + } + + EnsureDirExists(dirName); + foreach (DictionaryEntry ent in resourceKeys) + { + string key = MakeIdentifier((string) ent.Key); + constantsValues += " public const string " + + key + " = \"" + ent.Value + "\"; // \n"; + } + + string fileBody = GPGSUtil.ReadEditorTemplate("template-Constants"); + if (nameSpace != string.Empty) + { + fileBody = fileBody.Replace( + NAMESPACESTARTPLACEHOLDER, + "namespace " + nameSpace + "\n{"); + } + else + { + fileBody = fileBody.Replace(NAMESPACESTARTPLACEHOLDER, string.Empty); + } + + fileBody = fileBody.Replace(CLASSNAMEPLACEHOLDER, parts[parts.Length - 1]); + fileBody = fileBody.Replace(CONSTANTSPLACEHOLDER, constantsValues); + if (nameSpace != string.Empty) + { + fileBody = fileBody.Replace( + NAMESPACEENDPLACEHOLDER, + "}"); + } + else + { + fileBody = fileBody.Replace(NAMESPACEENDPLACEHOLDER, string.Empty); + } + + WriteFile(Path.Combine(dirName, parts[parts.Length - 1] + ".cs"), fileBody); + } + + /// + /// Updates the game info file. This is a generated file containing the + /// app and client ids. + /// + public static void UpdateGameInfo() + { + string fileBody = GPGSUtil.ReadEditorTemplate("template-GameInfo"); + + foreach (KeyValuePair ent in replacements) + { + string value = + GPGSProjectSettings.Instance.Get(ent.Value); + fileBody = fileBody.Replace(ent.Key, value); + } + + GPGSUtil.WriteFile(GameInfoPath, fileBody); + } + + /// + /// Checks the dependencies file and fixes repository paths + /// if they are incorrect (for example if the user moved plugin + /// into some subdirectory). This is a generated file containing + /// the list of dependencies that are needed for the plugin to work. + /// + public static void CheckAndFixDependencies() + { + string depPath = + SlashesToPlatformSeparator(Path.Combine(GPGSUtil.RootPath, + "Editor/GooglePlayGamesPluginDependencies.xml")); + + XmlDocument doc = new XmlDocument(); + doc.Load(depPath); + + XmlNodeList repos = doc.SelectNodes("//androidPackage[contains(@spec,'com.google.games')]//repository"); + foreach (XmlNode repo in repos) + { + if (!Directory.Exists(repo.InnerText)) + { + int pos = repo.InnerText.IndexOf(RootFolderName); + if (pos != -1) + { + repo.InnerText = + Path.Combine(RootPath, repo.InnerText.Substring(pos + RootFolderName.Length + 1)) + .Replace("\\", "/"); + } + } + } + + doc.Save(depPath); + } + + /// + /// Checks the file containing the list of versioned assets and fixes + /// paths to them if they are incorrect (for example if the user moved + /// plugin into some subdirectory). This is a generated file. + /// + public static void CheckAndFixVersionedAssestsPaths() + { + string[] foundPaths = + Directory.GetFiles(RootPath, "GooglePlayGamesPlugin_v*.txt", SearchOption.AllDirectories); + + if (foundPaths.Length == 1) + { + string tmpFilePath = Path.GetTempFileName(); + + StreamWriter writer = new StreamWriter(tmpFilePath); + using (StreamReader reader = new StreamReader(foundPaths[0])) + { + string assetPath; + while ((assetPath = reader.ReadLine()) != null) + { + int pos = assetPath.IndexOf(RootFolderName); + if (pos != -1) + { + assetPath = Path.Combine(RootPath, assetPath.Substring(pos + RootFolderName.Length + 1)) + .Replace("\\", "/"); + } + + writer.WriteLine(assetPath); + } + } + + writer.Flush(); + writer.Close(); + + try + { + File.Copy(tmpFilePath, foundPaths[0], true); + } + finally + { + File.Delete(tmpFilePath); + } + } + } + + /// + /// Ensures the dir exists. + /// + /// Directory to check. + public static void EnsureDirExists(string dir) + { + dir = SlashesToPlatformSeparator(dir); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + } + + /// + /// Deletes the dir if exists. + /// + /// Directory to delete. + public static void DeleteDirIfExists(string dir) + { + dir = SlashesToPlatformSeparator(dir); + if (Directory.Exists(dir)) + { + Directory.Delete(dir, true); + } + } + + /// + /// Gets the Google Play Services library version. This is only + /// needed for Unity versions less than 5. + /// + /// The GPS version. + /// Lib proj path. + private static int GetGPSVersion(string libProjPath) + { + string versionFile = libProjPath + "/res/values/version.xml"; + + XmlTextReader reader = new XmlTextReader(new StreamReader(versionFile)); + bool inResource = false; + int version = -1; + + while (reader.Read()) + { + if (reader.Name == "resources") + { + inResource = true; + } + + if (inResource && reader.Name == "integer") + { + if ("google_play_services_version".Equals( + reader.GetAttribute("name"))) + { + reader.Read(); + Debug.Log("Read version string: " + reader.Value); + version = Convert.ToInt32(reader.Value); + } + } + } + + reader.Close(); + return version; + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs.meta new file mode 100644 index 0000000..7d2b895 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: fd01714f9ee99447996b878b1ac67540 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef b/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef new file mode 100644 index 0000000..6dc51ca --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef @@ -0,0 +1,9 @@ +{ + "name": "Google.Play.Games.Editor", + "references": [ + "Google.Play.Games" + ], + "includePlatforms": [ + "Editor" + ] +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef.meta new file mode 100644 index 0000000..cb17582 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9172e27a923a34eb8b02dc3ab88d3dcd +labels: +- gvh +- gvh_version-2.1.0 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml new file mode 100644 index 0000000..6422381 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml @@ -0,0 +1,13 @@ + + + + + + + Assets/GooglePlayGames/com.google.play.games/Editor/m2repository + + + + \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml.meta new file mode 100644 index 0000000..ada360b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 23be7d2a8d0784f2195988f3ee220ea2 +labels: +- gvh +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt new file mode 100644 index 0000000..a658d5e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt @@ -0,0 +1,100 @@ +Assets/PlayServicesResolver/Editor/play-services-resolver_v1.2.137.0.txt +Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/project.properties +Assets/ExternalDependencyManager/Editor/Google.VersionHandler.pdb +Assets/ExternalDependencyManager/Editor/LICENSE +Assets/ExternalDependencyManager/Editor/CHANGELOG.md +Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll +Assets/ExternalDependencyManager/Editor/README.md +Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.182_manifest.txt +Assets/ExternalDependencyManager/Editor/1.2.182/Google.PackageManagerResolver.pdb +Assets/ExternalDependencyManager/Editor/1.2.182/Google.VersionHandlerImpl.pdb +Assets/ExternalDependencyManager/Editor/1.2.182/Google.VersionHandlerImpl.dll +Assets/ExternalDependencyManager/Editor/1.2.182/Google.PackageManagerResolver.dll +Assets/ExternalDependencyManager/Editor/1.2.182/Google.JarResolver.pdb +Assets/ExternalDependencyManager/Editor/1.2.182/Google.IOSResolver.pdb +Assets/ExternalDependencyManager/Editor/1.2.182/Google.JarResolver.dll +Assets/ExternalDependencyManager/Editor/1.2.182/Google.IOSResolver.dll +Assets/GooglePlayGames/AssemblyInfo.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs +Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs +Assets/GooglePlayGames/com.google.play.games/current-build/GooglePlayGamesPlugin-2.0.0.unitypackage +Assets/GooglePlayGames/com.google.play.games/package.json +Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt +Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt +Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSAndroidSetupUI.cs +Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSPostBuild.cs +Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUtil.cs +Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt +Assets/GooglePlayGames/com.google.play.games/Editor/Google.Play.Games.Editor.asmdef +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSUpgrader.cs +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5 +Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1 +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSStrings.cs +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSDocsUI.cs +Assets/GooglePlayGames/com.google.play.games/Editor/GPGSProjectSettings.cs diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt.meta new file mode 100644 index 0000000..1e73c50 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPlugin_v2.1.0.txt.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2cab45bef89b247bcb7a494b006fdf9b +labels: +- gvh +- gvh_manifest +- gvh_version-2.1.0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs b/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs new file mode 100644 index 0000000..f4cc487 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs @@ -0,0 +1,153 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.Editor +{ + using UnityEngine; + using UnityEditor; + + public class NearbyConnectionUI : EditorWindow + { + private string mNearbyServiceId = string.Empty; + + [MenuItem("Window/Google Play Games/Setup/Nearby Connections setup...", false, 3)] + public static void MenuItemNearbySetup() + { + EditorWindow window = EditorWindow.GetWindow( + typeof(NearbyConnectionUI), true, GPGSStrings.NearbyConnections.Title); + window.minSize = new Vector2(400, 200); + } + + [MenuItem("Window/Google Play Games/Setup/Nearby Connections setup...", true)] + public static bool EnableNearbyMenuItem() + { +#if UNITY_ANDROID + return true; +#else + return false; +#endif + } + + public void OnEnable() + { + mNearbyServiceId = GPGSProjectSettings.Instance.Get(GPGSUtil.SERVICEIDKEY); + } + + public void OnGUI() + { + GUI.skin.label.wordWrap = true; + GUILayout.BeginVertical(); + GUILayout.Space(10); + GUILayout.Label(GPGSStrings.NearbyConnections.Blurb); + GUILayout.Space(10); + + GUILayout.Label(GPGSStrings.Setup.NearbyServiceId, EditorStyles.boldLabel); + GUILayout.Space(10); + GUILayout.Label(GPGSStrings.Setup.NearbyServiceBlurb); + mNearbyServiceId = EditorGUILayout.TextField(GPGSStrings.Setup.NearbyServiceId, + mNearbyServiceId, GUILayout.Width(350)); + + GUILayout.FlexibleSpace(); + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button(GPGSStrings.Setup.SetupButton, + GUILayout.Width(100))) + { + DoSetup(); + } + + if (GUILayout.Button("Cancel", GUILayout.Width(100))) + { + this.Close(); + } + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.Space(20); + GUILayout.EndVertical(); + } + + private void DoSetup() + { + if (PerformSetup(mNearbyServiceId, true)) + { + EditorUtility.DisplayDialog(GPGSStrings.Success, + GPGSStrings.NearbyConnections.SetupComplete, GPGSStrings.Ok); + this.Close(); + } + } + + /// Provide static access to setup for facilitating automated builds. + /// The nearby connections service Id + /// true if building android + public static bool PerformSetup(string nearbyServiceId, bool androidBuild) + { + // check for valid app id + if (!GPGSUtil.LooksLikeValidServiceId(nearbyServiceId)) + { + if (EditorUtility.DisplayDialog( + "Remove Nearby connection permissions? ", + "The service Id is invalid. It must follow package naming rules. " + + "Do you want to remove the AndroidManifest entries for Nearby connections?", + "Yes", + "No")) + { + GPGSProjectSettings.Instance.Set(GPGSUtil.SERVICEIDKEY, null); + GPGSProjectSettings.Instance.Save(); + } + else + { + return false; + } + } + else + { + GPGSProjectSettings.Instance.Set(GPGSUtil.SERVICEIDKEY, nearbyServiceId); + GPGSProjectSettings.Instance.Save(); + } + + if (androidBuild) + { + // create needed directories + GPGSUtil.EnsureDirExists("Assets/Plugins"); + GPGSUtil.EnsureDirExists("Assets/Plugins/Android"); + + // Generate AndroidManifest.xml + GPGSUtil.GenerateAndroidManifest(); + + GPGSProjectSettings.Instance.Set(GPGSUtil.NEARBYSETUPDONEKEY, true); + GPGSProjectSettings.Instance.Save(); + + // Resolve the dependencies + Google.VersionHandler.VerboseLoggingEnabled = true; + Google.VersionHandler.UpdateVersionedAssets(forceUpdate: true); + Google.VersionHandler.Enabled = true; + AssetDatabase.Refresh(); + + Google.VersionHandler.InvokeStaticMethod( + Google.VersionHandler.FindClass( + "Google.JarResolver", + "GooglePlayServices.PlayServicesResolver"), + "MenuResolve", null); + } + + return true; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs.meta new file mode 100644 index 0000000..6e043af --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/NearbyConnectionUI.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b64332a502e18436da5652adbf7e24a3 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository.meta new file mode 100644 index 0000000..b57f758 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a1aac54589c4640cd89900056af3a094 +folderAsset: yes +timeCreated: 1515000812 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta new file mode 100644 index 0000000..d0d5ab2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76a0a965afaf3450c92e9b41b493bbeb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta new file mode 100644 index 0000000..8d48840 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6cb1e99a036f54817b99eeef873b6466 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta new file mode 100644 index 0000000..ef941dd --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e98998ec335bb4358bc79e29457320ae +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta new file mode 100644 index 0000000..81e51fc --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 227f33919ca3d4d60a6040a03cbaa5e9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta new file mode 100644 index 0000000..fad4662 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 097e60ab202a04d96b15903958e8d21f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom new file mode 100644 index 0000000..74cd294 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom @@ -0,0 +1,20 @@ + + + 4.0.0 + com.google.games + gpgs-plugin-support + 2.1.0 + srcaar + + + com.google.android.gms + play-services-games-v2 + 21.0.0 + + + com.google.android.gms + play-services-nearby + 18.5.0 + + + diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5 new file mode 100644 index 0000000..3b82535 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5 @@ -0,0 +1 @@ +bd3bb3899a24c1a87d597832701e7bcf \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5.meta new file mode 100644 index 0000000..4389a5d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.md5.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6c7298e4e719d4b4385fdbd461a80e16 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta new file mode 100644 index 0000000..1f0373e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 77c5e5feaf1bb418eb5dee0b81092649 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1 new file mode 100644 index 0000000..300fed1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1 @@ -0,0 +1 @@ +db337ca4a8846cf7b71dc54e408ef6702955ebd7 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1.meta new file mode 100644 index 0000000..b68d1fa --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha1.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8341b2c3a48474fa1844e4abb5680cb3 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256 new file mode 100644 index 0000000..1c3cebc --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256 @@ -0,0 +1 @@ +a470877748a60d4edc3ec1773906e069a06dd1481fde054f700e4ab0ae698728 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256.meta new file mode 100644 index 0000000..cd39299 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha256.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e6b6a3e652c5a492ab2801cd91083291 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512 new file mode 100644 index 0000000..961c82e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512 @@ -0,0 +1 @@ +499a85fbba0d49e29f1bcbd369b691b0fc8f12b74c68e9d85ffc0e2264ae49081b4decac323579ebbde56523df194ddac932adcfd7169d59044e39f53a179833 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512.meta new file mode 100644 index 0000000..5c5da01 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom.sha512.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b240939517fec40b4865e09113e40a67 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar new file mode 100644 index 0000000..6b9fc56 Binary files /dev/null and b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar differ diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5 new file mode 100644 index 0000000..6353382 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5 @@ -0,0 +1 @@ +e894d7c1af62ede159e7606c32166717 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5.meta new file mode 100644 index 0000000..2b39b5c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.md5.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: be12aa927c7cf4436b9e41baec85bc56 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.meta new file mode 100644 index 0000000..ac4c1a2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b05cec21e440d40d292505bdd9f0872a +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1 new file mode 100644 index 0000000..440bba1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1 @@ -0,0 +1 @@ +33458933461584ac9187cf85bef90da9c380856c \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1.meta new file mode 100644 index 0000000..9212271 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha1.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7fad262fe84ae4755bb1e5992d0bb0fe +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256 new file mode 100644 index 0000000..c826c16 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256 @@ -0,0 +1 @@ +52ba335460015c31f4f2aec66a28f2ae1e6338741ed03f75a792fbc248d279bb \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256.meta new file mode 100644 index 0000000..40222b7 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha256.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b355faca70a7f4859836cfd5bb5107db +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512 new file mode 100644 index 0000000..ff6f0a8 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512 @@ -0,0 +1 @@ +fba25ef5bc17ef310ad5b6b95c3e821e1e710b23167b9f3452cdd2ebe6b9dddbdc743fd23a9fa5a6565fee9a30562aa0e305579ca251966a8786dac50d6525a2 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512.meta new file mode 100644 index 0000000..7447cc8 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.srcaar.sha512.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7c8d8706ef3f5409d86d34690d62e5a7 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml new file mode 100644 index 0000000..c183b34 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml @@ -0,0 +1,13 @@ + + + com.google.games + gpgs-plugin-support + + 2.1.0 + 2.1.0 + + 2.1.0 + + 20250708083250 + + diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5 new file mode 100644 index 0000000..609a552 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5 @@ -0,0 +1 @@ +1a6ee98875ac2e9f5377a1927aad50bd \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5.meta new file mode 100644 index 0000000..2ea5bd5 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.md5.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: df1b97918a3cb4607a87f7d357adfee7 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.meta new file mode 100644 index 0000000..97a5311 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5e7cbb11d2cd04f6380a65c16715e9a4 +labels: +- gvh +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1 new file mode 100644 index 0000000..af4f38d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +713cb8be9f9968cbf68130abde91a6a08147535f \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1.meta new file mode 100644 index 0000000..db1e586 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha1.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a43cf6ce24a034a94bed8334f57647a7 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256 new file mode 100644 index 0000000..0e887f3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256 @@ -0,0 +1 @@ +8efe76e7d3745bc3722234db7e6922a89c5b2aa6620a5cfb532a8ddb87649bf9 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256.meta new file mode 100644 index 0000000..91642c2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha256.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 42a80f9d5c82741178cc211096f64370 +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512 b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512 new file mode 100644 index 0000000..9f45d5f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512 @@ -0,0 +1 @@ +add19f532d7d142f9f0a247a9c7e37dc4772b866c8672a05e881a7d6eba5bcff90c2119478e9a5965e4fd5b18bced11c27056eb78e06abb47e558f9c14b38997 \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512.meta new file mode 100644 index 0000000..31cf8dc --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/maven-metadata.xml.sha512.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 22b2c04f6a22f4165aab5a886ce75b1e +labels: +- gvh +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt b/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt new file mode 100644 index 0000000..d32616f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt @@ -0,0 +1,27 @@ + + + + + __NEARBY_PERMISSIONS__ + + + + __NEARBY_SERVICE_ELEMENT__ + + + + + + + + + + + diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt.meta new file mode 100644 index 0000000..9de8d79 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-AndroidManifest.txt.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0e1f3c150256848b1ba98702cfb71220 +labels: +- gvh +- gvh_version-2.1.0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt b/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt new file mode 100644 index 0000000..a1a6180 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt @@ -0,0 +1,29 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/// +/// This file is automatically generated DO NOT EDIT! +/// +/// These are the constants defined in the Play Games Console for Game Services +/// Resources. +/// + +__NameSpaceStart__ +public static class __Class__ +{ +__Constant_Properties__ +} +__NameSpaceEnd__ diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt.meta new file mode 100644 index 0000000..4d142a6 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-Constants.txt.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7f2719cb8be514661b7b6aa9986bfe5f +labels: +- gvh +- gvh_version-2.1.0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt b/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt new file mode 100644 index 0000000..47bb16a --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt @@ -0,0 +1,71 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID + +namespace GooglePlayGames { + /// + /// This file is automatically generated DO NOT EDIT! + /// + /// These are the constants defined in the Play Games Console for Game Services + /// Resources. + /// + /// + /// File containing information about the game. This is automatically updated by running the + /// platform-appropriate setup commands in the Unity editor (which does a simple search / replace + /// on the IDs in the form "__ID__"). We can check whether any particular field has been updated + /// by checking whether it still retains its initial value - we prevent the constants from being + /// replaced in the aforementioned search/replace by stripping off the leading and trailing "__". + /// + public static class GameInfo { + + private const string UnescapedApplicationId = "APP_ID"; + private const string UnescapedIosClientId = "IOS_CLIENTID"; + private const string UnescapedWebClientId = "WEB_CLIENTID"; + private const string UnescapedNearbyServiceId = "NEARBY_SERVICE_ID"; + + public const string ApplicationId = "__APP_ID__"; // Filled in automatically + public const string IosClientId = "__IOS_CLIENTID__"; // Filled in automatically + public const string WebClientId = "__WEB_CLIENTID__"; // Filled in automatically + public const string NearbyConnectionServiceId = "__NEARBY_SERVICE_ID__"; + + public static bool ApplicationIdInitialized() { + return !string.IsNullOrEmpty(ApplicationId) && !ApplicationId.Equals(ToEscapedToken(UnescapedApplicationId)); + } + + public static bool IosClientIdInitialized() { + return !string.IsNullOrEmpty(IosClientId) && !IosClientId.Equals(ToEscapedToken(UnescapedIosClientId)); + } + + public static bool WebClientIdInitialized() { + return !string.IsNullOrEmpty(WebClientId) && !WebClientId.Equals(ToEscapedToken(UnescapedWebClientId)); + } + + public static bool NearbyConnectionsInitialized() { + return !string.IsNullOrEmpty(NearbyConnectionServiceId) && + !NearbyConnectionServiceId.Equals(ToEscapedToken(UnescapedNearbyServiceId)); + } + + /// + /// Returns an escaped token (i.e. one flanked with "__") for the passed token + /// + /// The escaped token. + /// The Token + private static string ToEscapedToken(string token) { + return string.Format("__{0}__", token); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt.meta b/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt.meta new file mode 100644 index 0000000..2495e33 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c6fa1c0456d174d298bf8dd66f584e9e +labels: +- gvh +- gvh_version-2.1.0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Proguard.meta b/Assets/GooglePlayGames/com.google.play.games/Proguard.meta new file mode 100644 index 0000000..90a11ae --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Proguard.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 34de77d5a35fb46aeae90de4ad11647b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt b/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt new file mode 100644 index 0000000..63c7b08 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt @@ -0,0 +1,20 @@ +-keep class com.google.android.gms.games.leaderboard.** { *; } +-keep class com.google.android.gms.games.snapshot.** { *; } +-keep class com.google.android.gms.games.achievement.** { *; } +-keep class com.google.android.gms.games.event.** { *; } +-keep class com.google.android.gms.games.stats.** { *; } +-keep class com.google.android.gms.games.* { *; } +-keep class com.google.android.gms.common.api.ResultCallback { *; } +-keep class com.google.android.gms.signin.** { *; } +-keep class com.google.android.gms.dynamic.** { *; } +-keep class com.google.android.gms.dynamite.** { *; } +-keep class com.google.android.gms.tasks.** { *; } +-keep class com.google.android.gms.security.** { *; } +-keep class com.google.android.gms.base.** { *; } +-keep class com.google.android.gms.actions.** { *; } +-keep class com.google.games.bridge.** { *; } +-keep class com.google.android.gms.common.ConnectionResult { *; } +-keep class com.google.android.gms.common.GooglePlayServicesUtil { *; } +-keep class com.google.android.gms.common.api.** { *; } +-keep class com.google.android.gms.common.data.DataBufferUtils { *; } +-keep class com.google.android.gms.nearby.** { *; } diff --git a/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt.meta b/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt.meta new file mode 100644 index 0000000..283c644 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Proguard/games.txt.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3617310a589994e39a2cc011f0758cbf +labels: +- gvh +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime.meta new file mode 100644 index 0000000..989edc1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cdb02382f873f45598f111dc70b3b47e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef b/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef new file mode 100644 index 0000000..887a518 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef @@ -0,0 +1,7 @@ +{ + "name": "Google.Play.Games", + "includePlatforms": [ + "Android", + "Editor" + ] +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef.meta new file mode 100644 index 0000000..1502fc2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Google.Play.Games.asmdef.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1ed07ff861e5f468287b0baef844706d +labels: +- gvh +- gvh_version-2.1.0 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts.meta new file mode 100644 index 0000000..ee8be37 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee74fb8a25a6e4adea15f4675bac5756 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi.meta new file mode 100644 index 0000000..80e1ea0 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 0a565e85253b345878939982a360e0b6 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs new file mode 100644 index 0000000..738e6fb --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs @@ -0,0 +1,201 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System; + + /// Data interface for retrieving achievement information. + /// + /// There are 3 states an achievement can be in: + /// + /// Hidden - indicating the name and description of the achievement is + /// not visible to the player. + /// + /// Revealed - indicating the name and description of the achievement is + /// visible to the player. + /// Unlocked - indicating the player has unlocked, or achieved, the achievment. + /// + /// Achievements has two types, standard which is unlocked in one step, + /// and incremental, which require multiple steps to unlock. + /// + /// + public class Achievement + { + static readonly DateTime UnixEpoch = + new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + + private string mId = string.Empty; + private bool mIsIncremental = false; + private bool mIsRevealed = false; + private bool mIsUnlocked = false; + private int mCurrentSteps = 0; + private int mTotalSteps = 0; + private string mDescription = string.Empty; + private string mName = string.Empty; + private long mLastModifiedTime = 0; + private ulong mPoints; + private string mRevealedImageUrl; + private string mUnlockedImageUrl; + + /// + /// Returns a that represents the current . + /// + /// A that represents the current . + public override string ToString() + { + return string.Format( + "[Achievement] id={0}, name={1}, desc={2}, type={3}, revealed={4}, unlocked={5}, steps={6}/{7}", + mId, mName, mDescription, mIsIncremental ? "INCREMENTAL" : "STANDARD", + mIsRevealed, mIsUnlocked, mCurrentSteps, mTotalSteps); + } + + public Achievement() + { + } + + /// + /// Indicates whether this achievement is incremental. + /// + public bool IsIncremental + { + get { return mIsIncremental; } + + set { mIsIncremental = value; } + } + + /// + /// The number of steps the user has gone towards unlocking this achievement. + /// + public int CurrentSteps + { + get { return mCurrentSteps; } + + set { mCurrentSteps = value; } + } + + /// + /// The total number of steps needed to unlock this achievement. + /// + public int TotalSteps + { + get { return mTotalSteps; } + + set { mTotalSteps = value; } + } + + /// + /// Indicates whether the achievement is unlocked or not. + /// + public bool IsUnlocked + { + get { return mIsUnlocked; } + + set { mIsUnlocked = value; } + } + + /// + /// Indicates whether the achievement is revealed or not (hidden). + /// + public bool IsRevealed + { + get { return mIsRevealed; } + + set { mIsRevealed = value; } + } + + /// + /// The ID string of this achievement. + /// + public string Id + { + get { return mId; } + + set { mId = value; } + } + + /// + /// The description of this achievement. + /// + public string Description + { + get { return this.mDescription; } + + set { mDescription = value; } + } + + /// + /// The name of this achievement. + /// + public string Name + { + get { return this.mName; } + + set { mName = value; } + } + + /// + /// The date and time the state of the achievement was modified. + /// + /// + /// The value is invalid (-1 long) if the achievement state has + /// never been updated. + /// + public DateTime LastModifiedTime + { + get { return UnixEpoch.AddMilliseconds(mLastModifiedTime); } + + set + { + TimeSpan ts = value - UnixEpoch; + mLastModifiedTime = (long) ts.TotalMilliseconds; + } + } + + /// + /// The number of experience points earned for unlocking this Achievement. + /// + public ulong Points + { + get { return mPoints; } + + set { mPoints = value; } + } + + /// + /// The URL to the image to display when the achievement is revealed. + /// + public string RevealedImageUrl + { + get { return mRevealedImageUrl; } + + set { mRevealedImageUrl = value; } + } + + /// + /// The URL to the image to display when the achievement is unlocked. + /// + public string UnlockedImageUrl + { + get { return mUnlockedImageUrl; } + + set { mUnlockedImageUrl = value; } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs.meta new file mode 100644 index 0000000..4af8146 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Achievement.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b20fc2fda369044ba962d1d9115c4c63 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs new file mode 100644 index 0000000..b33d6c2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs @@ -0,0 +1,104 @@ +// +// Copyright (C) 2025 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID +namespace GooglePlayGames.BasicApi +{ + using System; + using System.Collections.Generic; + + /// + /// Represents the response received from Play Games Services when requesting a server-side OAuth 2.0 + /// authorization code for the signed-in player. + /// + public class AuthResponse + { + private readonly string _authCode; + private readonly List _grantedScopes; + + /// + /// Constructs an AuthResponse with the provided granted scopes and authentication code. + /// + /// The authentication code. + /// A list of AuthScope objects representing the granted scopes. + /// If grantedScopes is null. + public AuthResponse(string authCode, List grantedScopes) + { + if (grantedScopes == null) + { + throw new ArgumentNullException(nameof(grantedScopes), "Granted scopes list cannot be null"); + } + + _authCode = authCode; + _grantedScopes = grantedScopes; + } + + + /// + /// Gets the list of AuthScope permissions that the user has granted. + /// + /// + /// A list of the AuthScope permissions the user explicitly granted consent for (or + /// previously approved). The list will be empty if the user declines consent and none of the + /// requested AuthScope were previously granted. + /// + /// A List of AuthScope objects, representing the granted permissions. + public List GetGrantedScopes() + { + return _grantedScopes; + } + + /// + /// Gets the OAuth 2.0 authorization code. + /// + /// + /// This code is a short-lived credential that should be sent securely to your server to be + /// exchanged for an access token and conditionally a refresh token. + /// + /// A string containing the OAuth 2.0 authorization code. + public string GetAuthCode() + { + return _authCode; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + + var other = (AuthResponse)obj; + return _grantedScopes.Equals(other._grantedScopes) && _authCode == other._authCode; + } + + public override int GetHashCode() + { + return HashCode.Combine(_grantedScopes, _authCode); + } + + public override string ToString() + { + string grantedScopesText = _grantedScopes.Count > 0 ? string.Join(", ", _grantedScopes.ToArray()) : "[]"; + return $"AuthResponse {{ grantedScopes = {grantedScopesText}, authCode = {_authCode} }}"; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs.meta new file mode 100644 index 0000000..66605dd --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthResponse.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d31e1b3df27554441b81c35d645a008a +labels: +- gvh +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs new file mode 100644 index 0000000..ac2bee7 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs @@ -0,0 +1,102 @@ +// +// Copyright (C) 2025 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID +namespace GooglePlayGames.BasicApi +{ + using System; + using System.Collections.Generic; + using System.Linq; + + /// + /// Represents type-safe constants for the specific OAuth 2.0 authorization scopes used when + /// requesting server-side access to Play Games Services web APIs. + /// + public enum AuthScope + { + /// + /// See your primary Google Account email address. + /// + EMAIL, + + /// + /// See your personal info, including any personal info you've made publicly available. + /// + PROFILE, + + /// + /// Associate you with your personal info on Google. + /// + OPEN_ID + } + + /// + /// Extensions for the AuthScope enum. + /// + /// These extensions are used to converting between the AuthScope enum and its string + /// representation. + /// + /// + public static class AuthScopeExtensions + { + /// + /// A map of AuthScope string values to their enum representations. + /// + private static readonly Dictionary _stringToEnumMap = + new Dictionary + { + { "EMAIL", AuthScope.EMAIL }, + { "PROFILE", AuthScope.PROFILE }, + { "OPEN_ID", AuthScope.OPEN_ID } + }; + + /// + /// A map of AuthScope enum values to their string representations. + /// + private static readonly Dictionary _enumToStringMap = + _stringToEnumMap.ToDictionary(pair => pair.Value, pair => pair.Key); + + /// + /// Returns the standard string representation of this OAuth 2.0 scope. + /// + /// The AuthScope enum value. + /// The string value used to represent this scope. + /// If the provided AuthScope is not valid. + public static string GetValue(this AuthScope authScope) + { + if (!_enumToStringMap.ContainsKey(authScope)) + { + throw new ArgumentException($"Invalid AuthScope: {authScope}"); + } + return _enumToStringMap[authScope]; + } + + /// + /// Returns the AuthScope enum value corresponding to the provided string. + /// + /// The string value used to represent the scope. + /// The AuthScope enum value corresponding to the provided string. + /// If the provided string is not a valid AuthScope. + public static AuthScope FromValue(string value) + { + if (!_stringToEnumMap.ContainsKey(value)) + { + throw new ArgumentException($"Invalid AuthScope: {value}"); + } + return _stringToEnumMap[value]; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs.meta new file mode 100644 index 0000000..81144fe --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/AuthScope.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 46024b30df48146d9a58760a6b9e188e +labels: +- gvh +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs new file mode 100644 index 0000000..a40cc4b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs @@ -0,0 +1,100 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + /// + /// Common status codes. + /// See https://developers.google.com/android/reference/com/google/android/gms/common/api/CommonStatusCodes + /// + public enum CommonStatusCodes + { + /// The operation was successful, but the device's cache was used. + SuccessCached = -1, + + /// The operation was successful. + Success = 0, + + /// Google Play services is missing on this device. + ServiceMissing = 1, + + /// The installed version of Google Play services is out of date. + ServiceVersionUpdateRequired = 2, + + /// The installed version of Google Play services has been disabled on this device. + ServiceDisabled = 3, + + /// The client attempted to connect to the service but the user is not signed in. + SignInRequired = 4, + + /// The client attempted to connect to the service with an invalid account name specified. + InvalidAccount = 5, + + /// Completing the operation requires some form of resolution. + ResolutionRequired = 6, + + /// A network error occurred. + NetworkError = 7, + + /// An internal error occurred. + InternalError = 8, + + /// The version of the Google Play services installed on this device is not authentic. + ServiceInvalid = 9, + + /// The application is misconfigured. + DeveloperError = 10, + + /// The application is not licensed to the user. + LicenseCheckFailed = 11, + + /// The operation failed with no more detailed information. + Error = 13, + + /// A blocking call was interrupted while waiting and did not run to completion. + Interrupted = 14, + + /// Timed out while awaiting the result. + Timeout = 15, + + /// The result was canceled either due to client disconnect or cancel(). + Canceled = 16, + + /// The client attempted to call a method from an API that failed to connect. + ApiNotConnected = 17, + + /// Invalid credentials were provided. + AuthApiInvalidCredentials = 3000, + + /// Access is forbidden. + AuthApiAccessForbidden = 3001, + + /// Error related to the client. + AuthApiClientError = 3002, + + /// Error related to the server. + AuthApiServerError = 3003, + + /// Error related to token. + AuthTokenError = 3004, + + /// Error related to auth URL resolution. + AuthUrlResolution = 3005 + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs.meta new file mode 100644 index 0000000..0df4b9d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonStatusCodes.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: cd54f7a2763f74ce191bdd3efa0a44d5 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs new file mode 100644 index 0000000..3c8579c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs @@ -0,0 +1,214 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi +{ + /// + /// A enum describing where game data can be fetched from. + /// + public enum DataSource + { + /// + /// Allow a read from either a local cache, or the network. + /// + /// Values from the cache may be + /// stale (potentially producing more write conflicts), but reading from cache may still + /// allow reads to succeed if the device does not have internet access and may complete more + /// quickly (as the reads can occur locally rather requiring network roundtrips). + /// + ReadCacheOrNetwork, + + /// + /// Only allow reads from network. + /// + /// This guarantees any returned values were current at the time + /// the read succeeded, but prevents reads from succeeding if the network is unavailable for + /// any reason. + /// + ReadNetworkOnly + } + + /// Native response status codes + /// These values are returned by the native SDK API. + /// NOTE: These values are different than the CommonStatusCodes. + /// + public enum ResponseStatus + { + /// The operation was successful. + Success = 1, + + /// The operation was successful, but the device's cache was used. + SuccessWithStale = 2, + + /// The application is not licensed to the user. + LicenseCheckFailed = -1, + + /// An internal error occurred. + InternalError = -2, + + /// The player is not authorized to perform the operation. + NotAuthorized = -3, + + /// The installed version of Google Play services is out of date. + VersionUpdateRequired = -4, + + /// Timed out while awaiting the result. + Timeout = -5, + + ///< summary> + /// Constant indicating that the developer does not have access to the friends list, but can + /// call the AskForLoadFriendsResolution API to show a consent dialog. + /// + ResolutionRequired = -6, + } + + /// Native response status codes for UI operations. + /// These values are returned by the native SDK API. + /// + public enum UIStatus + { + /// The result is valid. + Valid = 1, + + /// An internal error occurred. + InternalError = -2, + + /// The player is not authorized to perform the operation. + NotAuthorized = -3, + + /// The installed version of Google Play services is out of date. + VersionUpdateRequired = -4, + + /// Timed out while awaiting the result. + Timeout = -5, + + /// UI closed by user. + UserClosedUI = -6, + UiBusy = -12, + + /// An network error occurred. + NetworkError = -20, + } + + /// Values specifying the start location for fetching scores. + public enum LeaderboardStart + { + /// Start fetching scores from the top of the list. + TopScores = 1, + + /// Start fetching relative to the player's score. + PlayerCentered = 2, + } + + /// Values specifying which leaderboard timespan to use. + public enum LeaderboardTimeSpan + { + /// Daily scores. The day resets at 11:59 PM PST. + Daily = 1, + + /// Weekly scores. The week resets at 11:59 PM PST on Sunday. + Weekly = 2, + + /// All time scores. + AllTime = 3, + } + + /// Values specifying which leaderboard collection to use. + public enum LeaderboardCollection + { + /// Public leaderboards contain the scores of players who are sharing their gameplay publicly. + Public = 1, + + /// Social leaderboards contain the scores of players in the viewing player's circles. + Social = 2, + } + + /// Values specifying the visibility status of the friends list. + public enum FriendsListVisibilityStatus + { + ///< summary> + /// Constant indicating that currently it's unknown if the friends list is visible to the + /// game, game can ask for permission from user. + /// + Unknown = 0, + + /// Constant indicating that the friends list is currently visible to the game. + Visible = 1, + + ///< summary> + /// Constant indicating that the developer does not have access to the friends list, but can + /// call the AskForLoadFriendsResolution API to show a consent dialog. + /// + ResolutionRequired = 2, + + ///< summary> + /// Constant indicating that the friends list is currently unavailable for this user, and it + /// is not possible to request access at this time, either because the user has permanently + /// declined or the friends feature is not available to them. In this state, any attempts to + /// request + /// access to the friends list will be unsuccessful. + /// + Unavailable = 3, + + /// An network error occurred. + NetworkError = -4, + + /// The player is not authorized to perform the operation. + NotAuthorized = -5, + } + + /// Values specifying the status of the friends list. + public enum LoadFriendsStatus + { + /// An unknown value to return when loadFriends is not available. + Unknown = 0, + + /// All the friends have been loaded. + Completed = 1, + + /// There are more friends to load. + LoadMore = 2, + + /// + /// The game doesn't have permission to access the player's friends list. No friends loaded. + /// + ResolutionRequired = -3, + + /// An internal error occurred. + InternalError = -4, + + /// The player is not authorized to perform the operation. + NotAuthorized = -5, + + /// An network error occurred. + NetworkError = -6, + } + + /// + /// Utility class for common types. + /// This class checks if a response status is a success or not. + /// + public class CommonTypesUtil + { + /// + /// Checks if a response status is a success or not. + /// + public static bool StatusIsSuccess(ResponseStatus status) + { + return ((int) status) > 0; + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs.meta new file mode 100644 index 0000000..2f68f82 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/CommonTypes.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 1c5d1cb1974d14c0c8b32fcf00089556 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs new file mode 100644 index 0000000..af03d90 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs @@ -0,0 +1,495 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.OurUtils; + using UnityEngine.SocialPlatforms; + + /// + /// Dummy client used in Editor. + /// + /// Google Play Game Services are not supported in the Editor + /// environment, so this client is used as a placeholder. + /// + public class DummyClient : IPlayGamesClient + { + /// + /// Authenticates the user. + /// + /// Callback to handle the sign-in status. + public void Authenticate(Action callback) + { + LogUsage(); + if (callback != null) + { + callback(SignInStatus.Canceled); + } + } + + /// + /// Manually authenticates the user. + /// + /// Callback to handle the sign-in status. + public void ManuallyAuthenticate(Action callback) + { + LogUsage(); + if (callback != null) + { + callback(SignInStatus.Canceled); + } + } + + /// + /// Checks if the user is authenticated. + /// + /// Returns false indicating user is not authenticated. + public bool IsAuthenticated() + { + LogUsage(); + return false; + } + + /// + /// Requests server-side access with a refresh token. + /// + /// Flag to force refresh the token. + /// Callback to handle the response. + public void RequestServerSideAccess(bool forceRefreshToken, Action callback) + { + LogUsage(); + if (callback != null) + { + callback(null); + } + } + + /// + /// Requests server-side access with specific scopes. + /// + /// Flag to force refresh the token. + /// List of requested authorization scopes. + /// Callback to handle the response. + public void RequestServerSideAccess(bool forceRefreshToken, List scopes, Action callback) + { + LogUsage(); + if (callback != null) + { + callback(null); + } + } + + /// + /// Requests recall of the access token. + /// + /// Callback to handle the recall response. + public void RequestRecallAccessToken(Action callback) + { + LogUsage(); + if (callback != null) + { + callback(null); + } + } + + /// + /// Retrieves the user ID. + /// + /// Returns a dummy user ID. + public string GetUserId() + { + LogUsage(); + return "DummyID"; + } + + /// + /// Retrieves the player statistics. + /// + /// Callback to handle the player stats response. + public void GetPlayerStats(Action callback) + { + LogUsage(); + callback(CommonStatusCodes.ApiNotConnected, new PlayerStats()); + } + + /// + /// Retrieves the user's display name. + /// + /// Returns a dummy display name. + public string GetUserDisplayName() + { + LogUsage(); + return "Player"; + } + + /// + /// Retrieves the user's image URL. + /// + /// Returns null since no image is available. + public string GetUserImageUrl() + { + LogUsage(); + return null; + } + + /// + /// Loads user profiles for the given user IDs. + /// + /// List of user IDs. + /// Callback to handle the user profile response. + public void LoadUsers(string[] userIds, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(null); + } + } + + /// + /// Loads achievements for the current user. + /// + /// Callback to handle the achievement response. + public void LoadAchievements(Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(null); + } + } + + /// + /// Unlocks the specified achievement. + /// + /// The achievement ID to unlock. + /// Callback to handle the unlock result. + public void UnlockAchievement(string achId, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Reveals the specified achievement. + /// + /// The achievement ID to reveal. + /// Callback to handle the reveal result. + public void RevealAchievement(string achId, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Increments the specified achievement by a number of steps. + /// + /// The achievement ID to increment. + /// The number of steps to increment the achievement. + /// Callback to handle the increment result. + public void IncrementAchievement(string achId, int steps, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Sets the steps of the specified achievement to at least a certain number. + /// + /// The achievement ID to update. + /// The number of steps to set. + /// Callback to handle the result of setting the steps. + public void SetStepsAtLeast(string achId, int steps, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Displays the achievements UI. + /// + /// Callback to handle the UI status. + public void ShowAchievementsUI(Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(UIStatus.VersionUpdateRequired); + } + } + + /// + /// Requests the load friends resolution UI. + /// + /// Callback to handle the UI status. + public void AskForLoadFriendsResolution(Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(UIStatus.VersionUpdateRequired); + } + } + + /// + /// Retrieves the last load friends status. + /// + /// Returns the last known load friends status. + public LoadFriendsStatus GetLastLoadFriendsStatus() + { + LogUsage(); + return LoadFriendsStatus.Unknown; + } + + /// + /// Loads friends with paging options. + /// + /// The number of friends to load per page. + /// Flag to force reload of the friends list. + /// Callback to handle the load friends status. + public void LoadFriends(int pageSize, bool forceReload, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(LoadFriendsStatus.Unknown); + } + } + + /// + /// Loads additional friends if available. + /// + /// The number of additional friends to load. + /// Callback to handle the load friends status. + public void LoadMoreFriends(int pageSize, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(LoadFriendsStatus.Unknown); + } + } + + /// + /// Displays the compare profile UI for a player. + /// + /// The user ID of the player to compare. + /// The in-game name of the other player. + /// The in-game name of the current player. + /// Callback to handle the UI status. + public void ShowCompareProfileWithAlternativeNameHintsUI(string userId, + string otherPlayerInGameName, + string currentPlayerInGameName, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(UIStatus.VersionUpdateRequired); + } + } + + /// + /// Retrieves the visibility status of the friends list. + /// + /// Flag to force reload the friends list visibility. + /// Callback to handle the friends list visibility status. + public void GetFriendsListVisibility(bool forceReload, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(FriendsListVisibilityStatus.Unknown); + } + } + + /// + /// Displays the leaderboard UI for a specific leaderboard. + /// + /// The ID of the leaderboard. + /// The time span for the leaderboard. + /// Callback to handle the UI status. + public void ShowLeaderboardUI( + string leaderboardId, + LeaderboardTimeSpan span, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(UIStatus.VersionUpdateRequired); + } + } + + /// + /// Retrieves the maximum number of leaderboard results that can be loaded. + /// + /// Returns the maximum number of leaderboard results. + public int LeaderboardMaxResults() + { + return 25; + } + + /// + /// Loads the leaderboard scores based on the specified parameters. + /// + /// The ID of the leaderboard to load scores from. + /// The start position for loading scores. + /// The number of scores to load. + /// The collection type (e.g., public or social). + /// The time span for the leaderboard scores. + /// Callback to handle the leaderboard score data. + public void LoadScores( + string leaderboardId, + LeaderboardStart start, + int rowCount, + LeaderboardCollection collection, + LeaderboardTimeSpan timeSpan, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback(new LeaderboardScoreData( + leaderboardId, + ResponseStatus.LicenseCheckFailed)); + } + } + + /// + /// Loads more leaderboard scores based on the provided pagination token. + /// + /// The token used for pagination. + /// The number of scores to load. + /// Callback to handle the leaderboard score data. + public void LoadMoreScores( + ScorePageToken token, + int rowCount, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback(new LeaderboardScoreData( + token.LeaderboardId, + ResponseStatus.LicenseCheckFailed)); + } + } + + /// + /// Submits a score to a specific leaderboard. + /// + /// The ID of the leaderboard. + /// The score to submit. + /// Callback to handle the score submission result. + public void SubmitScore(string leaderboardId, long score, Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Submits a score with additional metadata to a specific leaderboard. + /// + /// The ID of the leaderboard. + /// The score to submit. + /// Additional metadata to submit with the score. + /// Callback to handle the score submission result. + public void SubmitScore( + string leaderboardId, + long score, + string metadata, + Action callback) + { + LogUsage(); + if (callback != null) + { + callback.Invoke(false); + } + } + + /// + /// Retrieves the saved game client. + /// + /// Returns null since no saved game client is available. + public SavedGame.ISavedGameClient GetSavedGameClient() + { + LogUsage(); + return null; + } + + /// + /// Retrieves the events client. + /// + /// Returns null since no events client is available. + public GooglePlayGames.BasicApi.Events.IEventsClient GetEventsClient() + { + LogUsage(); + return null; + } + + /// + /// Loads friends with a simple boolean flag indicating success or failure. + /// + /// Callback to handle the load result. + public void LoadFriends(Action callback) + { + LogUsage(); + callback(false); + } + + /// + /// Retrieves the list of friends for the current user. + /// + /// Returns an empty array since no friends are loaded. + public IUserProfile[] GetFriends() + { + LogUsage(); + return new IUserProfile[0]; + } + + /// + /// Logs method usage for debugging purposes. + /// + private static void LogUsage() + { + Logger.d("Received method call on DummyClient - using stub implementation."); + } + + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs.meta new file mode 100644 index 0000000..73fdfdc --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/DummyClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 2c600182c9892457e92f885549bd838a +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events.meta new file mode 100644 index 0000000..fa1d608 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 672ea858ca3b74efb9d0981849563065 +folderAsset: yes +timeCreated: 1435699548 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs new file mode 100644 index 0000000..4938bce --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs @@ -0,0 +1,53 @@ +namespace GooglePlayGames.BasicApi.Events +{ + internal class Event : IEvent + { + private string mId; + private string mName; + private string mDescription; + private string mImageUrl; + private ulong mCurrentCount; + private EventVisibility mVisibility; + + internal Event(string id, string name, string description, string imageUrl, + ulong currentCount, EventVisibility visibility) + { + mId = id; + mName = name; + mDescription = description; + mImageUrl = imageUrl; + mCurrentCount = currentCount; + mVisibility = visibility; + } + + public string Id + { + get { return mId; } + } + + public string Name + { + get { return mName; } + } + + public string Description + { + get { return mDescription; } + } + + public string ImageUrl + { + get { return mImageUrl; } + } + + public ulong CurrentCount + { + get { return mCurrentCount; } + } + + public EventVisibility Visibility + { + get { return mVisibility; } + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs.meta new file mode 100644 index 0000000..6dc3df2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/Event.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ce7f6801baead4bbda584bb96882e78b +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs new file mode 100644 index 0000000..73d8477 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs @@ -0,0 +1,60 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +namespace GooglePlayGames.BasicApi.Events +{ + public enum EventVisibility + { + Hidden = 1, + Revealed = 2, + } + + /// + /// Data object representing an Event. for more. + /// + public interface IEvent + { + /// + /// The ID of the event. + /// + string Id { get; } + + /// + /// The name of the event. + /// + string Name { get; } + + /// + /// The description of the event. + /// + string Description { get; } + + /// + /// The URL of the image for the event. Empty if there is no image for this event. + /// + /// The image URL. + string ImageUrl { get; } + + /// + /// The current count for this event. + /// + ulong CurrentCount { get; } + + /// + /// The visibility of the event. + /// + EventVisibility Visibility { get; } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs.meta new file mode 100644 index 0000000..1511d16 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEvent.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 7e4f4f47218d14208a8ae0f676e1bca4 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs new file mode 100644 index 0000000..b13f1c5 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs @@ -0,0 +1,60 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID +namespace GooglePlayGames.BasicApi.Events +{ + using System; + using System.Collections.Generic; + + /// + /// An interface for interacting with events. + /// + /// See online + /// documentation for Events for more information. + /// + /// All callbacks in this interface must be invoked on the game thread. + /// + public interface IEventsClient + { + /// + /// Fetches all events defined for this game. + /// + /// The source of the event (i.e. whether we can return stale cached + /// values). + /// A callback for the results of the request. The passed list will only + /// be non-empty if the request succeeded. This callback will be invoked on the game thread. + /// + void FetchAllEvents(DataSource source, Action> callback); + + /// + /// Fetches the event with the specified ID. + /// + /// The source of the event (i.e. whether we can return stale cached + /// values). + /// The ID of the event. + /// A callback for the result of the event. If the request failed, the + /// passed event will be null. This callback will be invoked on the game thread. + void FetchEvent(DataSource source, string eventId, Action callback); + + /// + /// Increments the indicated event. + /// + /// The ID of the event to increment. + /// The number of steps to increment by. + void IncrementEvent(string eventId, uint stepsToIncrement); + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs.meta new file mode 100644 index 0000000..7686e27 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Events/IEventsClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: da57ba264ec114c57b8352923847ec34 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs new file mode 100644 index 0000000..46be03f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs @@ -0,0 +1,407 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System; + using System.Collections.Generic; + using UnityEngine.SocialPlatforms; + + /// + /// Defines an abstract interface for a Play Games Client. + /// + /// Concrete implementations + /// might be, for example, the client for Android or for iOS. One fundamental concept + /// that implementors of this class must adhere to is stable authentication state. + /// This means that once Authenticate() returns true through its callback, the user is + /// considered to be forever after authenticated while the app is running. The implementation + /// must make sure that this is the case -- for example, it must try to silently + /// re-authenticate the user if authentication is lost or wait for the authentication + /// process to get fixed if it is temporarily in a bad state (such as when the + /// Activity in Android has just been brought to the foreground and the connection to + /// the Games services hasn't yet been established). To the user of this + /// interface, once the user is authenticated, they're forever authenticated. + /// Unless, of course, there is an unusual permanent failure such as the underlying + /// service dying, in which it's acceptable that API method calls will fail. + /// + /// All methods can be called from the game thread. The user of this interface + /// DOES NOT NEED to call them from the UI thread of the game. Transferring to the UI + /// thread when necessary is a responsibility of the implementors of this interface. + /// + /// CALLBACKS: all callbacks must be invoked in Unity's main thread. + /// Implementors of this interface must guarantee that (suggestion: use + /// ). + /// + public interface IPlayGamesClient + { + /// + /// Returns the result of the automatic sign-in attempt. + /// + /// This returns the result + /// + /// Callback + void Authenticate(Action callback); + + /// + /// Manually requests that your game performs sign in with Play Games Services. + /// + /// + /// Note that a sign-in attempt will be made automatically when your game's application + /// started. For this reason most games will not need to manually request to perform sign-in + /// unless the automatic sign-in attempt failed and your game requires access to Play Games + /// Services. + /// + /// + void ManuallyAuthenticate(Action callback); + + /// + /// Returns whether or not user is authenticated. + /// + /// true if the user is authenticated; otherwise, false. + bool IsAuthenticated(); + + /// + /// Requests server-side access to Player Games Services for the currently signed in player. + /// + /// When requested an authorization code is returned that can be used by your game-server to + /// exchange for an access token and conditionally a refresh token (when forceRefreshToken + /// is true). The access token may then be used by your game-server to access the Play Games + /// Services web APIs. This is commonly used to complete a sign-in flow by verifying the Play Games + /// Services player id. + /// + /// If forceRefreshToken is true, when exchanging the authorization code a refresh token + /// will be returned in addition to the access token. The refresh token allows the game-server to + /// request additional access tokens, allowing your game-server to continue accesses Play Games + /// Services while the user is not actively playing your app. + /// If true when the returned authorization code is exchanged a + /// refresh token will be included in addition to an access token. + /// + void RequestServerSideAccess(bool forceRefreshToken, Action callback); + + /// + /// Requests server-side access to Play Games Services for the currently signed in player. + /// + /// An authorization code is returned when requested. Your server can then exchange this code + /// for an access token (and conditionally a refresh token when forceRefreshToken is + /// true). The access token allows your server to access the Play Games Services web APIs, which + /// is often used to complete sign-in by verifying the Play Games Services player ID. + /// + /// When forceRefreshToken is true during authorization code exchange, a refresh + /// token is provided along with the access token. This refresh token enables your server to obtain + /// new access tokens and continue accessing Play Games Services even when the user isn't actively + /// playing. Note that refresh tokens are only generated for players who have auto sign-in setting + /// enabled. + /// + /// Scopes represent the {@link AuthScope} values requested such as AuthScope.EMAIL, + /// AuthScope.PROFILE, AuthScope.OPEN_ID. For new permissions, users will see a + /// consent screen upon the first request. Granting consent (or if permissions were already + /// granted) results in the {@link AuthResponse} listing the effectively granted {@link AuthScope}. + /// Declining permission results in an empty list of granted {@link AuthScope} in the {@link + /// AuthResponse} . Regardless of granted permissions, a successful request will always return the + /// authorization code. + /// If true when the returned authorization code is exchanged a + /// refresh token will be included in addition to an access token. + ///A list of {@link AuthScope} values representing the OAuth 2.0 permissions being + ///requested, such as AuthScope.EMAIL, AuthScope.PROFILE and + /// AuthScope.OPEN_ID. + /// + /// A {@link Task} that completes with an {@link AuthResponse} containing the OAuth 2.0 + /// authorization code as a string and a list of the {@link AuthScope}s that were effectively + /// granted by the user (see description for details on consent). This authorization code can + /// be exchanged by your server for an access token (and conditionally a refresh token) that + /// can be used to access the Play Games Services web APIs and other Google Identity APIs. + void RequestServerSideAccess(bool forceRefreshToken, List scopes, Action callback); + + /// + /// Requests Recall Access to Player Games Services for the currently signed in account + /// + /// When requested a session id is returned that can be used by your game-server to + /// use Recall Access APIs like LinkPerson , UnlinkPersona and get Details about Recall Tokens + /// and corresponding personas. See https://developer.android.com/games/pgs/recall?hl=en. + /// + /// + /// + /// + /// + void RequestRecallAccessToken(Action callback); + + /// + /// Returns the authenticated user's ID. Note that this value may change if a user signs + /// out and signs in with a different account. + /// + /// The user's ID, null if the user is not logged in. + string GetUserId(); + + /// + /// Loads friends of the authenticated user. This loads the entire list of friends. + /// + /// Callback invoked when complete. bool argument + /// indicates success. + void LoadFriends(Action callback); + + /// + /// Returns a human readable name for the user, if they are logged in. + /// + /// The user's human-readable name. null if they are not logged + /// in + string GetUserDisplayName(); + + /// + /// Returns the user's avatar url, if they are logged in and have an avatar. + /// + /// The URL to load the avatar image. null if they are not logged + /// in + string GetUserImageUrl(); + + /// Gets the player stats. + /// Callback for response. + void GetPlayerStats(Action callback); + + /// + /// Loads the users specified. This is mainly used by the leaderboard + /// APIs to get the information of a high scorer. + /// + /// User identifiers. + /// Callback. + void LoadUsers(string[] userIds, Action callback); + + /// + /// Loads the achievements for the current signed in user and invokes + /// the callback. + /// + void LoadAchievements(Action callback); + + /// + /// Unlocks the achievement with the passed identifier. + /// + /// If the operation succeeds, the callback + /// will be invoked on the game thread with true. If the operation fails, the + /// callback will be invoked with false. This operation will immediately fail if + /// the user is not authenticated (i.e. the callback will immediately be invoked with + /// false). If the achievement is already unlocked, this call will + /// succeed immediately. + /// + /// The ID of the achievement to unlock. + /// Callback used to indicate whether the operation + /// succeeded or failed. + void UnlockAchievement(string achievementId, Action successOrFailureCalllback); + + /// + /// Reveals the achievement with the passed identifier. + /// + /// If the operation succeeds, the callback + /// will be invoked on the game thread with true. If the operation fails, the + /// callback will be invoked with false. This operation will immediately fail if + /// the user is not authenticated (i.e. the callback will immediately be invoked with + /// false). If the achievement is already in a revealed state, this call will + /// succeed immediately. + /// + /// The ID of the achievement to reveal. + /// Callback used to indicate whether the operation + /// succeeded or failed. + void RevealAchievement(string achievementId, Action successOrFailureCalllback); + + /// + /// Increments the achievement with the passed identifier. + /// + /// If the operation succeeds, the + /// callback will be invoked on the game thread with true. If the operation + /// fails, the callback will be invoked with false. This operation will + /// immediately fail if the user is not authenticated (i.e. the callback will immediately be + /// invoked with false). + /// + /// The ID of the achievement to increment. + /// The number of steps to increment by. + /// Callback used to indicate whether the operation + /// succeeded or failed. + void IncrementAchievement(string achievementId, int steps, + Action successOrFailureCalllback); + + /// + /// Set an achievement to have at least the given number of steps completed. + /// + /// + /// Calling this method while the achievement already has more steps than + /// the provided value is a no-op. Once the achievement reaches the + /// maximum number of steps, the achievement is automatically unlocked, + /// and any further mutation operations are ignored. + /// + /// Ach identifier. + /// Steps. + /// Callback. + void SetStepsAtLeast(string achId, int steps, Action callback); + + /// + /// Shows the appropriate platform-specific achievements UI. + /// The callback to invoke when complete. If null, + /// no callback is called. + /// + void ShowAchievementsUI(Action callback); + + /// + /// Shows the appropriate platform-specific friends sharing UI. + /// The callback to invoke when complete. If null, + /// no callback is called. + /// + void AskForLoadFriendsResolution(Action callback); + + /// + /// Returns the latest LoadFriendsStatus obtained from loading friends. + /// + LoadFriendsStatus GetLastLoadFriendsStatus(); + + /// + /// Shows the Play Games Player Profile UI for a specific user identifier. + /// + /// User Identifier. + /// + /// The game's own display name of the player referred to by userId. + /// + /// + /// The game's own display name of the current player. + /// + /// Callback invoked upon completion. + void ShowCompareProfileWithAlternativeNameHintsUI( + string otherUserId, string otherPlayerInGameName, string currentPlayerInGameName, + Action callback); + + /// + /// Returns if the user has allowed permission for the game to access the friends list. + /// + /// If true, this call will clear any locally cached data and + /// attempt to fetch the latest data from the server. Normally, this should be set to + /// false to gain advantages of data caching. Callback + /// invoked upon completion. + void GetFriendsListVisibility(bool forceReload, Action callback); + + /// + /// Loads the first page of the user's friends + /// + /// + /// The number of entries to request for this initial page. Note that if cached + /// data already exists, the returned buffer may contain more than this size, but it is + /// guaranteed to contain at least this many if the collection contains enough records. + /// + /// + /// If true, this call will clear any locally cached data and attempt to + /// fetch the latest data from the server. This would commonly be used for something like a + /// user-initiated refresh. Normally, this should be set to false to gain advantages + /// of data caching. + /// Callback invoked upon completion. + void LoadFriends(int pageSize, bool forceReload, Action callback); + + /// + /// Loads the friends list page + /// + /// + /// The number of entries to request for this page. Note that if cached data already + /// exists, the returned buffer may contain more than this size, but it is guaranteed + /// to contain at least this many if the collection contains enough records. + /// + /// + void LoadMoreFriends(int pageSize, Action callback); + + /// + /// Shows the leaderboard UI for a specific leaderboard. + /// + /// If the passed ID is null, all leaderboards are displayed. + /// + /// The leaderboard to display. null to display + /// all. + /// Timespan to display for the leaderboard + /// If non-null, the callback to invoke when the + /// leaderboard is dismissed. + /// + void ShowLeaderboardUI(string leaderboardId, LeaderboardTimeSpan span, + Action callback); + + /// + /// Loads the score data for the given leaderboard. + /// + /// Leaderboard identifier. + /// Start indicating the top scores or player centric + /// max number of scores to return. non-positive indicates + /// no rows should be returned. This causes only the summary info to + /// be loaded. This can be limited + /// by the SDK. + /// leaderboard collection: public or social + /// leaderboard timespan + /// callback with the scores, and a page token. + /// The token can be used to load next/prev pages. + void LoadScores(string leaderboardId, LeaderboardStart start, int rowCount, + LeaderboardCollection collection, LeaderboardTimeSpan timeSpan, + Action callback); + + /// + /// Loads the more scores for the leaderboard. + /// + /// The token is accessed + /// by calling LoadScores() with a positive row count. + /// + /// Token for tracking the score loading. + /// max number of scores to return. + /// This can be limited by the SDK. + /// Callback. + void LoadMoreScores(ScorePageToken token, int rowCount, + Action callback); + + /// + /// Returns the max number of scores returned per call. + /// + /// The max results. + int LeaderboardMaxResults(); + + /// + /// Submits the passed score to the passed leaderboard. + /// + /// This operation will immediately fail + /// if the user is not authenticated (i.e. the callback will immediately be invoked with + /// false). + /// + /// Leaderboard identifier. + /// Score. + /// Callback used to indicate whether the operation + /// succeeded or failed. + void SubmitScore(string leaderboardId, long score, Action successOrFailureCalllback); + + /// + /// Submits the score for the currently signed-in player. + /// + /// Score. + /// leaderboard id. + /// metadata about the score. + /// Callback upon completion. + void SubmitScore(string leaderboardId, long score, string metadata, + Action successOrFailureCalllback); + + /// + /// Gets the saved game client. + /// + /// The saved game client. + SavedGame.ISavedGameClient GetSavedGameClient(); + + /// + /// Gets the events client. + /// + /// The events client. + Events.IEventsClient GetEventsClient(); + + IUserProfile[] GetFriends(); + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs.meta new file mode 100644 index 0000000..c7fe324 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/IPlayGamesClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9138e04e4459148c680055b40ad324c0 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs new file mode 100644 index 0000000..032fc6c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs @@ -0,0 +1,174 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System.Collections.Generic; + using UnityEngine.SocialPlatforms; + + /// + /// Leaderboard score data. This is the callback data + /// when loading leaderboard scores. There are several SDK + /// API calls needed to be made to collect all the required data, + /// so this class is used to simplify the response. + /// + public class LeaderboardScoreData + { + private string mId; + private ResponseStatus mStatus; + private ulong mApproxCount; + private string mTitle; + private IScore mPlayerScore; + private ScorePageToken mPrevPage; + private ScorePageToken mNextPage; + private List mScores = new List(); + + /// + /// Initializes a new instance of the class. + /// + /// The identifier of the leaderboard. + internal LeaderboardScoreData(string leaderboardId) + { + mId = leaderboardId; + } + + /// + /// Initializes a new instance of the class with a specified status. + /// + /// The identifier of the leaderboard. + /// The response status of the leaderboard data. + internal LeaderboardScoreData(string leaderboardId, ResponseStatus status) + { + mId = leaderboardId; + mStatus = status; + } + + /// + /// Gets a value indicating whether the leaderboard data is valid. + /// + public bool Valid + { + get + { + return mStatus == ResponseStatus.Success || + mStatus == ResponseStatus.SuccessWithStale; + } + } + + /// + /// Gets or sets the status of the leaderboard data response. + /// + public ResponseStatus Status + { + get { return mStatus; } + + internal set { mStatus = value; } + } + + /// + /// Gets or sets the approximate count of scores in the leaderboard. + /// + public ulong ApproximateCount + { + get { return mApproxCount; } + + internal set { mApproxCount = value; } + } + + /// + /// Gets or sets the title of the leaderboard. + /// + public string Title + { + get { return mTitle; } + + internal set { mTitle = value; } + } + + /// + /// Gets or sets the unique identifier of the leaderboard. + /// + public string Id + { + get { return mId; } + + internal set { mId = value; } + } + + /// + /// Gets or sets the player's score in the leaderboard. + /// + public IScore PlayerScore + { + get { return mPlayerScore; } + + internal set { mPlayerScore = value; } + } + + /// + /// Gets an array of the scores in the leaderboard. + /// + public IScore[] Scores + { + get { return mScores.ToArray(); } + } + + /// + /// Adds a score to the leaderboard data. + /// + /// The score to add. + /// The count of scores after the addition. + internal int AddScore(PlayGamesScore score) + { + mScores.Add(score); + return mScores.Count; + } + + /// + /// Gets or sets the token for the previous page of scores. + /// + public ScorePageToken PrevPageToken + { + get { return mPrevPage; } + + internal set { mPrevPage = value; } + } + + /// + /// Gets or sets the token for the next page of scores. + /// + public ScorePageToken NextPageToken + { + get { return mNextPage; } + + internal set { mNextPage = value; } + } + + /// + /// Returns a string representation of the leaderboard score data. + /// + /// A string that represents the current object. + public override string ToString() + { + return string.Format("[LeaderboardScoreData: mId={0}, " + + " mStatus={1}, mApproxCount={2}, mTitle={3}]", + mId, mStatus, mApproxCount, mTitle); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs.meta new file mode 100644 index 0000000..3f5c114 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/LeaderboardScoreData.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 8e369c64e8c9f4571a8847f37848c37e +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby.meta new file mode 100644 index 0000000..0286871 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c980790a380df4850b17a208e544d062 +folderAsset: yes +timeCreated: 1435699549 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs new file mode 100644 index 0000000..6c6419e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs @@ -0,0 +1,67 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.OurUtils; + + /// + /// Represents the result of an attempt to start advertising for nearby connections. + /// + public struct AdvertisingResult + { + private readonly ResponseStatus mStatus; + private readonly string mLocalEndpointName; + + /// + /// Constructs a new . + /// + /// The result of the advertising attempt. + /// The name of the local endpoint. + /// If is null. + public AdvertisingResult(ResponseStatus status, string localEndpointName) + { + this.mStatus = status; + this.mLocalEndpointName = Misc.CheckNotNull(localEndpointName); + } + + /// + /// Gets a value indicating whether the advertising operation was successful. + /// + public bool Succeeded + { + get { return mStatus == ResponseStatus.Success; } + } + + /// + /// Gets the response status of the advertising operation. + /// + public ResponseStatus Status + { + get { return mStatus; } + } + + /// + /// Gets the name of the local endpoint used in the advertising operation. + /// + public string LocalEndpointName + { + get { return mLocalEndpointName; } + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs.meta new file mode 100644 index 0000000..8d791e6 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/AdvertisingResult.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 941324a6338664af6a9faf5b88cad408 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs new file mode 100644 index 0000000..585e46c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs @@ -0,0 +1,61 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using GooglePlayGames.OurUtils; + + /// + /// Represents a request to establish a connection with a remote endpoint. + /// Contains information about the remote endpoint and an optional payload. + /// + public struct ConnectionRequest + { + private readonly EndpointDetails mRemoteEndpoint; + private readonly byte[] mPayload; + + /// + /// Initializes a new instance of the struct. + /// + /// The ID of the remote endpoint requesting the connection. + /// The name of the remote endpoint. + /// The service ID the connection is targeting. + /// The payload associated with the connection request. + public ConnectionRequest(string remoteEndpointId, + string remoteEndpointName, string serviceId, byte[] payload) + { + Logger.d("Constructing ConnectionRequest"); + mRemoteEndpoint = new EndpointDetails(remoteEndpointId, remoteEndpointName, serviceId); + this.mPayload = Misc.CheckNotNull(payload); + } + + /// + /// Gets the details of the remote endpoint making the connection request. + /// + public EndpointDetails RemoteEndpoint + { + get { return mRemoteEndpoint; } + } + + /// + /// Gets the payload data included with the connection request. + /// + public byte[] Payload + { + get { return mPayload; } + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs.meta new file mode 100644 index 0000000..7d076a9 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionRequest.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c7f9bb6b249224f99ad05a87d3e4ee34 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs new file mode 100644 index 0000000..da8f614 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs @@ -0,0 +1,174 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using GooglePlayGames.OurUtils; + + /// + /// Represents a response to a connection request, including status, payload, and identifying information. + /// + public struct ConnectionResponse + { + private static readonly byte[] EmptyPayload = new byte[0]; + + /// + /// Status codes representing the outcome of a connection request. + /// + public enum Status + { + /// + /// Indicates that the connection was accepted. + /// + Accepted, + + /// + /// Indicates that the connection was rejected. + /// + Rejected, + + /// + /// Indicates that an internal error occurred. + /// + ErrorInternal, + + /// + /// Indicates that the device is not connected to a network. + /// + ErrorNetworkNotConnected, + + /// + /// Indicates that the remote endpoint is not connected. + /// + ErrorEndpointNotConnected, + + /// + /// Indicates that the endpoints are already connected. + /// + ErrorAlreadyConnected + } + + private readonly long mLocalClientId; + private readonly string mRemoteEndpointId; + private readonly Status mResponseStatus; + private readonly byte[] mPayload; + + /// + /// Initializes a new instance of the struct. + /// + /// The ID of the local client. + /// The ID of the remote endpoint. + /// The status of the connection response. + /// The payload data included with the response. + private ConnectionResponse(long localClientId, string remoteEndpointId, Status code, + byte[] payload) + { + this.mLocalClientId = localClientId; + this.mRemoteEndpointId = Misc.CheckNotNull(remoteEndpointId); + this.mResponseStatus = code; + this.mPayload = Misc.CheckNotNull(payload); + } + + /// + /// Gets the ID of the local client. + /// + public long LocalClientId + { + get { return mLocalClientId; } + } + + /// + /// Gets the ID of the remote endpoint responding to the connection request. + /// + public string RemoteEndpointId + { + get { return mRemoteEndpointId; } + } + + /// + /// Gets the status of the connection response. + /// + public Status ResponseStatus + { + get { return mResponseStatus; } + } + + /// + /// Gets the payload sent with the connection response. + /// + public byte[] Payload + { + get { return mPayload; } + } + + /// + /// Creates a response indicating the connection was rejected. + /// + public static ConnectionResponse Rejected(long localClientId, string remoteEndpointId) + { + return new ConnectionResponse(localClientId, remoteEndpointId, Status.Rejected, + EmptyPayload); + } + + /// + /// Creates a response indicating the device is not connected to a network. + /// + public static ConnectionResponse NetworkNotConnected(long localClientId, string remoteEndpointId) + { + return new ConnectionResponse(localClientId, remoteEndpointId, Status.ErrorNetworkNotConnected, + EmptyPayload); + } + + /// + /// Creates a response indicating an internal error occurred. + /// + public static ConnectionResponse InternalError(long localClientId, string remoteEndpointId) + { + return new ConnectionResponse(localClientId, remoteEndpointId, Status.ErrorInternal, + EmptyPayload); + } + + /// + /// Creates a response indicating the remote endpoint is not connected. + /// + public static ConnectionResponse EndpointNotConnected(long localClientId, string remoteEndpointId) + { + return new ConnectionResponse(localClientId, remoteEndpointId, Status.ErrorEndpointNotConnected, + EmptyPayload); + } + + /// + /// Creates a response indicating the connection was accepted with a payload. + /// + public static ConnectionResponse Accepted(long localClientId, string remoteEndpointId, + byte[] payload) + { + return new ConnectionResponse(localClientId, remoteEndpointId, Status.Accepted, + payload); + } + + /// + /// Creates a response indicating the endpoints are already connected. + /// + public static ConnectionResponse AlreadyConnected(long localClientId, + string remoteEndpointId) + { + return new ConnectionResponse(localClientId, remoteEndpointId, + Status.ErrorAlreadyConnected, + EmptyPayload); + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs.meta new file mode 100644 index 0000000..f079fb2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/ConnectionResponse.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ad6611af8d0204d0d8922a327d3d9ec0 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs new file mode 100644 index 0000000..38f0b5a --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs @@ -0,0 +1,176 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi.Nearby +{ + using UnityEngine; + + /// + /// Dummy implementation of INearbyConnectionClient. This class can be used for testing purposes. + /// It logs messages indicating that its methods have been called. + /// + public class DummyNearbyConnectionClient : INearbyConnectionClient + { + /// + /// The maximum size of an unreliable message payload. + /// + public int MaxUnreliableMessagePayloadLength() + { + return NearbyConnectionConfiguration.MaxUnreliableMessagePayloadLength; + } + + /// + /// The maximum size of a reliable message payload. + /// + public int MaxReliableMessagePayloadLength() + { + return NearbyConnectionConfiguration.MaxReliableMessagePayloadLength; + } + + /// + /// Logs the message about Reliable call from dummy implementation. + /// + public void SendReliable(System.Collections.Generic.List recipientEndpointIds, byte[] payload) + { + OurUtils.Logger.d("SendReliable called from dummy implementation"); + } + + /// + /// Logs the message about Unreliable call from dummy implementation. + /// + public void SendUnreliable(System.Collections.Generic.List recipientEndpointIds, byte[] payload) + { + OurUtils.Logger.d("SendUnreliable called from dummy implementation"); + } + + /// + /// Starts advertising for a service. + /// + public void StartAdvertising(string name, System.Collections.Generic.List appIdentifiers, + System.TimeSpan? advertisingDuration, System.Action resultCallback, + System.Action connectionRequestCallback) + { + AdvertisingResult obj = new AdvertisingResult(ResponseStatus.LicenseCheckFailed, string.Empty); + resultCallback.Invoke(obj); + } + + /// + /// Logs the message about StopAdvertising call from dummy implementation. + /// + public void StopAdvertising() + { + OurUtils.Logger.d("StopAvertising in dummy implementation called"); + } + + /// + /// Sends a connection request to the specified endpoint. + /// + public void SendConnectionRequest(string name, string remoteEndpointId, byte[] payload, + System.Action responseCallback, IMessageListener listener) + { + OurUtils.Logger.d("SendConnectionRequest called from dummy implementation"); + + if (responseCallback != null) + { + ConnectionResponse obj = ConnectionResponse.Rejected(0, string.Empty); + responseCallback.Invoke(obj); + } + } + + /// + /// Logs the message about accepts a connection request from the specified endpoint. + /// + public void AcceptConnectionRequest(string remoteEndpointId, byte[] payload, IMessageListener listener) + { + OurUtils.Logger.d("AcceptConnectionRequest in dummy implementation called"); + } + + /// + /// Logs the message about StartDiscovery call from dummy implementation. + /// + public void StartDiscovery(string serviceId, System.TimeSpan? advertisingTimeout, IDiscoveryListener listener) + { + OurUtils.Logger.d("StartDiscovery in dummy implementation called"); + } + + /// + /// Logs the message about StopDiscovery call from dummy implementation. + /// + public void StopDiscovery(string serviceId) + { + OurUtils.Logger.d("StopDiscovery in dummy implementation called"); + } + + /// + /// Logs the message about RejectConnectionRequest call from dummy implementation. + /// + public void RejectConnectionRequest(string requestingEndpointId) + { + OurUtils.Logger.d("RejectConnectionRequest in dummy implementation called"); + } + + /// + /// Logs the message about DisconnectFromEndpoint call from dummy implementation. + /// + public void DisconnectFromEndpoint(string remoteEndpointId) + { + OurUtils.Logger.d("DisconnectFromEndpoint in dummy implementation called"); + } + + /// + /// Logs the message about StopAllConnections call from dummy implementation. + /// + public void StopAllConnections() + { + OurUtils.Logger.d("StopAllConnections in dummy implementation called"); + } + + /// + /// Returns the local endpoint id string. + /// + public string LocalEndpointId() + { + return string.Empty; + } + + /// + /// Returns the local device id string. + /// + public string LocalDeviceId() + { + return "DummyDevice"; + } + + /// + /// Returns the app bundle id string. + /// + public string GetAppBundleId() + { + return "dummy.bundle.id"; + } + + /// + /// Returns the service id string. + /// + public string GetServiceId() + { + return "dummy.service.id"; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs.meta new file mode 100644 index 0000000..443da46 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/DummyNearbyConnectionClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9b3f34a2bba13428789d02b53fd89a47 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs new file mode 100644 index 0000000..3f3713b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs @@ -0,0 +1,67 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using GooglePlayGames.OurUtils; + + /// + /// Represents details of an endpoint involved in a Nearby Connections operation. + /// + public struct EndpointDetails + { + private readonly string mEndpointId; + private readonly string mName; + private readonly string mServiceId; + + /// + /// Initializes a new instance of the struct. + /// + /// The unique identifier of the endpoint. + /// The name of the endpoint. + /// The service ID associated with the endpoint. + public EndpointDetails(string endpointId, string name, string serviceId) + { + this.mEndpointId = Misc.CheckNotNull(endpointId); + this.mName = Misc.CheckNotNull(name); + this.mServiceId = Misc.CheckNotNull(serviceId); + } + + /// + /// Gets the unique identifier of the endpoint. + /// + public string EndpointId + { + get { return mEndpointId; } + } + + /// + /// Gets the name of the endpoint. + /// + public string Name + { + get { return mName; } + } + + /// + /// Gets the service ID associated with the endpoint. + /// + public string ServiceId + { + get { return mServiceId; } + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs.meta new file mode 100644 index 0000000..e1aaf46 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/EndpointDetails.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9d9a087b0e20d4752b24f33a4a2bf977 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs new file mode 100644 index 0000000..51ed85c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs @@ -0,0 +1,177 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using System; + using System.Collections.Generic; + + // move this inside IMessageListener and IDiscoveryListener are always declared. +#if UNITY_ANDROID + + /// + /// Interface for managing connections and communications between devices using Nearby Connections. + /// + public interface INearbyConnectionClient + { + /// + /// Gets the maximum length of an unreliable message payload. + /// + /// Maximum length of an unreliable message payload. + int MaxUnreliableMessagePayloadLength(); + + /// + /// Gets the maximum length of a reliable message payload. + /// + /// Maximum length of a reliable message payload. + int MaxReliableMessagePayloadLength(); + + /// + /// Sends a reliable message to a list of recipients. + /// + /// List of recipient endpoint IDs. + /// The message payload to send. + void SendReliable(List recipientEndpointIds, byte[] payload); + + /// + /// Sends an unreliable message to a list of recipients. + /// + /// List of recipient endpoint IDs. + /// The message payload to send. + void SendUnreliable(List recipientEndpointIds, byte[] payload); + + /// + /// Starts advertising the local device to nearby devices. + /// + /// The name to advertise. + /// List of application identifiers. + /// Optional advertising duration. + /// Callback for advertising result. + /// Callback for incoming connection requests. + void StartAdvertising(string name, List appIdentifiers, + TimeSpan? advertisingDuration, Action resultCallback, + Action connectionRequestCallback); + + /// + /// Stops advertising the local device to nearby devices. + /// + void StopAdvertising(); + + /// + /// Sends a connection request to a remote endpoint. + /// + /// The name of the local device. + /// The ID of the remote endpoint. + /// The connection request payload. + /// Callback for the connection response. + /// Listener for message events. + void SendConnectionRequest(string name, string remoteEndpointId, byte[] payload, + Action responseCallback, IMessageListener listener); + + /// + /// Accepts a connection request from a remote endpoint. + /// + /// The ID of the remote endpoint. + /// The connection acceptance payload. + /// Listener for message events. + void AcceptConnectionRequest(string remoteEndpointId, byte[] payload, + IMessageListener listener); + + /// + /// Starts discovering nearby endpoints for a specific service. + /// + /// The service ID to discover. + /// Optional timeout for advertising discovery. + /// Listener for discovery events. + void StartDiscovery(string serviceId, TimeSpan? advertisingTimeout, + IDiscoveryListener listener); + + /// + /// Stops discovering endpoints for a specific service. + /// + /// The service ID to stop discovering. + void StopDiscovery(string serviceId); + + /// + /// Rejects a connection request from a remote endpoint. + /// + /// The ID of the endpoint that sent the request. + void RejectConnectionRequest(string requestingEndpointId); + + /// + /// Disconnects from a remote endpoint. + /// + /// The ID of the remote endpoint to disconnect from. + void DisconnectFromEndpoint(string remoteEndpointId); + + /// + /// Stops all connections to nearby endpoints. + /// + void StopAllConnections(); + + /// + /// Gets the app bundle ID. + /// + /// The app bundle ID. + string GetAppBundleId(); + + /// + /// Gets the service ID used for discovery and connection. + /// + /// The service ID. + string GetServiceId(); + } +#endif + + /// + /// Interface for receiving messages and notifications about remote endpoints. + /// + public interface IMessageListener + { + /// + /// Called when a message is received from a remote endpoint. + /// + /// The ID of the remote endpoint. + /// The data of the received message. + /// Indicates whether the message is reliable. + void OnMessageReceived(string remoteEndpointId, byte[] data, + bool isReliableMessage); + + /// + /// Called when a remote endpoint has disconnected. + /// + /// The ID of the disconnected endpoint. + void OnRemoteEndpointDisconnected(string remoteEndpointId); + } + + /// + /// Interface for receiving notifications about discovered endpoints. + /// + public interface IDiscoveryListener + { + /// + /// Called when an endpoint is found during discovery. + /// + /// The details of the discovered endpoint. + void OnEndpointFound(EndpointDetails discoveredEndpoint); + + /// + /// Called when an endpoint is lost during discovery. + /// + /// The ID of the lost endpoint. + void OnEndpointLost(string lostEndpointId); + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs.meta new file mode 100644 index 0000000..8b154f2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/INearbyConnectionClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: cb64b5b444dd34de5bd308c7eed6e509 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs new file mode 100644 index 0000000..9bcc3c8 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs @@ -0,0 +1,91 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.Nearby +{ + using System; + using GooglePlayGames.OurUtils; + + /// + /// Represents the configuration for a Nearby Connections operation. + /// Includes initialization status and client-specific configuration. + /// + public enum InitializationStatus + { + /// + /// Indicates that the initialization was successful. + /// + Success, + + /// + /// Signifies that a version update is required for nearby connections. + /// + VersionUpdateRequired, + + /// + /// Denotes that an internal error occurred during initialization. + /// + InternalError + } + + /// + /// Defines the configuration for establishing a Nearby connection. + /// This includes parameters like client ID and initialization callback. + /// + public struct NearbyConnectionConfiguration + { + /// + /// A constant integer representing the maximum payload length for unreliable messages. + /// + public const int MaxUnreliableMessagePayloadLength = 1168; + + /// + /// A constant integer representing the maximum payload length for reliable messages. + /// + public const int MaxReliableMessagePayloadLength = 4096; + + private readonly Action mInitializationCallback; + private readonly long mLocalClientId; + + /// + /// Initializes a new instance of the struct. + /// + /// A callback that will be invoked when initialization completes. + /// The unique identifier for the local client. + public NearbyConnectionConfiguration(Action callback, + long localClientId) + { + this.mInitializationCallback = Misc.CheckNotNull(callback); + this.mLocalClientId = localClientId; + } + + /// + /// Gets the unique identifier for the local client. + /// + public long LocalClientId + { + get { return mLocalClientId; } + } + + /// + /// Gets the callback to be invoked upon the completion of initialization. + /// + public Action InitializationCallback + { + get { return mInitializationCallback; } + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs.meta new file mode 100644 index 0000000..184b7f7 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Nearby/NearbyConnectionConfiguration.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 968ac90e4a9094a4a92df9da1ee1f884 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs new file mode 100644 index 0000000..204dd61 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs @@ -0,0 +1,39 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID +namespace GooglePlayGames.BasicApi +{ + /// + /// Represents a player. A player is different from a participant! The participant is + /// an entity that takes part in a particular match; a Player is a real-world person + /// (tied to a Games account). The player exists across matches, the Participant + /// only exists in the context of a particular match. + /// + public class Player : PlayGamesUserProfile + { + /// + /// Constructor for Player. + /// + /// The display name of the player. + /// The player ID of the player. + /// The URL of the player's avatar. + internal Player(string displayName, string playerId, string avatarUrl) + : base(displayName, playerId, avatarUrl) + { + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs.meta new file mode 100644 index 0000000..17c4de3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/Player.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 4e1630bdd0c7b490e8f006f9a24ef758 +labels: +- gvh +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs new file mode 100644 index 0000000..8fc0274 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs @@ -0,0 +1,35 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi { + /// + /// Represents a player, a real-world person (tied to a Games account). + /// + public class PlayerProfile : PlayGamesUserProfile { + /// + /// Constructor for PlayerProfile. + /// + /// The display name of the player. + /// The player ID of the player. + /// The URL of the player's avatar. + /// Whether the player is a friend of the current player. + internal PlayerProfile(string displayName, string playerId, string avatarUrl, bool isFriend) + : base(displayName, playerId, avatarUrl, isFriend) {} + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs.meta new file mode 100644 index 0000000..e247772 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerProfile.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 547c7cbe798c749c7b389133ebabc40c +labels: +- gvh +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs new file mode 100644 index 0000000..a7e8c5f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs @@ -0,0 +1,268 @@ +// +// Copyright (C) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System; + + /// + /// Player stats. See https://developers.google.com/games/services/android/stats + /// + public class PlayerStats + { + private static float UNSET_VALUE = -1.0f; + + public PlayerStats( + int numberOfPurchases, + float avgSessionLength, + int daysSinceLastPlayed, + int numberOfSessions, + float sessPercentile, + float spendPercentile, + float spendProbability, + float churnProbability, + float highSpenderProbability, + float totalSpendNext28Days) + { + mValid = true; + mNumberOfPurchases = numberOfPurchases; + mAvgSessionLength = avgSessionLength; + mDaysSinceLastPlayed = daysSinceLastPlayed; + mNumberOfSessions = numberOfSessions; + mSessPercentile = sessPercentile; + mSpendPercentile = spendPercentile; + mSpendProbability = spendProbability; + mChurnProbability = churnProbability; + mHighSpenderProbability = highSpenderProbability; + mTotalSpendNext28Days = totalSpendNext28Days; + } + + public PlayerStats() + { + mValid = false; + } + + private bool mValid; + private int mNumberOfPurchases; + private float mAvgSessionLength; + private int mDaysSinceLastPlayed; + private int mNumberOfSessions; + private float mSessPercentile; + private float mSpendPercentile; + private float mSpendProbability; + private float mChurnProbability; + private float mHighSpenderProbability; + private float mTotalSpendNext28Days; + + /// + /// If this PlayerStats object is valid (i.e. successfully retrieved from games services). + /// + /// + /// Note that a PlayerStats with all stats unset may still be valid. + /// + public bool Valid + { + get { return mValid; } + } + + /// + /// The number of in-app purchases. + /// + public int NumberOfPurchases + { + get { return mNumberOfPurchases; } + } + + /// + /// The length of the avg session in minutes. + /// + public float AvgSessionLength + { + get { return mAvgSessionLength; } + } + + /// + /// The days since last played. + /// + public int DaysSinceLastPlayed + { + get { return mDaysSinceLastPlayed; } + } + + /// + /// The number of sessions based on sign-ins. + /// + public int NumberOfSessions + { + get { return mNumberOfSessions; } + } + + /// + /// The approximation of sessions percentile for the player. + /// + /// + /// This value is given as a decimal value between 0 and 1 (inclusive). + /// It indicates how many sessions the current player has + /// played in comparison to the rest of this game's player base. + /// Higher numbers indicate that this player has played more sessions. + /// A return value less than zero indicates this value is not available. + /// + public float SessPercentile + { + get { return mSessPercentile; } + } + + /// + /// The approximate spend percentile of the player. + /// + /// + /// This value is given as a decimal value between 0 and 1 (inclusive). + /// It indicates how much the current player has spent in + /// comparison to the rest of this game's player base. Higher + /// numbers indicate that this player has spent more. + /// A return value less than zero indicates this value is not available. + /// + public float SpendPercentile + { + get { return mSpendPercentile; } + } + + /// + /// The approximate probability of the player choosing to spend in this game. + /// + /// + /// This value is given as a decimal value between 0 and 1 (inclusive). + /// Higher values indicate that a player is more likely to spend. + /// A return value less than zero indicates this value is not available. + /// + public float SpendProbability + { + get { return mSpendProbability; } + } + + /// + /// The approximate probability of the player not returning to play the game. + /// + /// + /// Higher values indicate that a player is less likely to return. + /// A return value less than zero indicates this value is not available. + /// + public float ChurnProbability + { + get { return mChurnProbability; } + } + + /// + /// The high spender probability of this player. + /// + public float HighSpenderProbability + { + get { return mHighSpenderProbability; } + } + + /// + /// The predicted total spend of this player over the next 28 days. + /// + public float TotalSpendNext28Days + { + get { return mTotalSpendNext28Days; } + } + + /// + /// Determines whether this instance has NumberOfPurchases. + /// + /// true if this instance has NumberOfPurchases; otherwise, false. + public bool HasNumberOfPurchases() + { + return NumberOfPurchases != (int) UNSET_VALUE; + } + + /// + /// Determines whether this instance has AvgSessionLength. + /// + /// true if this instance has AvgSessionLength; otherwise, false. + public bool HasAvgSessionLength() + { + return AvgSessionLength != UNSET_VALUE; + } + + /// + /// Determines whether this instance has DaysSinceLastPlayed. + /// + /// true if this instance has DaysSinceLastPlayed; otherwise, false. + public bool HasDaysSinceLastPlayed() + { + return DaysSinceLastPlayed != (int) UNSET_VALUE; + } + + /// + /// Determines whether this instance has NumberOfSessions. + /// + /// true if this instance has NumberOfSessions; otherwise, false. + public bool HasNumberOfSessions() + { + return NumberOfSessions != (int) UNSET_VALUE; + } + + /// + /// Determines whether this instance has SessPercentile. + /// + /// true if this instance has SessPercentile; otherwise, false. + public bool HasSessPercentile() + { + return SessPercentile != UNSET_VALUE; + } + + /// + /// Determines whether this instance has SpendPercentile. + /// + /// true if this instance has SpendPercentile; otherwise, false. + public bool HasSpendPercentile() + { + return SpendPercentile != UNSET_VALUE; + } + + /// + /// Determines whether this instance has ChurnProbability. + /// + /// true if this instance has ChurnProbability; otherwise, false. + public bool HasChurnProbability() + { + return ChurnProbability != UNSET_VALUE; + } + + /// + /// Determines whether this instance has HighSpenderProbability. + /// + /// true if this instance has HighSpenderProbability; otherwise, false. + public bool HasHighSpenderProbability() + { + return HighSpenderProbability != UNSET_VALUE; + } + + /// + /// Determines whether this instance has TotalSpendNext28Days. + /// + /// true if this instance has TotalSpendNext28Days; otherwise, false. + public bool HasTotalSpendNext28Days() + { + return TotalSpendNext28Days != UNSET_VALUE; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs.meta new file mode 100644 index 0000000..5ed6e61 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/PlayerStats.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 0cf73f44d6d524deab1717d6e71e2c6d +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs new file mode 100644 index 0000000..44a10c3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs @@ -0,0 +1,57 @@ +// +// Copyright (C) 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + using System.Collections.Generic; + using UnityEngine.SocialPlatforms; + + /// + /// Recall Access data. This is the callback data + /// when requesting Recall Access. + /// + + public class RecallAccess + { + + /// + /// The session ID for the Recall Access. + /// + private string mSessionId; + + /// + /// Constructs a new RecallAccess object with the given session ID. + /// + /// The session ID for the Recall Access. + internal RecallAccess(string sessionId) + { + mSessionId = sessionId; + } + + /// + /// The session ID for the Recall Access. + /// + public string sessionId + { + get { return mSessionId; } + + internal set { mSessionId = value; } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs.meta new file mode 100644 index 0000000..c23bc98 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/RecallAccess.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 218f296754c404d38844833c7742e8c2 +labels: +- gvh +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame.meta new file mode 100644 index 0000000..599cdc6 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1bc47bd5631b849f88f2785c2d44019b +folderAsset: yes +timeCreated: 1435699548 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs new file mode 100644 index 0000000..aff1bda --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs @@ -0,0 +1,379 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.SavedGame +{ + using System; + using System.Collections.Generic; + + /// + /// An enum for the different strategies that can be used to resolve saved game conflicts (i.e. + /// conflicts produced by two or more separate writes to the same saved game at once). + /// + public enum ConflictResolutionStrategy + { + /// + /// Choose which saved game should be used on the basis of which one has the longest recorded + /// play time. In other words, in the case of a conflicting write, the saved game with the + /// longest play time will be considered cannonical. If play time has not been provided by the + /// developer, or in the case of two saved games with equal play times, + /// will be used instead. + /// + UseLongestPlaytime, + + /// + /// Choose the version of the saved game that existed before any conflicting write occurred. + /// Consider the following case: + /// - An initial version of a save game ("X") is written from a device ("Dev_A") + /// - The save game X is downloaded by another device ("Dev_B"). + /// - Dev_A writes a new version of the save game to the cloud ("Y") + /// - Dev_B does not see the new save game Y, and attempts to write a new save game ("Z"). + /// - Since Dev_B is performing a write using out of date information, a conflict is generated. + /// + /// In this situation, we can resolve the conflict by declaring either keeping Y as the + /// canonical version of the saved game (i.e. choose "original" aka ), + /// or by overwriting it with conflicting value, Z (i.e. choose "unmerged" aka + /// ). + /// + /// + UseOriginal, + + /// + /// See the documentation for + /// + UseUnmerged, + + /// + /// Manual resolution, no automatic resolution is attempted. + /// + UseManual, + + /// + /// The use last known good snapshot to resolve conflicts automatically. + /// + UseLastKnownGood, + + /// + /// The use most recently saved snapshot to resolve conflicts automatically. + /// + UseMostRecentlySaved + } + + /// + /// An enum for the different statuses that can be returned by the saved game client. + /// + public enum SavedGameRequestStatus + { + Success = 1, + + /// + /// The request failed due to a timeout. + /// + /// + TimeoutError = -1, + + /// + /// An unexpected internal error. Check the log for error messages. + /// + /// + InternalError = -2, + + /// + /// A error related to authentication. This is probably due to the user being signed out + /// before the request could be issued. + /// + /// + AuthenticationError = -3, + + /// + /// The request failed because it was given bad input (e.g. a filename with 200 characters). + /// + /// + BadInputError = -4 + } + + /// + /// An enum for the different UI statuses that can be returned by the saved game client. + /// + public enum SelectUIStatus + { + /// + /// The user selected a saved game. + /// + SavedGameSelected = 1, + + /// + /// The user closed the UI without selecting a saved game. + /// + /// + UserClosedUI = 2, + + /// + /// An unexpected internal error. Check the log for error messages. + /// + /// + InternalError = -1, + + /// + /// There was a timeout while displaying the UI. + /// + /// + TimeoutError = -2, + + /// + /// An error related to authentication. This error could be due to the user being signed out + /// before the request could be issued. + /// + /// + AuthenticationError = -3, + + /// + /// The request failed due to invalid input. For example, the filename exceeded the 200 character limit.. + /// + /// + BadInputError = -4, + + UiBusy = -5 + } + + /// + /// + /// A delegate that is invoked when we encounter a conflict during execution of + /// . The caller must resolve the + /// conflict using the passed . All passed metadata is open. + /// If was invoked with + /// prefetchDataOnConflict set to true, the and + /// will be equal to the binary data of the "original" and + /// "unmerged" saved game respectively (and null otherwise). Since conflict files may be generated + /// by other clients, it is possible that neither of the passed saved games were originally written + /// by the current device. Consequently, any conflict resolution strategy should not rely on local + /// data that is not part of the binary data of the passed saved games - this data will not be + /// present if conflict resolution occurs on a different device. In addition, since a given saved + /// game may have multiple conflicts, this callback must be designed to handle multiple invocations. + /// + public delegate void ConflictCallback(IConflictResolver resolver, ISavedGameMetadata original, + byte[] originalData, ISavedGameMetadata unmerged, byte[] unmergedData); + + /// + /// The main entry point for interacting with saved games. Saved games are persisted in the cloud + /// along with several game-specific properties ( for more + /// information). There are several core concepts involved with saved games: + /// + /// Filenames - act as unique identifiers for saved games. Two devices + /// performing a read or write using the same filename will end up reading or modifying the same + /// file (i.e. filenames are not device specific). + /// + /// + /// Saved Game Metadata are represented by . + /// The instances allow access to metadata properties about the underlying saved game (e.g. + /// description). In addition, metadata functions as a handle that are required to read and + /// manipulate saved game contents. Lastly, metadata may be "Open". Open metadata instances are + /// required to manipulate the underlying binary data of the saved game. See method comments to + /// determine whether a specific method requires or returns an open saved game. + /// + /// + /// Conflicts occur when multiple devices attempt to write to the same file + /// at the same time. The saved game system guarantees that no conflicting writes will be lost or + /// silently overwritten. Instead, they must be handled the next time the file with a conflict is + /// Opened. Conflicts can be handled automatically ( + /// ) or can be manuallyhandled by the developer + /// (). See the Open methods for more discussion. + /// + /// + /// Saved games will generally be used in the following workflow: + /// + /// Determine which saved game to use (either using a hardcoded filename or + /// ShowSelectSavedGameUI) + /// Open the file using OpenWithManualConflictResolution or + /// OpenWithAutomaticConflictResolution + /// Read the binary data of the saved game using ReadBinaryData handle it + /// as appropriate for your game. + /// When you have updates, persist them in the cloud using CommitUpdate. Note + /// that writing to the cloud is relatively expensive, and shouldn't be done frequently. + /// + /// + /// + /// See online + /// documentation for Saved Games for more information. + /// + public interface ISavedGameClient + { + /// + /// Opens the file with the indicated name and data source. If the file has an outstanding + /// conflict, it will be resolved using the specified conflict resolution strategy. The + /// metadata returned by this method will be "Open" - it can be used as a parameter for + /// and . + /// + /// The name of the file to open. Filenames must consist of + /// only non-URL reserved characters (i.e. a-z, A-Z, 0-9, or the symbols "-", ".", "_", or "~") + /// be between 1 and 100 characters in length (inclusive). + /// The data source to use. for a description + /// of the available options here. + /// The conflict resolution that should be used if any + /// conflicts are encountered while opening the file. + /// for a description of these strategies. + /// The callback that is invoked when this operation finishes. The + /// returned metadata will only be non-null if the open succeeded. This callback will always + /// execute on the game thread and the returned metadata (if any) will be "Open". + void OpenWithAutomaticConflictResolution(string filename, DataSource source, + ConflictResolutionStrategy resolutionStrategy, + Action callback); + + /// + /// Opens the file with the indicated name and data source. If there is a conflict that + /// requires resolution, it will be resolved manually using the passed conflict callback. Once + /// all pending conflicts are resolved, the completed callback will be invoked with the + /// retrieved data. In the event of an error, the completed callback will be invoked with the + /// corresponding error status. All callbacks will be executed on the game thread. + /// + /// The name of the file to open. Filenames must consist of + /// only non-URL reserved characters (i.e. a-z, A-Z, 0-9, or the symbols "-", ".", "_", or "~") + /// be between 1 and 100 characters in length (inclusive). + /// The data source to use. for a description + /// of the available options here. + /// If set to true, the data for the two + /// conflicting files will be automatically retrieved and passed as parameters in + /// . If set to false, null binary data + /// will be passed into and the caller will have to fetch + /// it themselves. + /// The callback that will be invoked if one or more conflict is + /// encountered while executing this method. Note that more than one conflict may be present + /// and that this callback might be executed more than once to resolve multiple conflicts. + /// This callback is always executed on the game thread. + /// The callback that is invoked when this operation finishes. + /// The returned metadata will only be non-null if the open succeeded. If an error is + /// encountered during conflict resolution, that error will be reflected here. This callback + /// will always execute on the game thread and the returned metadata (if any) will be "Open". + /// + void OpenWithManualConflictResolution(string filename, DataSource source, + bool prefetchDataOnConflict, ConflictCallback conflictCallback, + Action completedCallback); + + /// + /// Reads the binary data of the passed saved game. The passed metadata must be opened (i.e. + /// returns true). The callback will always be executed + /// on the game thread. + /// + /// The metadata for the saved game whose binary data we want to read. + /// This metadata must be open. If it is not open, the method will immediately fail with status + /// . + /// + /// The callback that is invoked when the read finishes. If the + /// read completed without error, the passed status will be and the passed + /// bytes will correspond to the binary data for the file. In the case of + /// + void ReadBinaryData(ISavedGameMetadata metadata, + Action completedCallback); + + /// + /// Shows the select saved game UI with the indicated configuration. If the user selects a + /// saved game in that UI, it will be returned in the passed callback. This metadata will be + /// unopened and must be passed to either or + /// in order to retrieve the binary data. + /// The callback will always be executed on the game thread. + /// + /// The user-visible title of the displayed selection UI. + /// The maximum number of saved games the UI may display. + /// This value must be greater than 0. + /// If set to true, show UI that will allow the user to + /// create a new saved game. + /// If set to true show UI that will allow the user to + /// delete a saved game. + /// The callback that is invoked when an error occurs or if the user + /// finishes interacting with the UI. If the user selected a saved game, this will be passed + /// into the callback along with the status. This saved game + /// will not be Open, and must be opened before it can be written to or its binary data can be + /// read. If the user backs out of the UI without selecting a saved game, this callback will + /// receive and a null saved game. This callback will always execute + /// on the game thread. + void ShowSelectSavedGameUI(string uiTitle, uint maxDisplayedSavedGames, bool showCreateSaveUI, + bool showDeleteSaveUI, Action callback); + + /// + /// Durably commits an update to the passed saved game. When this method returns successfully, + /// the data is durably persisted to disk and will eventually be uploaded to the cloud (in + /// practice, this will happen very quickly unless the device does not have a network + /// connection). If an update to the saved game has occurred after the metadata was retrieved + /// from the cloud, this update will produce a conflict (this commonly occurs if two different + /// devices are writing to the cloud at the same time). All conflicts must be handled the next + /// time this saved game is opened. See and + /// for more information. + /// + /// The metadata for the saved game to update. This metadata must be + /// Open (i.e. returns true)."/> If it is not open, the + /// method will immediately fail with status + /// All updates that should be applied to the saved game + /// metadata. + /// The new binary content of the saved game + /// The callback that is invoked when this operation finishes. + /// The returned metadata will only be non-null if the commit succeeded. If an error is + /// encountered during conflict resolution, that error will be reflected here. This callback + /// will always execute on the game thread and the returned metadata (if any) will NOT be + /// "Open" (i.e. commiting an update closes the metadata). + void CommitUpdate(ISavedGameMetadata metadata, SavedGameMetadataUpdate updateForMetadata, + byte[] updatedBinaryData, Action callback); + + /// + /// Returns the metadata for all known saved games for this game. All returned saved games are + /// not open, and must be opened before they can be used for writes or binary data reads. The + /// callback will always occur on the game thread. + /// + /// The data source to use. for a description + /// of the available options here. + /// The callback that is invoked when this operation finishes. + /// The returned metadata will only be non-empty if the commit succeeded. If an error is + /// encountered during the fetch, that error will be reflected here. This callback + /// will always execute on the game thread and the returned metadata (if any) will NOT be + /// "Open". + void FetchAllSavedGames(DataSource source, + Action> callback); + + /// + /// Delete the specified snapshot. + /// This will delete the data of the snapshot locally and on the server. + /// + /// the saved game metadata identifying the data to + /// delete. + void Delete(ISavedGameMetadata metadata); + } + + /// + /// An interface that allows developers to resolve metadata conflicts that may be encountered while + /// opening saved games. + /// + public interface IConflictResolver + { + /// + /// Resolves the conflict by choosing the passed metadata to be canonical. The passed metadata + /// must be one of the two instances passed as parameters into - + /// this instance will be kept as the cannonical value in the cloud. + /// + /// The chosen metadata. This metadata must be open. If it is not + /// open, the invocation of that produced this + /// ConflictResolver will immediately fail with . + void ChooseMetadata(ISavedGameMetadata chosenMetadata); + + /// + /// Resolves the conflict and updates the data. + /// + /// Metadata for the chosen version. This is either the + /// original or unmerged metadata provided when the callback is invoked. + /// Metadata update, same as when committing changes. + /// Updated data to use when resolving the conflict. + void ResolveConflict(ISavedGameMetadata chosenMetadata, SavedGameMetadataUpdate metadataUpdate, + byte[] updatedData); + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs.meta new file mode 100644 index 0000000..6303390 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 5d4ff89980bdd4c9780aa3ceee54a51b +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs new file mode 100644 index 0000000..7b80eac --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs @@ -0,0 +1,77 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.SavedGame +{ + using System; + + /// + /// Interface representing the metadata for a saved game. These instances are also used as handles + /// for reading and writing the content of the underlying file. + /// + public interface ISavedGameMetadata + { + /// + /// Returns true if this metadata can be used for operations related to raw file data (i.e. + /// the binary data contained in the underlying file). Metadata returned by Open operations + /// will be "Open". After an update to the file is committed or the metadata is used to resolve + /// a conflict, the corresponding Metadata is closed, and IsOpen will return false. + /// + /// + /// true if this instance is open; otherwise, false. + bool IsOpen { get; } + + /// + /// Returns the filename for this saved game. A saved game filename will only consist of + /// non-URL reserved characters (i.e. a-z, A-Z, 0-9, or the symbols "-", ".", "_", or "~") + /// and will between 1 and 100 characters in length (inclusive). + /// + /// The filename. + string Filename { get; } + + /// + /// Returns a human-readable description of what the saved game contains. This may be null. + /// + /// The description. + string Description { get; } + + /// + /// A URL corresponding to the PNG-encoded image corresponding to this saved game. null if + /// the saved game does not have a cover image. + /// + /// The cover image URL. + string CoverImageURL { get; } + + /// + /// Returns the total time played by the player for this saved game. This value is + /// developer-specified and may be tracked in any way that is appropriate to the game. Note + /// that this value is specific to this specific saved game (unless the developer intentionally + /// sets the same value on all saved games). If the value was not set, this will be equal to + /// TimeSpan.FromMilliseconds(0) + /// + /// The total time played. + TimeSpan TotalTimePlayed { get; } + + /// + /// A timestamp corresponding to the last modification to the underlying saved game. If the + /// saved game is newly created, this value will correspond to the time the first Open + /// occurred. Otherwise, this corresponds to time the last successful write occurred (either by + /// CommitUpdate or Resolve methods). + /// + /// The last modified timestamp. + DateTime LastModifiedTimestamp { get; } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs.meta new file mode 100644 index 0000000..b65aa21 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/ISavedGameMetadata.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a94650f478358403ea166d374b2a950c +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs new file mode 100644 index 0000000..967ce54 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs @@ -0,0 +1,160 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.BasicApi.SavedGame +{ + using System; + using GooglePlayGames.OurUtils; + + /// + /// A struct representing the mutation of saved game metadata. Fields can either have a new value + /// or be untouched (in which case the corresponding field in the saved game metadata will be + /// untouched). Instances must be built using + /// and once created, these instances are immutable and threadsafe. + /// + public struct SavedGameMetadataUpdate + { + private readonly bool mDescriptionUpdated; + private readonly string mNewDescription; + private readonly bool mCoverImageUpdated; + private readonly byte[] mNewPngCoverImage; + private readonly TimeSpan? mNewPlayedTime; + + /// + /// Initializes a new instance of the struct using the specified builder. + /// + /// The builder used to initialize the saved game metadata update. + private SavedGameMetadataUpdate(Builder builder) + { + mDescriptionUpdated = builder.mDescriptionUpdated; + mNewDescription = builder.mNewDescription; + mCoverImageUpdated = builder.mCoverImageUpdated; + mNewPngCoverImage = builder.mNewPngCoverImage; + mNewPlayedTime = builder.mNewPlayedTime; + } + + /// + /// Gets whether the description has been updated in the metadata. + /// + public bool IsDescriptionUpdated + { + get { return mDescriptionUpdated; } + } + + /// + /// Gets the updated description for the saved game, if it has been changed. + /// + public string UpdatedDescription + { + get { return mNewDescription; } + } + + /// + /// Gets whether the cover image has been updated in the metadata. + /// + public bool IsCoverImageUpdated + { + get { return mCoverImageUpdated; } + } + + /// + /// Gets the updated PNG cover image, if it has been changed. + /// + public byte[] UpdatedPngCoverImage + { + get { return mNewPngCoverImage; } + } + + /// + /// Gets whether the played time has been updated in the metadata. + /// + public bool IsPlayedTimeUpdated + { + get { return mNewPlayedTime.HasValue; } + } + + /// + /// Gets the updated played time, if it has been changed. + /// + public TimeSpan? UpdatedPlayedTime + { + get { return mNewPlayedTime; } + } + + /// + /// A builder for constructing instances of . + /// + public struct Builder + { + internal bool mDescriptionUpdated; + internal string mNewDescription; + internal bool mCoverImageUpdated; + internal byte[] mNewPngCoverImage; + internal TimeSpan? mNewPlayedTime; + + /// + /// Sets the description to be updated in the saved game metadata. + /// + /// The new description to set. + /// The builder with the updated description. + public Builder WithUpdatedDescription(string description) + { + mNewDescription = Misc.CheckNotNull(description); + mDescriptionUpdated = true; + return this; + } + + /// + /// Sets the PNG cover image to be updated in the saved game metadata. + /// + /// The new PNG image data for the cover image. + /// The builder with the updated cover image. + public Builder WithUpdatedPngCoverImage(byte[] newPngCoverImage) + { + mCoverImageUpdated = true; + mNewPngCoverImage = newPngCoverImage; + return this; + } + + /// + /// Sets the played time to be updated in the saved game metadata. + /// + /// The new played time to set. + /// The builder with the updated played time. + /// Thrown if the played time exceeds the maximum allowed value. + public Builder WithUpdatedPlayedTime(TimeSpan newPlayedTime) + { + if (newPlayedTime.TotalMilliseconds > ulong.MaxValue) + { + throw new InvalidOperationException("Timespans longer than ulong.MaxValue " + + "milliseconds are not allowed"); + } + + mNewPlayedTime = newPlayedTime; + return this; + } + + /// + /// Builds a new instance with the configured updates. + /// + /// A new instance of . + public SavedGameMetadataUpdate Build() + { + return new SavedGameMetadataUpdate(this); + } + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs.meta new file mode 100644 index 0000000..cb2edf9 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SavedGame/SavedGameMetadataUpdate.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 602d9e1c90f0144e79536115f3614478 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs new file mode 100644 index 0000000..e0f9c1d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs @@ -0,0 +1,112 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames.BasicApi +{ + /// + /// Enum representing the direction of score page navigation. + /// + public enum ScorePageDirection + { + /// + /// Represents the forward direction (next page). + /// + Forward = 1, + + /// + /// Represents the backward direction (previous page). + /// + Backward = 2, + } + + /// + /// Score page token. This holds the internal token used + /// to page through the score pages. The id, collection, and + /// timespan are added as a convenience, and not actually part of the + /// page token returned from the SDK. + /// + public class ScorePageToken + { + private string mId; + private object mInternalObject; + private LeaderboardCollection mCollection; + private LeaderboardTimeSpan mTimespan; + private ScorePageDirection mDirection; + + /// + /// Initializes a new instance of the class. + /// + /// The internal object representing the page token. + /// The leaderboard ID. + /// The leaderboard collection type. For example, public or social. + /// The timespan of the leaderboard. For example, daily or all-time. + /// The direction of the score page navigation, such as forward or backward. + internal ScorePageToken(object internalObject, string id, + LeaderboardCollection collection, LeaderboardTimeSpan timespan, + ScorePageDirection direction) + { + mInternalObject = internalObject; + mId = id; + mCollection = collection; + mTimespan = timespan; + mDirection = direction; + } + + /// + /// Gets the collection type of the leaderboard. For example, public or social. + /// + public LeaderboardCollection Collection + { + get { return mCollection; } + } + + /// + /// Gets the timespan of the leaderboard. For example, daily or all-time. + /// + public LeaderboardTimeSpan TimeSpan + { + get { return mTimespan; } + } + + /// + /// Gets the direction of the score page navigation. For example, forward or backward. + /// + public ScorePageDirection Direction + { + get { return mDirection; } + } + + /// + /// Gets the leaderboard ID associated with this token. + /// + public string LeaderboardId + { + get { return mId; } + } + + /// + /// Gets the internal object representing the page token. + /// This is an internal implementation detail and should not be accessed directly. + /// + internal object InternalObject + { + get { return mInternalObject; } + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs.meta new file mode 100644 index 0000000..2b9f8c5 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/ScorePageToken.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3eade9d49f3e341ddb2ba8209e7ddf42 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs new file mode 100644 index 0000000..657c172 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs @@ -0,0 +1,29 @@ +namespace GooglePlayGames.BasicApi +{ + /// + /// Enum to specify the interactivity of the sign in flow. + /// + public enum SignInInteractivity + { + /// no UIs will be shown (if UIs are needed, it will fail rather than show them). + NoPrompt, + + /// + /// This may show UIs, consent dialogs, etc. + /// At the end of the process, callback will be invoked to notify of the result. + /// Once the callback returns true, the user is considered to be authenticated. + /// + CanPromptAlways, + + /// When this is selected, PlayGamesPlatform.Authenticate does the following in order: + /// 1. Attempt to silent sign in. + /// 2. If silent sign in fails, check if user has previously declined to sign in and don’t prompt interactive + /// sign in if they have. + /// 3. Check the internet connection and fail with NO_INTERNET_CONNECTION if there is no internet connection. + /// 4. Prompt interactive sign in. + /// 5. If the interactive sign in is not successful (user declines or cancels), then + /// remember this for step 2 the next time the user opens the game and don’t ask for sign-in. + /// + CanPromptOnce + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs.meta new file mode 100644 index 0000000..afaf0ce --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInInteractivity.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: f5c7733064f2b09dc8df0009b3bbb1d6 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs new file mode 100644 index 0000000..84a51e6 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs @@ -0,0 +1,17 @@ +namespace GooglePlayGames.BasicApi +{ + /// + /// Enum to specify the sign in status. + /// + public enum SignInStatus + { + /// The operation was successful. + Success, + + /// An internal error occurred. + InternalError, + + /// The sign in was canceled. + Canceled, + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs.meta new file mode 100644 index 0000000..5b8c624 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/BasicApi/SignInStatus.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 0992bc2597d741e59dc3f8c963a3ca25 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs new file mode 100644 index 0000000..176350c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs @@ -0,0 +1,71 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if UNITY_ANDROID + +namespace GooglePlayGames { + /// + /// This file is automatically generated DO NOT EDIT! + /// + /// These are the constants defined in the Play Games Console for Game Services + /// Resources. + /// + /// + /// File containing information about the game. This is automatically updated by running the + /// platform-appropriate setup commands in the Unity editor (which does a simple search / replace + /// on the IDs in the form "__ID__"). We can check whether any particular field has been updated + /// by checking whether it still retains its initial value - we prevent the constants from being + /// replaced in the aforementioned search/replace by stripping off the leading and trailing "__". + /// + public static class GameInfo { + + private const string UnescapedApplicationId = "APP_ID"; + private const string UnescapedIosClientId = "IOS_CLIENTID"; + private const string UnescapedWebClientId = "WEB_CLIENTID"; + private const string UnescapedNearbyServiceId = "NEARBY_SERVICE_ID"; + + public const string ApplicationId = "794819463840"; // Filled in automatically + public const string IosClientId = "__IOS_CLIENTID__"; // Filled in automatically + public const string WebClientId = "794819463840-29f4mdui49adq6gq43dtmqiknljv1jrb.apps.googleusercontent.com"; // Filled in automatically + public const string NearbyConnectionServiceId = ""; + + public static bool ApplicationIdInitialized() { + return !string.IsNullOrEmpty(ApplicationId) && !ApplicationId.Equals(ToEscapedToken(UnescapedApplicationId)); + } + + public static bool IosClientIdInitialized() { + return !string.IsNullOrEmpty(IosClientId) && !IosClientId.Equals(ToEscapedToken(UnescapedIosClientId)); + } + + public static bool WebClientIdInitialized() { + return !string.IsNullOrEmpty(WebClientId) && !WebClientId.Equals(ToEscapedToken(UnescapedWebClientId)); + } + + public static bool NearbyConnectionsInitialized() { + return !string.IsNullOrEmpty(NearbyConnectionServiceId) && + !NearbyConnectionServiceId.Equals(ToEscapedToken(UnescapedNearbyServiceId)); + } + + /// + /// Returns an escaped token (i.e. one flanked with "__") for the passed token + /// + /// The escaped token. + /// The Token + private static string ToEscapedToken(string token) { + return string.Format("__{0}__", token); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs.meta new file mode 100644 index 0000000..aa49e49 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/GameInfo.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a722d413080904cc1bd07f4db21e1af1 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform.meta new file mode 100644 index 0000000..b7673b5 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: ef66268ee929544fb82bbef6ac13bafe +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs new file mode 100644 index 0000000..f9a65eb --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs @@ -0,0 +1,371 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System; + using GooglePlayGames.BasicApi; + using UnityEngine; +#if UNITY_2017_1_OR_NEWER + using UnityEngine.Networking; +#endif + using UnityEngine.SocialPlatforms; + + /// + /// Delegate for reporting achievement progress. + /// + /// The achievement ID. + /// The progress of the achievement (a value between 0.0 and 100.0). + /// A callback to be invoked with a boolean indicating success. + internal delegate void ReportProgress(string id, double progress, Action callback); + + /// + /// Represents a Google Play Games achievement. It can be used to report an achievement + /// to the API, offering identical functionality as . + /// Implements both the and interfaces. + /// + internal class PlayGamesAchievement : IAchievement, IAchievementDescription + { + /// + /// The callback for reporting progress. + /// + private readonly ReportProgress mProgressCallback; + + /// + /// The achievement's ID. + /// + private string mId = string.Empty; + + /// + /// A flag indicating if the achievement is incremental. + /// + private bool mIsIncremental = false; + + /// + /// The current steps completed for an incremental achievement. + /// + private int mCurrentSteps = 0; + + /// + /// The total steps required for an incremental achievement. + /// + private int mTotalSteps = 0; + + /// + /// The percentage of completion. + /// + private double mPercentComplete = 0.0; + + /// + /// A flag indicating if the achievement is completed (unlocked). + /// + private bool mCompleted = false; + + /// + /// A flag indicating if the achievement is hidden. + /// + private bool mHidden = false; + + /// + /// The last time the achievement was modified. + /// + private DateTime mLastModifiedTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); + + /// + /// The title of the achievement. + /// + private string mTitle = string.Empty; + + /// + /// The URL for the revealed (locked) achievement image. + /// + private string mRevealedImageUrl = string.Empty; + + /// + /// The URL for the unlocked achievement image. + /// + private string mUnlockedImageUrl = string.Empty; +#if UNITY_2017_1_OR_NEWER + /// + /// The web request used to fetch the achievement image. + /// + private UnityWebRequest mImageFetcher = null; +#else + /// + /// The web request used to fetch the achievement image. + /// + private WWW mImageFetcher = null; +#endif + /// + /// The downloaded achievement image as a Texture2D. + /// + private Texture2D mImage = null; + + /// + /// The description of the achievement. + /// + private string mDescription = string.Empty; + + /// + /// The points awarded for unlocking the achievement. + /// + private ulong mPoints = 0; + + /// + /// Initializes a new instance of the class. + /// Uses the default progress reporting mechanism from . + /// + internal PlayGamesAchievement() + : this(PlayGamesPlatform.Instance.ReportProgress) + { + } + + /// + /// Initializes a new instance of the class with a custom progress callback. + /// + /// The callback to use for reporting progress. + internal PlayGamesAchievement(ReportProgress progressCallback) + { + mProgressCallback = progressCallback; + } + + /// + /// Initializes a new instance of the class from a object. + /// + /// The achievement data from the Basic API. + internal PlayGamesAchievement(Achievement ach) : this() + { + this.mId = ach.Id; + this.mIsIncremental = ach.IsIncremental; + this.mCurrentSteps = ach.CurrentSteps; + this.mTotalSteps = ach.TotalSteps; + if (ach.IsIncremental) + { + if (ach.TotalSteps > 0) + { + this.mPercentComplete = + ((double) ach.CurrentSteps / (double) ach.TotalSteps) * 100.0; + } + else + { + this.mPercentComplete = 0.0; + } + } + else + { + this.mPercentComplete = ach.IsUnlocked ? 100.0 : 0.0; + } + + this.mCompleted = ach.IsUnlocked; + this.mHidden = !ach.IsRevealed; + this.mLastModifiedTime = ach.LastModifiedTime; + this.mTitle = ach.Name; + this.mDescription = ach.Description; + this.mPoints = ach.Points; + this.mRevealedImageUrl = ach.RevealedImageUrl; + this.mUnlockedImageUrl = ach.UnlockedImageUrl; + } + + /// + /// Reveals, unlocks or increments the achievement. + /// + /// + /// This method is equivalent to calling . + /// The and properties should be set before calling this method. + /// + /// An action to be invoked with a value indicating whether the operation was successful. + public void ReportProgress(Action callback) + { + mProgressCallback.Invoke(mId, mPercentComplete, callback); + } + + /// + /// Asynchronously loads the achievement's image from its URL. + /// + /// The image once loaded; otherwise, null. + private Texture2D LoadImage() + { + if (hidden) + { + // Return null, as hidden achievements do not have images. + return null; + } + + string url = completed ? mUnlockedImageUrl : mRevealedImageUrl; + + // The URL can be null if no image is configured. + if (!string.IsNullOrEmpty(url)) + { + if (mImageFetcher == null || mImageFetcher.url != url) + { +#if UNITY_2017_1_OR_NEWER + mImageFetcher = UnityWebRequestTexture.GetTexture(url); +#else + mImageFetcher = new WWW(url); +#endif + mImage = null; + } + + // If we already have the texture, return it to avoid repeated downloads. + if (mImage != null) + { + return mImage; + } + + if (mImageFetcher.isDone) + { +#if UNITY_2017_1_OR_NEWER + mImage = DownloadHandlerTexture.GetContent(mImageFetcher); +#else + mImage = mImageFetcher.texture; +#endif + return mImage; + } + } + + // If there is no URL or the download is not complete, return null. + return null; + } + + + /// + /// Gets or sets the ID of this achievement. + /// + /// The achievement ID. + public string id + { + get { return mId; } + set { mId = value; } + } + + /// + /// Gets a value indicating whether this achievement is incremental. + /// + /// This value is set by . + /// true if incremental; otherwise, false. + public bool isIncremental + { + get { return mIsIncremental; } + } + + /// + /// Gets the current number of steps completed for this achievement. + /// + /// This value is only defined for incremental achievements and is set by . + /// The current steps. + public int currentSteps + { + get { return mCurrentSteps; } + } + + /// + /// Gets the total number of steps for this achievement. + /// + /// This value is only defined for incremental achievements and is set by . + /// The total steps. + public int totalSteps + { + get { return mTotalSteps; } + } + + /// + /// Gets or sets the completion percentage of this achievement. + /// + /// The percent completed (from 0.0 to 100.0). + public double percentCompleted + { + get { return mPercentComplete; } + set { mPercentComplete = value; } + } + + /// + /// Gets a value indicating whether this achievement is completed (unlocked). + /// + /// This value is set by . + /// true if completed; otherwise, false. + public bool completed + { + get { return this.mCompleted; } + } + + /// + /// Gets a value indicating whether this achievement is hidden. + /// + /// This value is set by . + /// true if hidden; otherwise, false. + public bool hidden + { + get { return this.mHidden; } + } + + /// + /// Gets the date and time this achievement was last reported. + /// + /// The last reported date. + public DateTime lastReportedDate + { + get { return mLastModifiedTime; } + } + + /// + /// Gets the title of the achievement. + /// + /// The title. + public String title + { + get { return mTitle; } + } + + /// + /// Gets the image for the achievement, loading it asynchronously if necessary. + /// + /// The achievement image as a . + public Texture2D image + { + get { return LoadImage(); } + } + + /// + /// Gets the description for the achieved state. + /// + /// The achieved description. + public string achievedDescription + { + get { return mDescription; } + } + + /// + /// Gets the description for the unachieved state. + /// + /// The unachieved description. + public string unachievedDescription + { + get { return mDescription; } + } + + /// + /// Gets the point value of the achievement. + /// + /// The points. + public int points + { + get { return (int) mPoints; } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs.meta new file mode 100644 index 0000000..fecc388 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesAchievement.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e5354c32a5dc64372ba5102f7f787adf +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs new file mode 100644 index 0000000..d7306c3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs @@ -0,0 +1,303 @@ +// +// Copyright (C) 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System.Collections.Generic; + using GooglePlayGames.BasicApi; + using UnityEngine; + using UnityEngine.SocialPlatforms; + + /// + /// Represents a Google Play Games leaderboard. The class provides a way to configure and store + /// data for a specific leaderboard. + /// Implements Unity's generic ILeaderboard interface. + /// + public class PlayGamesLeaderboard : ILeaderboard + { + /// + /// The ID of the leaderboard. + /// + private string mId; + + /// + /// The user scope for the leaderboard scores. For example, determines if scores are fetched + /// from all players (Global) or just the user's friends (FriendsOnly). + /// + private UserScope mUserScope; + + /// + /// Specifies the start rank and the number of scores to retrieve. + /// + private Range mRange; + + /// + /// Filters scores by time period. For example, AllTime, Weekly, Daily. + /// + private TimeScope mTimeScope; + + /// + /// An array of user IDs to filter the scores. + /// + private string[] mFilteredUserIds; + + /// + /// A boolean flag that is true while the scores are being loaded; otherwise, false. + /// + private bool mLoading; + + /// + /// The score of the local user. + /// + private IScore mLocalUserScore; + + /// + /// The approximate total number of scores in the leaderboard. + /// + private uint mMaxRange; + + /// + /// The list of loaded scores. + /// + private List mScoreList = new List(); + + /// + /// The title of the leaderboard. + /// + private string mTitle; + + /// + /// Initializes a new instance of the class. + /// + /// The leaderboard ID. + public PlayGamesLeaderboard(string id) + { + mId = id; + } + + #region ILeaderboard implementation + + /// + /// Sets a filter to load scores only for a specific set of users. + /// + /// The array of user IDs to filter by. + public void SetUserFilter(string[] userIDs) + { + mFilteredUserIds = userIDs; + } + + /// + /// Initiates the loading of scores from the Google Play Games platform. + /// + /// A callback that will be invoked with a boolean indicating the success of the operation. + public void LoadScores(System.Action callback) + { + PlayGamesPlatform.Instance.LoadScores(this, callback); + } + + /// + /// Gets a value indicating whether the leaderboard scores are currently loading. + /// + /// true if loading; otherwise, false. + public bool loading + { + get { return mLoading; } + internal set { mLoading = value; } + } + + /// + /// Gets or sets the leaderboard ID. + /// + /// The leaderboard ID. + public string id + { + get { return mId; } + set { mId = value; } + } + + /// + /// Gets or sets the user scope for the scores to be loaded. + /// + /// The user scope. + public UserScope userScope + { + get { return mUserScope; } + set { mUserScope = value; } + } + + /// + /// Gets or sets the rank range for the scores to be loaded. + /// + /// The rank range. + public Range range + { + get { return mRange; } + set { mRange = value; } + } + + /// + /// Gets or sets the time scope for the scores to be loaded. + /// + /// The time scope. + public TimeScope timeScope + { + get { return mTimeScope; } + set { mTimeScope = value; } + } + + /// + /// Gets the local user's score on this leaderboard. + /// + /// The local user's score. + public IScore localUserScore + { + get { return mLocalUserScore; } + } + + /// + /// Gets the approximate number of total scores in the leaderboard. + /// + /// The maximum range of scores. + public uint maxRange + { + get { return mMaxRange; } + } + + /// + /// Gets the array of loaded scores. + /// + /// The scores. + public IScore[] scores + { + get + { + PlayGamesScore[] arr = new PlayGamesScore[mScoreList.Count]; + mScoreList.CopyTo(arr); + return arr; + } + } + + /// + /// Gets the title of the leaderboard. + /// + /// The title. + public string title + { + get { return mTitle; } + } + + #endregion + + /// + /// Populates the leaderboard's properties from a object. + /// + /// The data object containing leaderboard information. + /// true if the data was valid and applied; otherwise, false. + internal bool SetFromData(LeaderboardScoreData data) + { + if (data.Valid) + { + OurUtils.Logger.d("Setting leaderboard from: " + data); + SetMaxRange(data.ApproximateCount); + SetTitle(data.Title); + SetLocalUserScore((PlayGamesScore) data.PlayerScore); + foreach (IScore score in data.Scores) + { + AddScore((PlayGamesScore) score); + } + + mLoading = data.Scores.Length == 0 || HasAllScores(); + } + + return data.Valid; + } + + /// + /// Sets the maximum range (approximate total number of scores). + /// + /// The value for the maximum range. + internal void SetMaxRange(ulong val) + { + mMaxRange = (uint) val; + } + + /// + /// Sets the title of the leaderboard. + /// + /// The title string. + internal void SetTitle(string value) + { + mTitle = value; + } + + /// + /// Sets the local user's score. + /// + /// The local user's score. + internal void SetLocalUserScore(PlayGamesScore score) + { + mLocalUserScore = score; + } + + /// + /// Adds a score to the internal list of scores. If a user filter is active, + /// the score will only be added if the user ID matches the filter. + /// + /// The score to add. + /// The new count of scores in the list. + internal int AddScore(PlayGamesScore score) + { + if (mFilteredUserIds == null || mFilteredUserIds.Length == 0) + { + mScoreList.Add(score); + } + else + { + foreach (string fid in mFilteredUserIds) + { + if (fid.Equals(score.userID)) + { + mScoreList.Add(score); + break; + } + } + } + + return mScoreList.Count; + } + + /// + /// Gets the number of scores currently loaded. + /// + /// The score count. + public int ScoreCount + { + get { return mScoreList.Count; } + } + + /// + /// Checks if all requested scores have been loaded. + /// + /// true if the number of loaded scores matches the requested range or the total number of scores; otherwise, false. + internal bool HasAllScores() + { + return mScoreList.Count >= mRange.count || mScoreList.Count >= maxRange; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs.meta new file mode 100644 index 0000000..6fdb4b4 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLeaderboard.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a027e4767bd0f41509b9ef6bd2f6080e +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs new file mode 100644 index 0000000..e77ac88 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs @@ -0,0 +1,227 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System; + using GooglePlayGames.BasicApi; + using UnityEngine.SocialPlatforms; + + /// + /// Represents the Google Play Games local user, providing access to + /// authentication and user-specific functionality. Implements Unity's + /// ILocalUser interface. + /// + public class PlayGamesLocalUser : PlayGamesUserProfile, ILocalUser + { + /// + /// A reference to the active Play Games platform instance. + /// + internal PlayGamesPlatform mPlatform; + + /// + /// Cached player stats. + /// + private PlayerStats mStats; + + /// + /// Initializes a new instance of the class. + /// + /// The platform instance. + internal PlayGamesLocalUser(PlayGamesPlatform plaf) + : base("localUser", string.Empty, string.Empty) + { + mPlatform = plaf; + mStats = null; + } + + /// + /// Authenticates the local user. This is equivalent to calling + /// . + /// + /// A callback to invoke with a boolean indicating success. + public void Authenticate(Action callback) + { + mPlatform.Authenticate(status => callback(status == SignInStatus.Success)); + } + + /// + /// Authenticates the local user with an extended callback that includes the reason for failure. + /// This is equivalent to calling . + /// + /// + /// A callback to invoke with a boolean indicating success and a string containing the status. + /// + public void Authenticate(Action callback) + { + mPlatform.Authenticate(status => callback(status == SignInStatus.Success, status.ToString())); + } + + /// + /// Loads the friends of the authenticated user. + /// + /// A callback to invoke with a boolean indicating success. + public void LoadFriends(Action callback) + { + mPlatform.LoadFriends(this, callback); + } + + /// + /// Gets the local user's friends. This will be null until completes. + /// + /// An array of the user's friends, or null if not yet loaded. + public IUserProfile[] friends + { + get { return mPlatform.GetFriends(); } + } + + /// + /// Gets a value indicating whether the local user is authenticated to Google Play Games. + /// + /// true if authenticated; otherwise, false. + public bool authenticated + { + get { return mPlatform.IsAuthenticated(); } + } + + /// + /// Gets a value indicating whether the user is underage. + /// + /// This is not implemented and returns true as a placeholder. + public bool underage + { + get { return true; } + } + + + + /// + /// Gets the display name of the local user. + /// + /// The user's display name. + public new string userName + { + get + { + string retval = string.Empty; + if (authenticated) + { + retval = mPlatform.GetUserDisplayName(); + if (!base.userName.Equals(retval)) + { + ResetIdentity(retval, mPlatform.GetUserId(), mPlatform.GetUserImageUrl()); + } + } + + return retval; + } + } + + /// + /// Gets the user's Google ID (Player ID). + /// + /// + /// This ID is persistent and uniquely identifies the user across all games. + /// It is the preferred way to identify a player. + /// + /// The user's Google ID. + public new string id + { + get + { + string retval = string.Empty; + if (authenticated) + { + retval = mPlatform.GetUserId(); + if (!base.id.Equals(retval)) + { + ResetIdentity(mPlatform.GetUserDisplayName(), retval, mPlatform.GetUserImageUrl()); + } + } + + return retval; + } + } + + + /// + /// Gets a value indicating whether this user is a friend of the local user. + /// + /// Always returns true. + public new bool isFriend + { + get { return true; } + } + + /// + /// Gets the user's state. + /// + /// For the local user, this is always UserState.Online. + public new UserState state + { + get { return UserState.Online; } + } + + /// + /// Gets the URL of the user's avatar image. + /// + /// The avatar image URL. + public new string AvatarURL + { + get + { + string retval = string.Empty; + if (authenticated) + { + retval = mPlatform.GetUserImageUrl(); + if (!base.id.Equals(retval)) + { + ResetIdentity(mPlatform.GetUserDisplayName(), + mPlatform.GetUserId(), retval); + } + } + + return retval; + } + } + + /// + /// Gets the player's stats from the server. + /// + /// A callback to be invoked with the status code and the player's stats. + /// The stats may be cached from a previous call. + /// + public void GetStats(Action callback) + { + if (mStats == null || !mStats.Valid) + { + mPlatform.GetPlayerStats((rc, stats) => + { + mStats = stats; + callback(rc, stats); + }); + } + else + { + // Return cached stats with a success code. + callback(CommonStatusCodes.Success, mStats); + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs.meta new file mode 100644 index 0000000..f3c3d99 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesLocalUser.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3b5f03fe051cb4a41a3b5489bd63c24c +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs new file mode 100644 index 0000000..95d8693 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs @@ -0,0 +1,1404 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.Events; + using GooglePlayGames.BasicApi.Nearby; + using GooglePlayGames.BasicApi.SavedGame; + using GooglePlayGames.OurUtils; + using UnityEngine; + using UnityEngine.SocialPlatforms; + + /// + /// Provides access to the Google Play Games platform. This is an implementation of + /// UnityEngine.SocialPlatforms.ISocialPlatform. Activate this platform by calling + /// the method, then authenticate by calling + /// the method. After authentication + /// completes, you may call the other methods of this class. This is not a complete + /// implementation of the ISocialPlatform interface. Methods lacking an implementation + /// or whose behavior is at variance with the standard are noted as such. + /// + public class PlayGamesPlatform : ISocialPlatform + { + /// Singleton instance + private static volatile PlayGamesPlatform sInstance = null; + + /// status of nearby connection initialization. + private static volatile bool sNearbyInitializePending; + + /// Reference to the nearby client. + /// This is static since it can be used without using play game services. + private static volatile INearbyConnectionClient sNearbyConnectionClient; + + /// The local user. + private PlayGamesLocalUser mLocalUser = null; + + /// Reference to the platform specific implementation. + private IPlayGamesClient mClient = null; + + /// the default leaderboard we show on ShowLeaderboardUI + private string mDefaultLbUi = null; + + /// the mapping table from alias to leaderboard/achievement id. + private Dictionary mIdMap = new Dictionary(); + + /// + /// Initializes a new instance of the class. + /// + /// Implementation client to use for this instance. + internal PlayGamesPlatform(IPlayGamesClient client) + { + this.mClient = Misc.CheckNotNull(client); + this.mLocalUser = new PlayGamesLocalUser(this); + } + + /// + /// Initializes a new instance of the class. + /// + private PlayGamesPlatform() + { + GooglePlayGames.OurUtils.Logger.d("Creating new PlayGamesPlatform"); + this.mLocalUser = new PlayGamesLocalUser(this); + } + + /// + /// Gets or sets a value indicating whether debug logs are enabled. This property + /// may be set before calling method. + /// + /// + /// true if debug log enabled; otherwise, false. + /// + public static bool DebugLogEnabled + { + get { return GooglePlayGames.OurUtils.Logger.DebugLogEnabled; } + + set { GooglePlayGames.OurUtils.Logger.DebugLogEnabled = value; } + } + + /// + /// Gets the singleton instance of the Play Games platform. + /// + /// + /// The instance. + /// + public static PlayGamesPlatform Instance + { + get + { + if (sInstance == null) + { + OurUtils.Logger.d("Initializing the PlayGamesPlatform instance."); + sInstance = + new PlayGamesPlatform(PlayGamesClientFactory.GetPlatformPlayGamesClient()); + } + + return sInstance; + } + } + + /// + /// Gets the nearby connection client. NOTE: Can be null until the nearby client + /// is initialized. Call InitializeNearby to use callback to be notified when initialization + /// is complete. + /// + /// The nearby. + public static INearbyConnectionClient Nearby + { + get + { + if (sNearbyConnectionClient == null && !sNearbyInitializePending) + { + sNearbyInitializePending = true; + InitializeNearby(null); + } + + return sNearbyConnectionClient; + } + } + + /// Gets the saved game client object. + /// The saved game client. + public ISavedGameClient SavedGame + { + get { return mClient.GetSavedGameClient(); } + } + + /// Gets the events client object. + /// The events client. + public IEventsClient Events + { + get { return mClient.GetEventsClient(); } + } + + /// + /// Gets the local user. + /// + /// + /// The local user. + /// + public ILocalUser localUser + { + get { return mLocalUser; } + } + + /// + /// Initializes the nearby connection platform. + /// + /// This call initializes the nearby connection platform. This + /// is independent of the Play Game Services initialization. Multiple + /// calls to this method are ignored. + /// + /// Callback invoked when complete. + public static void InitializeNearby(Action callback) + { + OurUtils.Logger.d("Calling InitializeNearby!"); + if (sNearbyConnectionClient == null) + { +#if UNITY_ANDROID && !UNITY_EDITOR + NearbyConnectionClientFactory.Create(client => { + OurUtils.Logger.d("Nearby Client Created!!"); + sNearbyConnectionClient = client; + if (callback != null) { + callback.Invoke(client); + } + else { + OurUtils.Logger.d("Initialize Nearby callback is null"); + } + }); +#else + sNearbyConnectionClient = new DummyNearbyConnectionClient(); + if (callback != null) + { + callback.Invoke(sNearbyConnectionClient); + } + +#endif + } + else if (callback != null) + { + OurUtils.Logger.d("Nearby Already initialized: calling callback directly"); + callback.Invoke(sNearbyConnectionClient); + } + else + { + OurUtils.Logger.d("Nearby Already initialized"); + } + } + + /// + /// Activates the Play Games platform as the implementation of Social.Active. + /// After calling this method, you can call methods on Social.Active. For + /// example, Social.Active.Authenticate(). + /// + /// The singleton instance. + public static PlayGamesPlatform Activate() + { + GooglePlayGames.OurUtils.Logger.d("Activating PlayGamesPlatform."); + + Social.Active = PlayGamesPlatform.Instance; + GooglePlayGames.OurUtils.Logger.d( + "PlayGamesPlatform activated: " + Social.Active); + return PlayGamesPlatform.Instance; + } + + /// + /// Specifies that the ID fromId should be implicitly replaced by toId + /// on any calls that take a leaderboard or achievement ID. + /// + /// After a mapping is + /// registered, you can use fromId instead of toId when making a call. + /// For example, the following two snippets are equivalent: + /// ReportProgress("Cfiwjew894_AQ", 100.0, callback); + /// is equivalent to: + /// AddIdMapping("super-combo", "Cfiwjew894_AQ"); + /// ReportProgress("super-combo", 100.0, callback); + /// + /// + /// The identifier to map. + /// + /// + /// The identifier that fromId will be mapped to. + /// + public void AddIdMapping(string fromId, string toId) + { + mIdMap[fromId] = toId; + } + + /// + /// Returns the result of the automatic sign-in attempt. Play Games SDK automatically + /// prompts users to sign in when the game is started. This API is useful for understanding + /// if your game has access to Play Games Services and should be used when your game is + /// started in order to conditionally enable or disable your Play Games Services + /// integration. + /// + /// The callback to call when authentication finishes. + public void Authenticate(Action callback) + { + mClient.Authenticate(callback); + } + + /// + /// Provided for compatibility with ISocialPlatform. + /// + /// + /// Unused parameter for this implementation. + /// Callback invoked when complete. + public void Authenticate(ILocalUser unused, Action callback) + { + Authenticate(status => callback(status == SignInStatus.Success)); + } + + /// + /// Provided for compatibility with ISocialPlatform. + /// + /// + /// Unused parameter for this implementation. + /// Callback invoked when complete. + public void Authenticate(ILocalUser unused, Action callback) + { + Authenticate(status => callback(status == SignInStatus.Success, status.ToString())); + } + + /// + /// Manually requests that your game performs sign in with Play Games Services. + /// + /// + /// Note that a sign-in attempt will be made automatically when your game's application + /// started. For this reason most games will not need to manually request to perform sign-in + /// unless the automatic sign-in attempt failed and your game requires access to Play Games + /// Services. + /// + /// + public void ManuallyAuthenticate(Action callback) { + mClient.ManuallyAuthenticate(callback); + } + + /// + /// Determines whether the user is authenticated. + /// + /// + /// true if the user is authenticated; otherwise, false. + /// + public bool IsAuthenticated() + { + return mClient != null && mClient.IsAuthenticated(); + } + + /// + /// Requests server-side access to Player Games Services for the currently signed in player. + /// + /// When requested an authorization code is returned that can be used by your game-server to + /// exchange for an access token and conditionally a refresh token (when + /// forceRefreshToken is true). The access token may then be used by your game-server to + /// access the Play Games Services web APIs. This is commonly used to complete a sign-in flow + /// by verifying the Play Games Services player id. + /// + ///

If forceRefreshToken is true, when exchanging the authorization code a refresh + /// token will be returned in addition to the access token. The refresh token allows the + /// game-server to request additional access tokens, allowing your game-server to continue + /// accesses Play Games Services while the user is not actively playing your app.

+ /// If set to true, a refresh token will be returned along with the access token. + /// The callback to invoke with the server authorization code. + public void RequestServerSideAccess(bool forceRefreshToken, Action callback) + { + Misc.CheckNotNull(callback); + + if (!IsAuthenticated()) + { + OurUtils.Logger.e("RequestServerSideAccess() can only be called after authentication."); + InvokeCallbackOnGameThread(callback, null); + return; + } + + mClient.RequestServerSideAccess(forceRefreshToken, callback); + } + + /// + /// Requests server-side access to Player Games Services for the currently signed in player. + /// + /// When requested an authorization code is returned that can be used by your game-server to + /// exchange for an access token and conditionally a refresh token (when + /// forceRefreshToken is true). The access token may then be used by your game-server to + /// access the Play Games Services web APIs. This is commonly used to complete a sign-in flow + /// by verifying the Play Games Services player id. + /// + ///

If forceRefreshToken is true, when exchanging the authorization code a refresh + /// token will be returned in addition to the access token. The refresh token allows the + /// game-server to request additional access tokens, allowing your game-server to continue + /// accesses Play Games Services while the user is not actively playing your app.

+ /// If set to true, a refresh token will be returned along with the access token. + /// The OAuth 2.0 scopes to request access to. + /// The callback to invoke with the AuthResponse. + public void RequestServerSideAccess(bool forceRefreshToken, List scopes, Action callback) + { + Misc.CheckNotNull(callback); + + if (!IsAuthenticated()) + { + OurUtils.Logger.e("RequestServerSideAccess() can only be called after authentication."); + InvokeCallbackOnGameThread(callback, null); + return; + } + + mClient.RequestServerSideAccess(forceRefreshToken, scopes, callback); + } + + /// + /// Requests access to the recall API. + /// + /// The callback to invoke with the recall access. + public void RequestRecallAccess(Action callback) + { + Misc.CheckNotNull(callback); + + mClient.RequestRecallAccessToken(callback); + } + + /// + /// Loads the users. + /// + /// User identifiers. + /// Callback invoked when complete. + public void LoadUsers(string[] userIds, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetUserId() can only be called after authentication."); + callback(new IUserProfile[0]); + + return; + } + + mClient.LoadUsers(userIds, callback); + } + + /// + /// Returns the user's Google ID. + /// + /// + /// The user's Google ID. No guarantees are made as to the meaning or format of + /// this identifier except that it is unique to the user who is signed in. + /// + public string GetUserId() + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetUserId() can only be called after authentication."); + return "0"; + } + + return mClient.GetUserId(); + } + + /// + /// Gets the player stats. + /// + /// Callback invoked when completed. + public void GetPlayerStats(Action callback) + { + if (mClient != null && mClient.IsAuthenticated()) + { + mClient.GetPlayerStats(callback); + } + else + { + GooglePlayGames.OurUtils.Logger.e( + "GetPlayerStats can only be called after authentication."); + + callback(CommonStatusCodes.SignInRequired, new PlayerStats()); + } + } + + /// + /// Returns the user's display name. + /// + /// + /// The user display name. For example, "Bruno Oliveira" + /// + public string GetUserDisplayName() + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetUserDisplayName can only be called after authentication."); + return string.Empty; + } + + return mClient.GetUserDisplayName(); + } + + /// + /// Returns the user's avatar URL if they have one. + /// + /// + /// The URL, or null if the user is not authenticated or does not have + /// an avatar. + /// + public string GetUserImageUrl() + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetUserImageUrl can only be called after authentication."); + return null; + } + + return mClient.GetUserImageUrl(); + } + + /// + /// Reports the progress of an achievement (reveal, unlock or increment). This method attempts + /// to implement the expected behavior of ISocialPlatform.ReportProgress as closely as possible, + /// as described below. Although this method works with incremental achievements for compatibility + /// purposes, calling this method for incremental achievements is not recommended, + /// since the Play Games API exposes incremental achievements in a very different way + /// than the interface presented by ISocialPlatform.ReportProgress. The implementation of this + /// method for incremental achievements attempts to produce the correct result, but may be + /// imprecise. If possible, call instead. + /// + /// + /// The ID of the achievement to unlock, reveal or increment. This can be a raw Google Play + /// Games achievement ID (alphanumeric string), or an alias that was previously configured + /// by a call to . + /// + /// + /// Progress of the achievement. If the achievement is standard (not incremental), then + /// a progress of 0.0 will reveal the achievement and 100.0 will unlock it. Behavior of other + /// values is undefined. If the achievement is incremental, then this value is interpreted + /// as the total percentage of the achievement's progress that the player should have + /// as a result of this call (regardless of the progress they had before). So if the + /// player's previous progress was 30% and this call specifies 50.0, the new progress will + /// be 50% (not 80%). + /// + /// + /// Callback that will be called to report the result of the operation: true on + /// success, false otherwise. + /// + public void ReportProgress(string achievementID, double progress, Action callback) + { + callback = ToOnGameThread(callback); + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "ReportProgress can only be called after authentication."); + callback.Invoke(false); + + return; + } + + // map ID, if it's in the dictionary + GooglePlayGames.OurUtils.Logger.d("ReportProgress, " + achievementID + ", " + progress); + achievementID = MapId(achievementID); + + // if progress is 0.0, we just want to reveal it + if (progress < 0.000001) + { + GooglePlayGames.OurUtils.Logger.d( + "Progress 0.00 interpreted as request to reveal."); + mClient.RevealAchievement(achievementID, callback); + return; + } + + mClient.LoadAchievements(ach => + { + for (int i = 0; i < ach.Length; i++) + { + if (ach[i].Id == achievementID) + { + if (ach[i].IsIncremental) + { + GooglePlayGames.OurUtils.Logger.d("Progress " + progress + + " interpreted as incremental target (approximate)."); + + if (progress >= 0.0 && progress <= 1.0) + { + // in a previous version, incremental progress was reported by using the range [0-1] + GooglePlayGames.OurUtils.Logger.w( + "Progress " + progress + + " is less than or equal to 1. You might be trying to use values in the range of [0,1], while values are expected to be within the range [0,100]. If you are using the latter, you can safely ignore this message."); + } + + mClient.SetStepsAtLeast(achievementID, progressToSteps(progress, ach[i].TotalSteps), callback); + } + else + { + if (progress >= 100) + { + // unlock it! + GooglePlayGames.OurUtils.Logger.d("Progress " + progress + " interpreted as UNLOCK."); + mClient.UnlockAchievement(achievementID, callback); + } + else + { + // not enough to unlock + GooglePlayGames.OurUtils.Logger.d( + "Progress " + progress + " not enough to unlock non-incremental achievement."); + callback.Invoke(false); + } + } + + return; + } + } + + // Achievement not found + GooglePlayGames.OurUtils.Logger.e("Unable to locate achievement " + achievementID); + callback.Invoke(false); + }); + } + + /// + /// Converts a progress value to a number of steps. + /// + /// + /// The progress value. + /// + /// + /// The total number of steps. + /// + /// + /// The number of steps. + /// + internal static int progressToSteps(double progress, int totalSteps) { + return (progress >= 100.0) ? totalSteps : (int) (progress * totalSteps / 100.0); + } + + /// + /// Reveals the achievement with the passed identifier. This is a Play Games extension of the ISocialPlatform API. + /// + /// If the operation succeeds, the callback + /// will be invoked on the game thread with true. If the operation fails, the + /// callback will be invoked with false. This operation will immediately fail if + /// the user is not authenticated (the callback will immediately be invoked with + /// false). If the achievement is already in a revealed state, this call will + /// succeed immediately. + /// + /// + /// The ID of the achievement to increment. This can be a raw Google Play + /// Games achievement ID (alphanumeric string), or an alias that was previously configured + /// by a call to . + /// + /// + /// The callback to call to report the success or failure of the operation. The callback + /// will be called with true to indicate success or false for failure. + /// + public void RevealAchievement(string achievementID, Action callback = null) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "RevealAchievement can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + // map ID, if it's in the dictionary + GooglePlayGames.OurUtils.Logger.d( + "RevealAchievement: " + achievementID); + achievementID = MapId(achievementID); + mClient.RevealAchievement(achievementID, callback); + } + + /// + /// Unlocks the achievement with the passed identifier. This is a Play Games extension of the ISocialPlatform API. + /// + /// If the operation succeeds, the callback + /// will be invoked on the game thread with true. If the operation fails, the + /// callback will be invoked with false. This operation will immediately fail if + /// the user is not authenticated (the callback will immediately be invoked with + /// false). If the achievement is already unlocked, this call will + /// succeed immediately. + /// + /// + /// The ID of the achievement to increment. This can be a raw Google Play + /// Games achievement ID (alphanumeric string), or an alias that was previously configured + /// by a call to . + /// + /// + /// The callback to call to report the success or failure of the operation. The callback + /// will be called with true to indicate success or false for failure. + /// + public void UnlockAchievement(string achievementID, Action callback = null) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "UnlockAchievement can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + // map ID, if it's in the dictionary + GooglePlayGames.OurUtils.Logger.d( + "UnlockAchievement: " + achievementID); + achievementID = MapId(achievementID); + mClient.UnlockAchievement(achievementID, callback); + } + + /// + /// Increments an achievement. This is a Play Games extension of the ISocialPlatform API. + /// + /// + /// The ID of the achievement to increment. This can be a raw Google Play + /// Games achievement ID (alphanumeric string), or an alias that was previously configured + /// by a call to . + /// + /// + /// The number of steps to increment the achievement by. + /// + /// + /// The callback to call to report the success or failure of the operation. The callback + /// will be called with true to indicate success or false for failure. + /// + public void IncrementAchievement(string achievementID, int steps, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "IncrementAchievement can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + // map ID, if it's in the dictionary + GooglePlayGames.OurUtils.Logger.d( + "IncrementAchievement: " + achievementID + ", steps " + steps); + achievementID = MapId(achievementID); + mClient.IncrementAchievement(achievementID, steps, callback); + } + + /// + /// Set an achievement to have at least the given number of steps completed. + /// Calling this method while the achievement already has more steps than + /// the provided value is a no-op. Once the achievement reaches the + /// maximum number of steps, the achievement is automatically unlocked, + /// and any further mutation operations are ignored. + /// + /// + /// The ID of the achievement to increment. This can be a raw Google Play + /// Games achievement ID (alphanumeric string), or an alias that was previously configured + /// by a call to . + /// + /// + /// The number of steps to increment the achievement by. + /// + /// + /// The callback to call to report the success or failure of the operation. The callback + /// will be called with true to indicate success or false for failure. + /// + public void SetStepsAtLeast(string achievementID, int steps, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "SetStepsAtLeast can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + // map ID, if it's in the dictionary + GooglePlayGames.OurUtils.Logger.d( + "SetStepsAtLeast: " + achievementID + ", steps " + steps); + achievementID = MapId(achievementID); + mClient.SetStepsAtLeast(achievementID, steps, callback); + } + + /// + /// Loads the Achievement descriptions. + /// + /// The callback to receive the descriptions + public void LoadAchievementDescriptions(Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "LoadAchievementDescriptions can only be called after authentication."); + if (callback != null) + { + callback.Invoke(null); + } + + return; + } + + mClient.LoadAchievements(ach => + { + IAchievementDescription[] data = new IAchievementDescription[ach.Length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = new PlayGamesAchievement(ach[i]); + } + + callback.Invoke(data); + }); + } + + /// + /// Loads the achievement state for the current user. + /// + /// The callback to receive the achievements + public void LoadAchievements(Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("LoadAchievements can only be called after authentication."); + callback.Invoke(null); + + return; + } + + mClient.LoadAchievements(ach => + { + IAchievement[] data = new IAchievement[ach.Length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = new PlayGamesAchievement(ach[i]); + } + + callback.Invoke(data); + }); + } + + /// + /// Creates an achievement object which may be subsequently used to report an + /// achievement. + /// + /// + /// The achievement object. + /// + public IAchievement CreateAchievement() + { + return new PlayGamesAchievement(); + } + + /// + /// Reports a score to a leaderboard. + /// + /// + /// The score to report. + /// + /// + /// The ID of the leaderboard on which the score is to be posted. This may be a raw + /// Google Play Games leaderboard ID or an alias configured through a call to + /// . + /// + /// + /// The callback to call to report the success or failure of the operation. The callback + /// will be called with true to indicate success or false for failure. + /// + public void ReportScore(long score, string board, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("ReportScore can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + GooglePlayGames.OurUtils.Logger.d("ReportScore: score=" + score + ", board=" + board); + string leaderboardId = MapId(board); + mClient.SubmitScore(leaderboardId, score, callback); + } + + /// + /// Submits the score for the currently signed-in player + /// to the leaderboard associated with a specific id + /// and metadata (such as something the player did to earn the score). + /// + /// Score to report. + /// leaderboard id. + /// metadata about the score. + /// Callback invoked upon completion. + public void ReportScore(long score, string board, string metadata, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("ReportScore can only be called after authentication."); + if (callback != null) + { + callback.Invoke(false); + } + + return; + } + + GooglePlayGames.OurUtils.Logger.d("ReportScore: score=" + score + + ", board=" + board + + " metadata=" + metadata); + string leaderboardId = MapId(board); + mClient.SubmitScore(leaderboardId, score, metadata, callback); + } + + /// + /// Loads the scores relative the player. + /// + /// This returns the 25 + /// (which is the max results returned by the SDK per call) scores + /// that are around the player's score on the Public, all time leaderboard. + /// Use the overloaded methods which are specific to GPGS to modify these + /// parameters. + /// + /// Leaderboard Id + /// Callback to invoke when completed. + public void LoadScores(string leaderboardId, Action callback) + { + LoadScores( + leaderboardId, + LeaderboardStart.PlayerCentered, + mClient.LeaderboardMaxResults(), + LeaderboardCollection.Public, + LeaderboardTimeSpan.AllTime, + (scoreData) => callback(scoreData.Scores)); + } + + /// + /// Loads the scores using the provided parameters. This call may fail when trying to load friends with + /// ResponseCode.ResolutionRequired if the user has not share the friends list with the game. In this case, use + /// AskForLoadFriendsResolution to request access. + /// + /// Leaderboard identifier. + /// Start either top scores, or player centered. + /// Row count. the number of rows to return. + /// Collection. social or public + /// Time span. daily, weekly, all-time + /// Callback to invoke when completed. + public void LoadScores( + string leaderboardId, + LeaderboardStart start, + int rowCount, + LeaderboardCollection collection, + LeaderboardTimeSpan timeSpan, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("LoadScores can only be called after authentication."); + callback(new LeaderboardScoreData( + leaderboardId, + ResponseStatus.NotAuthorized)); + return; + } + + mClient.LoadScores( + leaderboardId, + start, + rowCount, + collection, + timeSpan, + callback); + } + + /// + /// Loads more scores. This call may fail when trying to load friends with + /// ResponseCode.ResolutionRequired if the user has not share the friends list with the game. In this case, use + /// AskForLoadFriendsResolution to request access. + /// + /// This is used to load the next "page" of scores. + /// Token used to recording the loading. + /// Row count. + /// Callback invoked when complete. + public void LoadMoreScores( + ScorePageToken token, + int rowCount, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("LoadMoreScores can only be called after authentication."); + callback( + new LeaderboardScoreData( + token.LeaderboardId, + ResponseStatus.NotAuthorized)); + return; + } + + mClient.LoadMoreScores(token, rowCount, callback); + } + + /// + /// Returns a leaderboard object that can be configured to + /// load scores. + /// + /// The leaderboard object. + public ILeaderboard CreateLeaderboard() + { + return new PlayGamesLeaderboard(mDefaultLbUi); + } + + /// + /// Shows the standard Google Play Games achievements user interface, + /// which allows the player to browse their achievements. + /// + public void ShowAchievementsUI() + { + ShowAchievementsUI(null); + } + + /// + /// Shows the standard Google Play Games achievements user interface, + /// which allows the player to browse their achievements. + /// + /// If non-null, the callback is invoked when + /// the achievement UI is dismissed + public void ShowAchievementsUI(Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("ShowAchievementsUI can only be called after authentication."); + return; + } + + GooglePlayGames.OurUtils.Logger.d("ShowAchievementsUI callback is " + callback); + mClient.ShowAchievementsUI(callback); + } + + /// + /// Shows the standard Google Play Games leaderboards user interface, + /// which allows the player to browse their leaderboards. If you have + /// configured a specific leaderboard as the default through a call to + /// , the UI will show that + /// specific leaderboard only. Otherwise, a list of all the leaderboards + /// will be shown. + /// + public void ShowLeaderboardUI() + { + GooglePlayGames.OurUtils.Logger.d("ShowLeaderboardUI with default ID"); + ShowLeaderboardUI(MapId(mDefaultLbUi), null); + } + + /// + /// Shows the standard Google Play Games leaderboard UI for the given + /// leaderboard. + /// + /// + /// The ID of the leaderboard to display. This may be a raw + /// Google Play Games leaderboard ID or an alias configured through a call to + /// . + /// + public void ShowLeaderboardUI(string leaderboardId) + { + if (leaderboardId != null) + { + leaderboardId = MapId(leaderboardId); + } + + ShowLeaderboardUI(leaderboardId, LeaderboardTimeSpan.AllTime, null); + } + + /// + /// Shows the leaderboard UI and calls the specified callback upon + /// completion. + /// + /// leaderboard ID, can be null meaning all leaderboards. + /// Callback to call. If null, nothing is called. + public void ShowLeaderboardUI(string leaderboardId, Action callback) + { + ShowLeaderboardUI(leaderboardId, LeaderboardTimeSpan.AllTime, callback); + } + + /// + /// Shows the leaderboard UI and calls the specified callback upon + /// completion. + /// + /// leaderboard ID, can be null meaning all leaderboards. + /// Timespan to display scores in the leaderboard. + /// Callback to call. If null, nothing is called. + public void ShowLeaderboardUI( + string leaderboardId, + LeaderboardTimeSpan span, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("ShowLeaderboardUI can only be called after authentication."); + if (callback != null) + { + callback(UIStatus.NotAuthorized); + } + + return; + } + + GooglePlayGames.OurUtils.Logger.d("ShowLeaderboardUI, lbId=" + + leaderboardId + " callback is " + callback); + mClient.ShowLeaderboardUI(leaderboardId, span, callback); + } + + /// + /// Sets the default leaderboard for the leaderboard UI. After calling this + /// method, a call to will show only the specified + /// leaderboard instead of showing the list of all leaderboards. + /// + /// + /// The ID of the leaderboard to display on the default UI. This may be a raw + /// Google Play Games leaderboard ID or an alias configured through a call to + /// . + /// + public void SetDefaultLeaderboardForUI(string lbid) + { + GooglePlayGames.OurUtils.Logger.d("SetDefaultLeaderboardForUI: " + lbid); + if (lbid != null) + { + lbid = MapId(lbid); + } + + mDefaultLbUi = lbid; + } + + /// + /// Loads the friends that also play this game. See loadConnectedPlayers. + /// + /// This is a callback variant of LoadFriends. When completed, + /// the friends list set in the user object, so they can accessed via the + /// friends property as needed. + /// + /// The current local user + /// Callback invoked when complete. + public void LoadFriends(ILocalUser user, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "LoadScores can only be called after authentication."); + if (callback != null) + { + callback(false); + } + + return; + } + + mClient.LoadFriends(callback); + } + + /// + /// Loads the leaderboard based on the constraints in the leaderboard + /// object. + /// + /// The leaderboard object. This is created by + /// calling CreateLeaderboard(), and then initialized appropriately. + /// Callback invoked when complete. + public void LoadScores(ILeaderboard board, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e("LoadScores can only be called after authentication."); + if (callback != null) + { + callback(false); + } + + return; + } + + LeaderboardTimeSpan timeSpan; + switch (board.timeScope) + { + case TimeScope.AllTime: + timeSpan = LeaderboardTimeSpan.AllTime; + break; + case TimeScope.Week: + timeSpan = LeaderboardTimeSpan.Weekly; + break; + case TimeScope.Today: + timeSpan = LeaderboardTimeSpan.Daily; + break; + default: + timeSpan = LeaderboardTimeSpan.AllTime; + break; + } + + ((PlayGamesLeaderboard) board).loading = true; + GooglePlayGames.OurUtils.Logger.d("LoadScores, board=" + board + + " callback is " + callback); + mClient.LoadScores( + board.id, + LeaderboardStart.PlayerCentered, + board.range.count > 0 ? board.range.count : mClient.LeaderboardMaxResults(), + board.userScope == UserScope.FriendsOnly ? LeaderboardCollection.Social : LeaderboardCollection.Public, + timeSpan, + (scoreData) => HandleLoadingScores( + (PlayGamesLeaderboard) board, scoreData, callback)); + } + + /// + /// Check if the leaderboard is currently loading. + /// + /// true, if loading was gotten, false otherwise. + /// The leaderboard to check for loading in progress + public bool GetLoading(ILeaderboard board) + { + return board != null && board.loading; + } + + /// + /// Shows the Player Profile UI for the given user identifier. + /// + /// User Identifier. + /// + /// The game's own display name of the player referred to by userId. + /// + /// + /// The game's own display name of the current player. + /// + /// Callback invoked upon completion. + public void ShowCompareProfileWithAlternativeNameHintsUI(string userId, + string otherPlayerInGameName, + string currentPlayerInGameName, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "ShowCompareProfileWithAlternativeNameHintsUI can only be called after authentication."); + InvokeCallbackOnGameThread(callback, UIStatus.NotAuthorized); + + return; + } + + GooglePlayGames.OurUtils.Logger.d( + "ShowCompareProfileWithAlternativeNameHintsUI, userId=" + userId + " callback is " + + callback); + mClient.ShowCompareProfileWithAlternativeNameHintsUI(userId, otherPlayerInGameName, + currentPlayerInGameName, callback); + } + + /// + /// Returns if the user has allowed permission for the game to access the friends list. + /// + /// If true, this call will clear any locally cached data and + /// attempt to fetch the latest data from the server. Normally, this should be set to + /// false to gain advantages of data caching. + /// Callback invoked upon completion. + public void GetFriendsListVisibility(bool forceReload, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetFriendsListVisibility can only be called after authentication."); + InvokeCallbackOnGameThread(callback, FriendsListVisibilityStatus.NotAuthorized); + return; + } + + GooglePlayGames.OurUtils.Logger.d("GetFriendsListVisibility, callback is " + callback); + mClient.GetFriendsListVisibility(forceReload, callback); + } + + /// + /// Shows the appropriate platform-specific friends sharing UI. + /// The callback to invoke when complete. If null, + /// no callback is called. + /// + public void AskForLoadFriendsResolution(Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "AskForLoadFriendsResolution can only be called after authentication."); + InvokeCallbackOnGameThread(callback, UIStatus.NotAuthorized); + return; + } + + GooglePlayGames.OurUtils.Logger.d("AskForLoadFriendsResolution callback is " + callback); + mClient.AskForLoadFriendsResolution(callback); + } + + /// + /// Gets status of the last call to load friends. + /// + public LoadFriendsStatus GetLastLoadFriendsStatus() + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "GetLastLoadFriendsStatus can only be called after authentication."); + return LoadFriendsStatus.NotAuthorized; + } + + return mClient.GetLastLoadFriendsStatus(); + } + + /// + /// Loads the first page of the user's friends. + /// + /// + /// The number of entries to request for this initial page. Note that if cached + /// data already exists, the returned buffer may contain more than this size, but it is + /// guaranteed to contain at least this many if the collection contains enough records. + /// + /// + /// If true, this call will clear any locally cached data and attempt to + /// fetch the latest data from the server. This would commonly be used for something like a + /// user-initiated refresh. Normally, this should be set to false to gain advantages of data caching. + /// + /// Callback invoked upon completion with the status. + public void LoadFriends(int pageSize, bool forceReload, + Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "LoadFriends can only be called after authentication."); + InvokeCallbackOnGameThread(callback, LoadFriendsStatus.NotAuthorized); + return; + } + + mClient.LoadFriends(pageSize, forceReload, callback); + } + + /// + /// Loads the friends list page + /// + /// + /// The number of entries to request for this initial page. Note that if cached + /// data already exists, the returned buffer may contain more than this size, but it is + /// guaranteed to contain at least this many if the collection contains enough records. + /// + /// + public void LoadMoreFriends(int pageSize, Action callback) + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.e( + "LoadMoreFriends can only be called after authentication."); + InvokeCallbackOnGameThread(callback, LoadFriendsStatus.NotAuthorized); + return; + } + + mClient.LoadMoreFriends(pageSize, callback); + } + + /// + /// Handles the processing of scores during loading. + /// + /// leaderboard being loaded + /// Score data. + /// Callback invoked when complete. + internal void HandleLoadingScores( + PlayGamesLeaderboard board, + LeaderboardScoreData scoreData, + Action callback) + { + bool ok = board.SetFromData(scoreData); + if (ok && !board.HasAllScores() && scoreData.NextPageToken != null) + { + int rowCount = board.range.count - board.ScoreCount; + + // need to load more scores + mClient.LoadMoreScores( + scoreData.NextPageToken, + rowCount, + (nextScoreData) => + HandleLoadingScores(board, nextScoreData, callback)); + } + else + { + callback(ok); + } + } + + /// + /// Internal implmentation of getFriends.Gets the friends. + /// + /// The friends. + internal IUserProfile[] GetFriends() + { + if (!IsAuthenticated()) + { + GooglePlayGames.OurUtils.Logger.d("Cannot get friends when not authenticated!"); + return new IUserProfile[0]; + } + + return mClient.GetFriends(); + } + + /// + /// Maps the alias to the identifier. + /// + /// Alias to map + /// This maps an aliased ID to the actual id. The intent of + /// this method is to allow easy to read constants to be used instead of + /// the generated ids. + /// + /// The identifier, or null if not found. + private string MapId(string id) + { + if (id == null) + { + return null; + } + + if (mIdMap.ContainsKey(id)) + { + string result = mIdMap[id]; + GooglePlayGames.OurUtils.Logger.d("Mapping alias " + id + " to ID " + result); + return result; + } + + return id; + } + + private static void InvokeCallbackOnGameThread(Action callback, T data) + { + if (callback == null) + { + return; + } + + PlayGamesHelperObject.RunOnGameThread(() => { callback(data); }); + } + + private static Action ToOnGameThread(Action toConvert) + { + if (toConvert == null) + { + return delegate { }; + } + + return (val) => PlayGamesHelperObject.RunOnGameThread(() => toConvert(val)); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs.meta new file mode 100644 index 0000000..994be87 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesPlatform.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c1de7754a6e7f4fb08b76780a184b3ca +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs new file mode 100644 index 0000000..132a74e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs @@ -0,0 +1,149 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System; + using UnityEngine.SocialPlatforms; + + /// + /// Represents a score on a Google Play Games leaderboard. Implements the Unity + /// IScore interface. + /// + public class PlayGamesScore : IScore + { + /// + /// The ID of the leaderboard this score belongs to. + /// + private string mLbId = null; + + /// + /// The numerical value of the score. + /// + private long mValue = 0; + + /// + /// The rank of this score on the leaderboard. + /// + private ulong mRank = 0; + + /// + /// The ID of the player who achieved this score. + /// + private string mPlayerId = string.Empty; + + /// + /// The metadata associated with this score (also known as a score tag). + /// + private string mMetadata = string.Empty; + + /// + /// The date and time when the score was achieved. + /// + private DateTime mDate = new DateTime(1970, 1, 1, 0, 0, 0); + + /// + /// Initializes a new instance of the class. + /// + /// The date the score was achieved. + /// The leaderboard ID. + /// The rank of the score. + /// The player's ID. + /// The numerical score value. + /// The metadata (score tag) associated with the score. + internal PlayGamesScore(DateTime date, string leaderboardId, + ulong rank, string playerId, ulong value, string metadata) + { + this.mDate = date; + mLbId = leaderboardID; + this.mRank = rank; + this.mPlayerId = playerId; + this.mValue = (long) value; + this.mMetadata = metadata; + } + + /// + /// Reports this score to the Google Play Games services. This is equivalent + /// to calling . + /// + /// A callback to be invoked with a boolean indicating the success of the operation. + public void ReportScore(Action callback) + { + PlayGamesPlatform.Instance.ReportScore(mValue, mLbId, mMetadata, callback); + } + + /// + /// Gets or sets the ID of the leaderboard this score is for. + /// + public string leaderboardID + { + get { return mLbId; } + set { mLbId = value; } + } + + /// + /// Gets or sets the score value. + /// + public long value + { + get { return mValue; } + set { mValue = value; } + } + + /// + /// Gets the date and time this score was achieved. + /// + public DateTime date + { + get { return mDate; } + } + + /// + /// Gets the score value as a formatted string. + /// + public string formattedValue + { + get { return mValue.ToString(); } + } + + /// + /// Gets the ID of the user who achieved this score. + /// + public string userID + { + get { return mPlayerId; } + } + + /// + /// Gets the rank of this score in the leaderboard. + /// + public int rank + { + get { return (int) mRank; } + } + + /// + /// Gets the metadata associated with this score (also known as a score tag). + /// + public string metaData + { + get { return mMetadata; } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs.meta new file mode 100644 index 0000000..e45e321 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesScore.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 2a6e2425305ab455a91061b1eb955b38 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs new file mode 100644 index 0000000..0f9440d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs @@ -0,0 +1,299 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using System; + using System.Collections; + using GooglePlayGames.OurUtils; + using UnityEngine; +#if UNITY_2017_2_OR_NEWER + using UnityEngine.Networking; +#endif + using UnityEngine.SocialPlatforms; + + /// + /// Represents a Google Play Games user profile. Implements the Unity's IUserProfile + /// interface and is used as a base class for . + /// + public class PlayGamesUserProfile : IUserProfile + { + /// + /// The user's display name. + /// + private string mDisplayName; + + /// + /// The user's unique player ID. + /// + private string mPlayerId; + + /// + /// The URL for the user's avatar image. + /// + private string mAvatarUrl; + + /// + /// A flag indicating if this user is a friend of the local user. + /// + private bool mIsFriend; + + /// + /// A flag to prevent multiple concurrent image loading coroutines. + /// + private volatile bool mImageLoading = false; + + /// + /// The cached user avatar image. + /// + private Texture2D mImage; + + /// + /// Initializes a new instance of the class. + /// + /// The user's display name. + /// The user's player ID. + /// The URL of the user's avatar. + internal PlayGamesUserProfile(string displayName, string playerId, + string avatarUrl) + { + mDisplayName = displayName; + mPlayerId = playerId; + setAvatarUrl(avatarUrl); + mImageLoading = false; + mIsFriend = false; + } + + /// + /// Initializes a new instance of the class. + /// + /// The user's display name. + /// The user's player ID. + /// The URL of the user's avatar. + /// A flag indicating if the user is a friend. + internal PlayGamesUserProfile(string displayName, string playerId, string avatarUrl, + bool isFriend) + { + mDisplayName = displayName; + mPlayerId = playerId; + mAvatarUrl = avatarUrl; + mImageLoading = false; + mIsFriend = isFriend; + } + + /// + /// Resets the user's identity with new information. If the avatar URL has changed, + /// the old image is discarded. + /// + /// The new display name. + /// The new player ID. + /// The new avatar URL. + protected void ResetIdentity(string displayName, string playerId, + string avatarUrl) + { + mDisplayName = displayName; + mPlayerId = playerId; + mIsFriend = false; + if (mAvatarUrl != avatarUrl) + { + mImage = null; + setAvatarUrl(avatarUrl); + } + + mImageLoading = false; + } + + #region IUserProfile implementation + + /// + /// Gets the user's display name. + /// + /// The name of the user. + public string userName + { + get { return mDisplayName; } + } + + /// + /// Gets the user's unique player ID. + /// + /// The player ID. + public string id + { + get { return mPlayerId; } + } + + /// + /// Gets the user's game-specific identifier. In this implementation, it is the same as the player ID. + /// + public string gameId + { + get { return mPlayerId; } + } + + /// + /// Gets a value indicating whether this user is a friend of the local user. + /// + /// true if this user is a friend; otherwise, false. + public bool isFriend + { + get { return mIsFriend; } + } + + /// + /// Gets the user's current state. In this implementation, it always returns 'Online'. + /// + public UserState state + { + get { return UserState.Online; } + } + + /// + /// Gets the user's avatar image as a . + /// The image is loaded asynchronously. Returns null until the image has been loaded. + /// + /// The user's avatar image. + public Texture2D image + { + get + { + if (!mImageLoading && mImage == null && !string.IsNullOrEmpty(AvatarURL)) + { + OurUtils.Logger.d("Starting to load image: " + AvatarURL); + mImageLoading = true; + PlayGamesHelperObject.RunCoroutine(LoadImage()); + } + + return mImage; + } + } + + #endregion + + /// + /// Gets the URL of the user's avatar. + /// + public string AvatarURL + { + get { return mAvatarUrl; } + } + + /// + /// An enumerator that asynchronously loads the user's avatar image from the . + /// + /// An to be used with a coroutine. + internal IEnumerator LoadImage() + { + // The URL can be null if the user does not have an avatar configured. + if (!string.IsNullOrEmpty(AvatarURL)) + { +#if UNITY_2017_2_OR_NEWER + UnityWebRequest www = UnityWebRequestTexture.GetTexture(AvatarURL); + www.SendWebRequest(); +#else + WWW www = new WWW(AvatarURL); +#endif + while (!www.isDone) + { + yield return null; + } + + if (www.error == null) + { +#if UNITY_2017_2_OR_NEWER + this.mImage = DownloadHandlerTexture.GetContent(www); +#else + this.mImage = www.texture; +#endif + } + else + { + mImage = Texture2D.blackTexture; + OurUtils.Logger.e("Error downloading image: " + www.error); + } + + mImageLoading = false; + } + else + { + OurUtils.Logger.e("No URL found."); + mImage = Texture2D.blackTexture; + mImageLoading = false; + } + } + + /// + /// Determines whether the specified is equal to the current . + /// Equality is based on the player ID. + /// + /// The to compare with the current . + /// true if the specified object is equal to the current object; otherwise, false. + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + PlayGamesUserProfile other = obj as PlayGamesUserProfile; + if (other == null) + { + return false; + } + + return StringComparer.Ordinal.Equals(mPlayerId, other.mPlayerId); + } + + /// + /// Serves as a hash function for a object. + /// + /// A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a hash table. + public override int GetHashCode() + { + return typeof(PlayGamesUserProfile).GetHashCode() ^ mPlayerId.GetHashCode(); + } + + /// + /// Returns a that represents the current . + /// + /// A string representation of the object. + public override string ToString() + { + return string.Format("[Player: '{0}' (id {1})]", mDisplayName, mPlayerId); + } + + /// + /// Sets the avatar URL, ensuring it uses HTTPS. + /// + /// The avatar URL to set. + private void setAvatarUrl(string avatarUrl) + { + mAvatarUrl = avatarUrl; + if (!string.IsNullOrEmpty(mAvatarUrl) && !mAvatarUrl.StartsWith("https") && mAvatarUrl.StartsWith("http")) + { + mAvatarUrl = mAvatarUrl.Insert(4, "s"); + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs.meta new file mode 100644 index 0000000..70b194e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/ISocialPlatform/PlayGamesUserProfile.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ab1b90315f37e498a849765260dd436c +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils.meta new file mode 100644 index 0000000..01304aa --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: dc34e4ac2f7e6420da72898e7b511098 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs new file mode 100644 index 0000000..af8b8c3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs @@ -0,0 +1,92 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.OurUtils +{ + using System; + using UnityEngine; + + public class Logger + { + private static bool debugLogEnabled = false; + + public static bool DebugLogEnabled + { + get { return debugLogEnabled; } + + set { debugLogEnabled = value; } + } + + private static bool warningLogEnabled = true; + + public static bool WarningLogEnabled + { + get { return warningLogEnabled; } + + set { warningLogEnabled = value; } + } + + public static void d(string msg) + { + if (debugLogEnabled) + { + PlayGamesHelperObject.RunOnGameThread(() => + Debug.Log(ToLogMessage(string.Empty, "DEBUG", msg))); + } + } + + public static void w(string msg) + { + if (warningLogEnabled) + { + PlayGamesHelperObject.RunOnGameThread(() => + Debug.LogWarning(ToLogMessage("!!!", "WARNING", msg))); + } + } + + public static void e(string msg) + { + if (warningLogEnabled) + { + PlayGamesHelperObject.RunOnGameThread(() => + Debug.LogWarning(ToLogMessage("***", "ERROR", msg))); + } + } + + public static string describe(byte[] b) + { + return b == null ? "(null)" : "byte[" + b.Length + "]"; + } + + private static string ToLogMessage(string prefix, string logType, string msg) + { + string timeString = null; + try + { + timeString = DateTime.Now.ToString("MM/dd/yy H:mm:ss zzz"); + } + catch (Exception) + { + PlayGamesHelperObject.RunOnGameThread(() => + Debug.LogWarning("*** [Play Games Plugin " + PluginVersion.VersionString + "] ERROR: Failed to format DateTime.Now")); + timeString = string.Empty; + } + + return string.Format("{0} [Play Games Plugin " + PluginVersion.VersionString+ "] {1} {2}: {3}", + prefix, timeString, logType, msg); + } + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs.meta new file mode 100644 index 0000000..05bbca7 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Logger.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: cde7cfd197b4a47edac2efe305e22e78 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs new file mode 100644 index 0000000..8af6ea8 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs @@ -0,0 +1,100 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.OurUtils +{ + using System; + + public static class Misc + { + public static bool BuffersAreIdentical(byte[] a, byte[] b) + { + if (a == b) + { + // not only identical but the very same! + return true; + } + + if (a == null || b == null) + { + // one of them is null, the other one isn't + return false; + } + + if (a.Length != b.Length) + { + return false; + } + + for (int i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) + { + return false; + } + } + + return true; + } + + public static byte[] GetSubsetBytes(byte[] array, int offset, int length) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (offset < 0 || offset >= array.Length) + { + throw new ArgumentOutOfRangeException("offset"); + } + + if (length < 0 || (array.Length - offset) < length) + { + throw new ArgumentOutOfRangeException("length"); + } + + if (offset == 0 && length == array.Length) + { + return array; + } + + byte[] piece = new byte[length]; + Array.Copy(array, offset, piece, 0, length); + return piece; + } + + public static T CheckNotNull(T value) + { + if (value == null) + { + throw new ArgumentNullException(); + } + + return value; + } + + public static T CheckNotNull(T value, string paramName) + { + if (value == null) + { + throw new ArgumentNullException(paramName); + } + + return value; + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs.meta new file mode 100644 index 0000000..b4bca20 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/Misc.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ee52269f55933442fa5ea52e688ebec2 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs new file mode 100644 index 0000000..3b09327 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs @@ -0,0 +1,104 @@ +#if UNITY_ANDROID + +namespace GooglePlayGames.OurUtils +{ + using BasicApi.Nearby; + using System; + using UnityEngine; + + public class NearbyHelperObject : MonoBehaviour + { + // our (singleton) instance + private static NearbyHelperObject instance = null; + + // timers to keep track of discovery and advertising + private static double mAdvertisingRemaining = 0; + private static double mDiscoveryRemaining = 0; + + // nearby client to stop discovery and to stop advertising + private static INearbyConnectionClient mClient = null; + + public static void CreateObject(INearbyConnectionClient client) + { + if (instance != null) + { + return; + } + + mClient = client; + if (Application.isPlaying) + { + // add an invisible game object to the scene + GameObject obj = new GameObject("PlayGames_NearbyHelper"); + DontDestroyOnLoad(obj); + instance = obj.AddComponent(); + } + else + { + instance = new NearbyHelperObject(); + } + } + + private static double ToSeconds(TimeSpan? span) + { + if (!span.HasValue) + { + return 0; + } + + if (span.Value.TotalSeconds < 0) + { + return 0; + } + + return span.Value.TotalSeconds; + } + + public static void StartAdvertisingTimer(TimeSpan? span) + { + mAdvertisingRemaining = ToSeconds(span); + } + + public static void StartDiscoveryTimer(TimeSpan? span) + { + mDiscoveryRemaining = ToSeconds(span); + } + + public void Awake() + { + DontDestroyOnLoad(gameObject); + } + + public void OnDisable() + { + if (instance == this) + { + instance = null; + } + } + + public void Update() + { + // check if currently advertising + if (mAdvertisingRemaining > 0) + { + mAdvertisingRemaining -= Time.deltaTime; + if (mAdvertisingRemaining < 0) + { + mClient.StopAdvertising(); + } + } + + // check if currently discovering + if (mDiscoveryRemaining > 0) + { + mDiscoveryRemaining -= Time.deltaTime; + if (mDiscoveryRemaining < 0) + { + mClient.StopDiscovery(mClient.GetServiceId()); + } + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs.meta new file mode 100644 index 0000000..2573b0d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/NearbyHelperObject.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b66cca4a5a1f4a5092a280c452185308 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs new file mode 100644 index 0000000..43ce29e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs @@ -0,0 +1,42 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID +namespace GooglePlayGames.OurUtils +{ + using UnityEngine; + using System; + + public static class PlatformUtils + { + /// + /// Check if the Google Play Games platform is supported at runtime. + /// + /// If the platform is supported. + public static bool Supported + { + get + { +#if UNITY_EDITOR + return false; +#else + return true; +#endif + } + } + } +} +#endif //UNITY_ANDROID \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs.meta new file mode 100644 index 0000000..3b2ccfd --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlatformUtils.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 053811e778f3d4e3e98065f5db5bd005 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs new file mode 100644 index 0000000..6c8551c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs @@ -0,0 +1,222 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames.OurUtils +{ + using System; + using System.Collections; + using UnityEngine; + using System.Collections.Generic; + + public class PlayGamesHelperObject : MonoBehaviour + { + // our (singleton) instance + private static PlayGamesHelperObject instance = null; + + // are we a dummy instance (used in the editor?) + private static bool sIsDummy = false; + + // queue of actions to run on the game thread + private static List sQueue = new List(); + + // member variable used to copy actions from the sQueue and + // execute them on the game thread. It is a member variable + // to help minimize memory allocations. + List localQueue = new List(); + + // flag that alerts us that we should check the queue + // (we do this just so we don't have to lock() the queue every + // frame to check if it's empty or not). + private volatile static bool sQueueEmpty = true; + + // callback for application pause and focus events + private static List> sPauseCallbackList = + new List>(); + + private static List> sFocusCallbackList = + new List>(); + + // Call this once from the game thread + public static void CreateObject() + { + if (instance != null) + { + return; + } + + if (Application.isPlaying) + { + // add an invisible game object to the scene + GameObject obj = new GameObject("PlayGames_QueueRunner"); + DontDestroyOnLoad(obj); + instance = obj.AddComponent(); + } + else + { + instance = new PlayGamesHelperObject(); + sIsDummy = true; + } + } + + public void Awake() + { + DontDestroyOnLoad(gameObject); + } + + public void OnDisable() + { + if (instance == this) + { + instance = null; + } + } + + public static void RunCoroutine(IEnumerator action) + { + if (instance != null) + { + RunOnGameThread(() => instance.StartCoroutine(action)); + } + } + + public static void RunOnGameThread(System.Action action) + { + if (action == null) + { + throw new ArgumentNullException("action"); + } + + if (sIsDummy) + { + return; + } + + lock (sQueue) + { + sQueue.Add(action); + sQueueEmpty = false; + } + } + + public void Update() + { + if (sIsDummy || sQueueEmpty) + { + return; + } + + // first copy the shared queue into a local queue + localQueue.Clear(); + lock (sQueue) + { + // transfer the whole queue to our local queue + localQueue.AddRange(sQueue); + sQueue.Clear(); + sQueueEmpty = true; + } + + // execute queued actions (from local queue) + // use a loop to avoid extra memory allocations using the + // forEach + for (int i = 0; i < localQueue.Count; i++) + { + localQueue[i].Invoke(); + } + } + + public void OnApplicationFocus(bool focused) + { + foreach (Action cb in sFocusCallbackList) + { + try + { + cb(focused); + } + catch (Exception e) + { + Logger.e("Exception in OnApplicationFocus:" + + e.Message + "\n" + e.StackTrace); + } + } + } + + public void OnApplicationPause(bool paused) + { + foreach (Action cb in sPauseCallbackList) + { + try + { + cb(paused); + } + catch (Exception e) + { + Logger.e("Exception in OnApplicationPause:" + + e.Message + "\n" + e.StackTrace); + } + } + } + + /// + /// Adds a callback that is called when the Unity method OnApplicationFocus + /// is called. + /// + /// + /// Callback. + public static void AddFocusCallback(Action callback) + { + if (!sFocusCallbackList.Contains(callback)) + { + sFocusCallbackList.Add(callback); + } + } + + /// + /// Removes the callback from the list to call when handling OnApplicationFocus + /// is called. + /// + /// true, if focus callback was removed, false otherwise. + /// Callback. + public static bool RemoveFocusCallback(Action callback) + { + return sFocusCallbackList.Remove(callback); + } + + /// + /// Adds a callback that is called when the Unity method OnApplicationPause + /// is called. + /// + /// + /// Callback. + public static void AddPauseCallback(Action callback) + { + if (!sPauseCallbackList.Contains(callback)) + { + sPauseCallbackList.Add(callback); + } + } + + /// + /// Removes the callback from the list to call when handling OnApplicationPause + /// is called. + /// + /// true, if focus callback was removed, false otherwise. + /// Callback. + public static bool RemovePauseCallback(Action callback) + { + return sPauseCallbackList.Remove(callback); + } + } +} \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs.meta new file mode 100644 index 0000000..b4be3e6 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/OurUtils/PlayGamesHelperObject.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 7dd6f93ee6cb54945aea72a87542f720 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms.meta new file mode 100644 index 0000000..dd9d70b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 58fac82a81a11415b99606841f6040a6 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android.meta new file mode 100644 index 0000000..a8981c4 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5c9032ae026414e1bbe872da53708edd +folderAsset: yes +timeCreated: 1441206393 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs new file mode 100644 index 0000000..c25d19a --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs @@ -0,0 +1,1128 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID +#pragma warning disable 0642 // Possible mistaken empty statement + +namespace GooglePlayGames.Android +{ + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.Events; + using GooglePlayGames.BasicApi.SavedGame; + using GooglePlayGames.OurUtils; + using System; + using System.Collections.Generic; + using System.Linq; + using UnityEngine; + using UnityEngine.SocialPlatforms; + + public class AndroidClient : IPlayGamesClient + { + private enum AuthState + { + Unauthenticated, + Authenticated + } + + private readonly object GameServicesLock = new object(); + private readonly object AuthStateLock = new object(); + private readonly static String PlayGamesSdkClassName = + "com.google.android.gms.games.PlayGamesSdk"; + + private volatile ISavedGameClient mSavedGameClient; + private volatile IEventsClient mEventsClient; + private volatile Player mUser = null; + private volatile AuthState mAuthState = AuthState.Unauthenticated; + private IUserProfile[] mFriends = new IUserProfile[0]; + private LoadFriendsStatus mLastLoadFriendsStatus = LoadFriendsStatus.Unknown; + + AndroidJavaClass mGamesClass = new AndroidJavaClass("com.google.android.gms.games.PlayGames"); + private static string TasksClassName = "com.google.android.gms.tasks.Tasks"; + + private AndroidJavaObject mFriendsResolutionException = null; + + private readonly int mLeaderboardMaxResults = 25; // can be from 1 to 25 + + private readonly int mFriendsMaxResults = 200; // the maximum load friends page size + + internal AndroidClient() + { + PlayGamesHelperObject.CreateObject(); + InitializeSdk(); + } + + private static void InitializeSdk() { + using (var playGamesSdkClass = new AndroidJavaClass(PlayGamesSdkClassName)) { + playGamesSdkClass.CallStatic("initialize", AndroidHelperFragment.GetActivity()); + } + } + + public void Authenticate(Action callback) + { + Authenticate( /* isAutoSignIn= */ true, callback); + } + + public void ManuallyAuthenticate(Action callback) + { + Authenticate( /* isAutoSignIn= */ false, callback); + } + + private void Authenticate(bool isAutoSignIn, Action callback) + { + callback = AsOnGameThreadCallback(callback); + lock (AuthStateLock) + { + // If the user is already authenticated, just fire the callback, we don't need + // any additional work. + if (mAuthState == AuthState.Authenticated) + { + OurUtils.Logger.d("Already authenticated."); + InvokeCallbackOnGameThread(callback, SignInStatus.Success); + return; + } + } + + string methodName = isAutoSignIn ? "isAuthenticated" : "signIn"; + + OurUtils.Logger.d("Starting Auth using the method " + methodName); + using (var client = getGamesSignInClient()) + using ( + var task = client.Call(methodName)) + { + AndroidTaskUtils.AddOnSuccessListener(task, authenticationResult => + { + bool isAuthenticated = authenticationResult.Call("isAuthenticated"); + SignInOnResult(isAuthenticated, callback); + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("Authentication failed - " + exception.Call("toString")); + callback(SignInStatus.InternalError); + }); + } + } + + private void SignInOnResult(bool isAuthenticated, Action callback) + { + if (isAuthenticated) + { + using (var signInTasks = new AndroidJavaObject("java.util.ArrayList")) + { + AndroidJavaObject taskGetPlayer = + getPlayersClient().Call("getCurrentPlayer"); + signInTasks.Call("add", taskGetPlayer); + + using (var tasks = new AndroidJavaClass(TasksClassName)) + using (var allTask = tasks.CallStatic("whenAll", signInTasks)) + { + AndroidTaskUtils.AddOnCompleteListener( + allTask, + completeTask => + { + if (completeTask.Call("isSuccessful")) + { + using (var resultObject = taskGetPlayer.Call("getResult")) + { + mUser = AndroidJavaConverter.ToPlayer(resultObject); + } + + lock (GameServicesLock) + { + mSavedGameClient = new AndroidSavedGameClient(this); + mEventsClient = new AndroidEventsClient(); + } + + mAuthState = AuthState.Authenticated; + InvokeCallbackOnGameThread(callback, SignInStatus.Success); + OurUtils.Logger.d("Authentication succeeded"); + LoadAchievements(ignore => { }); + } + else + { + if (completeTask.Call("isCanceled")) + { + InvokeCallbackOnGameThread(callback, SignInStatus.Canceled); + return; + } + + using (var exception = completeTask.Call("getException")) + { + OurUtils.Logger.e( + "Authentication failed - " + exception.Call("toString")); + InvokeCallbackOnGameThread(callback, SignInStatus.InternalError); + } + } + } + ); + } + } + } + else + { + lock (AuthStateLock) + { + OurUtils.Logger.e("Returning an error code."); + InvokeCallbackOnGameThread(callback, SignInStatus.Canceled); + } + } + } + + public void RequestServerSideAccess(bool forceRefreshToken, Action callback) + { + callback = AsOnGameThreadCallback(callback); + + if (!GameInfo.WebClientIdInitialized()) + { + throw new InvalidOperationException("Requesting server side access requires web " + + "client id to be configured."); + } + + using (var client = getGamesSignInClient()) + using (var task = client.Call("requestServerSideAccess", + GameInfo.WebClientId, forceRefreshToken)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + authCode => callback(authCode) + ); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("Requesting server side access task failed - " + + exception.Call("toString")); + callback(null); + }); + } + } + + public void RequestServerSideAccess(bool forceRefreshToken, List scopes, Action callback) + { + callback = AsOnGameThreadCallback(callback); + + if (!GameInfo.WebClientIdInitialized()) + { + throw new InvalidOperationException("Requesting server-side access requires a web client ID to be configured."); + } + + if (scopes == null) + { + throw new ArgumentException("At least one scope must be provided."); + } + + var javaScopesList = new AndroidJavaObject("java.util.ArrayList"); + + foreach (var scope in scopes) + { + javaScopesList.Call("add", getJavaScopeEnum(scope)); + } + + using (var client = getGamesSignInClient()) + using (var task = client.Call( + "requestServerSideAccess", + GameInfo.WebClientId, + forceRefreshToken, + javaScopesList)) + { + AndroidTaskUtils.AddOnSuccessListener(task, result => callback(ToAuthResponse(result))); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("Requesting server-side access with scopes task failed - " + exception.Call("toString")); + callback(new AuthResponse(null, new List())); // Return empty response on failure + }); + } + } + + private AuthResponse ToAuthResponse(AndroidJavaObject result) + { + string authCode = result.Call("getAuthCode"); + var grantedScopesObject = result.Call("getGrantedScopes"); + + var grantedScopesList = new List(); + if (grantedScopesObject != null) + { + int size = grantedScopesObject.Call("size"); + for (int i = 0; i < size; i++) + { + var javaScopeEnum = grantedScopesObject.Call("get", i); + string javaScopeName = javaScopeEnum.Call("name"); + if (Enum.TryParse(javaScopeName, out AuthScope grantedScope)) + { + grantedScopesList.Add(grantedScope); + } + else + { + OurUtils.Logger.w($"Unrecognized scope {javaScopeName} returned from java side."); + } + } + } + AuthResponse authResponse = new AuthResponse(authCode, grantedScopesList); + return authResponse; + } + + private AndroidJavaObject getJavaScopeEnum(AuthScope scope) + { + String AuthScopeClassName = "com.google.android.gms.games.gamessignin.AuthScope"; + var javaAuthScopeClass = new AndroidJavaClass(AuthScopeClassName); + return javaAuthScopeClass.CallStatic("valueOf", scope.GetValue()); + } + + + public void RequestRecallAccessToken(Action callback) + { + callback = AsOnGameThreadCallback(callback); + using (var client = getRecallClient()) + using (var task = client.Call("requestRecallAccess")) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + recallAccess => { + var sessionId = recallAccess.Call("getSessionId"); + callback(new RecallAccess(sessionId)); + } + ); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("Requesting Recall access task failed - " + + exception.Call("toString")); + callback(null); + }); + } + } + + private static Action AsOnGameThreadCallback(Action callback) + { + if (callback == null) + { + return delegate { }; + } + + return result => InvokeCallbackOnGameThread(callback, result); + } + + private static void InvokeCallbackOnGameThread(Action callback) + { + if (callback == null) + { + return; + } + + PlayGamesHelperObject.RunOnGameThread(() => { callback(); }); + } + + private static void InvokeCallbackOnGameThread(Action callback, T data) + { + if (callback == null) + { + return; + } + + PlayGamesHelperObject.RunOnGameThread(() => { callback(data); }); + } + + + private static Action AsOnGameThreadCallback( + Action toInvokeOnGameThread) + { + return (result1, result2) => + { + if (toInvokeOnGameThread == null) + { + return; + } + + PlayGamesHelperObject.RunOnGameThread(() => toInvokeOnGameThread(result1, result2)); + }; + } + + private static void InvokeCallbackOnGameThread(Action callback, T1 t1, T2 t2) + { + if (callback == null) + { + return; + } + + PlayGamesHelperObject.RunOnGameThread(() => { callback(t1, t2); }); + } + + public bool IsAuthenticated() + { + lock (AuthStateLock) + { + return mAuthState == AuthState.Authenticated; + } + } + + public void LoadFriends(Action callback) + { + LoadAllFriends(mFriendsMaxResults, /* forceReload= */ false, /* loadMore= */ false, callback); + } + + private void LoadAllFriends(int pageSize, bool forceReload, bool loadMore, + Action callback) + { + LoadFriendsPaginated(pageSize, loadMore, forceReload, result => + { + mLastLoadFriendsStatus = result; + switch (result) + { + case LoadFriendsStatus.Completed: + InvokeCallbackOnGameThread(callback, true); + break; + case LoadFriendsStatus.LoadMore: + // There are more friends to load. + LoadAllFriends(pageSize, /* forceReload= */ false, /* loadMore= */ true, callback); + break; + case LoadFriendsStatus.ResolutionRequired: + case LoadFriendsStatus.InternalError: + case LoadFriendsStatus.NotAuthorized: + InvokeCallbackOnGameThread(callback, false); + break; + default: + GooglePlayGames.OurUtils.Logger.d("There was an error when loading friends." + result); + InvokeCallbackOnGameThread(callback, false); + break; + } + }); + } + + public void LoadFriends(int pageSize, bool forceReload, + Action callback) + { + LoadFriendsPaginated(pageSize, /* isLoadMore= */ false, /* forceReload= */ forceReload, + callback); + } + + public void LoadMoreFriends(int pageSize, Action callback) + { + LoadFriendsPaginated(pageSize, /* isLoadMore= */ true, /* forceReload= */ false, + callback); + } + + private void LoadFriendsPaginated(int pageSize, bool isLoadMore, bool forceReload, + Action callback) + { + mFriendsResolutionException = null; + using (var playersClient = getPlayersClient()) + using (var task = isLoadMore + ? playersClient.Call("loadMoreFriends", pageSize) + : playersClient.Call("loadFriends", pageSize, + forceReload)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, annotatedData => + { + using (var playersBuffer = annotatedData.Call("get")) + { + AndroidJavaObject metadata = playersBuffer.Call("getMetadata"); + var areMoreFriendsToLoad = metadata != null && + metadata.Call("getString", + "next_page_token") != null; + mFriends = AndroidJavaConverter.playersBufferToArray(playersBuffer); + mLastLoadFriendsStatus = areMoreFriendsToLoad + ? LoadFriendsStatus.LoadMore + : LoadFriendsStatus.Completed; + InvokeCallbackOnGameThread(callback, mLastLoadFriendsStatus); + } + }); + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + AndroidHelperFragment.IsResolutionRequired(exception, resolutionRequired => + { + if (resolutionRequired) + { + mFriendsResolutionException = + exception.Call("getResolution"); + mLastLoadFriendsStatus = LoadFriendsStatus.ResolutionRequired; + mFriends = new IUserProfile[0]; + InvokeCallbackOnGameThread(callback, LoadFriendsStatus.ResolutionRequired); + } + else + { + mFriendsResolutionException = null; + + if (IsApiException(exception)) + { + var statusCode = exception.Call("getStatusCode"); + if (statusCode == /* GamesClientStatusCodes.NETWORK_ERROR_NO_DATA */ 26504) + { + mLastLoadFriendsStatus = LoadFriendsStatus.NetworkError; + InvokeCallbackOnGameThread(callback, LoadFriendsStatus.NetworkError); + return; + } + } + + mLastLoadFriendsStatus = LoadFriendsStatus.InternalError; + OurUtils.Logger.e("LoadFriends failed: " + + exception.Call("toString")); + InvokeCallbackOnGameThread(callback, LoadFriendsStatus.InternalError); + } + }); + return; + }); + } + } + + private static bool IsApiException(AndroidJavaObject exception) { + var exceptionClassName = exception.Call("getClass") + .Call("getName"); + return exceptionClassName == "com.google.android.gms.common.api.ApiException"; + } + + public LoadFriendsStatus GetLastLoadFriendsStatus() + { + return mLastLoadFriendsStatus; + } + + public void AskForLoadFriendsResolution(Action callback) + { + if (mFriendsResolutionException == null) + { + GooglePlayGames.OurUtils.Logger.d("The developer asked for access to the friends " + + "list but there is no intent to trigger the UI. This may be because the user " + + "has granted access already or the game has not called loadFriends() before."); + using (var playersClient = getPlayersClient()) + using ( + var task = playersClient.Call("loadFriends", /* pageSize= */ 1, + /* forceReload= */ false)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, annotatedData => { InvokeCallbackOnGameThread(callback, UIStatus.Valid); }); + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + AndroidHelperFragment.IsResolutionRequired(exception, resolutionRequired => + { + if (resolutionRequired) + { + mFriendsResolutionException = + exception.Call("getResolution"); + AndroidHelperFragment.AskForLoadFriendsResolution( + mFriendsResolutionException, AsOnGameThreadCallback(callback)); + return; + } + + if (IsApiException(exception)) + { + var statusCode = exception.Call("getStatusCode"); + if (statusCode == + /* GamesClientStatusCodes.NETWORK_ERROR_NO_DATA */ 26504) + { + InvokeCallbackOnGameThread(callback, UIStatus.NetworkError); + return; + } + } + + OurUtils.Logger.e("LoadFriends failed: " + + exception.Call("toString")); + InvokeCallbackOnGameThread(callback, UIStatus.InternalError); + }); + }); + } + } + else + { + AndroidHelperFragment.AskForLoadFriendsResolution(mFriendsResolutionException, + AsOnGameThreadCallback(callback)); + } + } + + public void ShowCompareProfileWithAlternativeNameHintsUI(string playerId, + string otherPlayerInGameName, + string currentPlayerInGameName, + Action callback) + { + AndroidHelperFragment.ShowCompareProfileWithAlternativeNameHintsUI( + playerId, otherPlayerInGameName, currentPlayerInGameName, + AsOnGameThreadCallback(callback)); + } + + public void GetFriendsListVisibility(bool forceReload, + Action callback) + { + using (var playersClient = getPlayersClient()) + using ( + var task = playersClient.Call("getCurrentPlayer", forceReload)) + { + AndroidTaskUtils.AddOnSuccessListener(task, annotatedData => + { + AndroidJavaObject currentPlayerInfo = + annotatedData.Call("get").Call( + "getCurrentPlayerInfo"); + int playerListVisibility = + currentPlayerInfo.Call("getFriendsListVisibilityStatus"); + InvokeCallbackOnGameThread(callback, + AndroidJavaConverter.ToFriendsListVisibilityStatus(playerListVisibility)); + }); + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + InvokeCallbackOnGameThread(callback, FriendsListVisibilityStatus.NetworkError); + return; + }); + } + } + + public IUserProfile[] GetFriends() + { + return mFriends; + } + + public string GetUserId() + { + if (mUser == null) + { + return null; + } + + return mUser.id; + } + + public string GetUserDisplayName() + { + if (mUser == null) + { + return null; + } + + return mUser.userName; + } + + public string GetUserImageUrl() + { + if (mUser == null) + { + return null; + } + + return mUser.AvatarURL; + } + + public void GetPlayerStats(Action callback) + { + using (var playerStatsClient = getPlayerStatsClient()) + using (var task = playerStatsClient.Call("loadPlayerStats", /* forceReload= */ false)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var playerStatsJava = annotatedData.Call("get")) + { + int numberOfPurchases = playerStatsJava.Call("getNumberOfPurchases"); + float avgSessionLength = playerStatsJava.Call("getAverageSessionLength"); + int daysSinceLastPlayed = playerStatsJava.Call("getDaysSinceLastPlayed"); + int numberOfSessions = playerStatsJava.Call("getNumberOfSessions"); + float sessionPercentile = playerStatsJava.Call("getSessionPercentile"); + float spendPercentile = playerStatsJava.Call("getSpendPercentile"); + float spendProbability = playerStatsJava.Call("getSpendProbability"); + float churnProbability = playerStatsJava.Call("getChurnProbability"); + float highSpenderProbability = playerStatsJava.Call("getHighSpenderProbability"); + float totalSpendNext28Days = playerStatsJava.Call("getTotalSpendNext28Days"); + + PlayerStats result = new PlayerStats( + numberOfPurchases, + avgSessionLength, + daysSinceLastPlayed, + numberOfSessions, + sessionPercentile, + spendPercentile, + spendProbability, + churnProbability, + highSpenderProbability, + totalSpendNext28Days); + + InvokeCallbackOnGameThread(callback, CommonStatusCodes.Success, result); + } + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("GetPlayerStats failed: " + exception.Call("toString")); + var statusCode = IsAuthenticated() + ? CommonStatusCodes.InternalError + : CommonStatusCodes.SignInRequired; + InvokeCallbackOnGameThread(callback, statusCode, new PlayerStats()); + }); + } + } + + public void LoadUsers(string[] userIds, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, new IUserProfile[0]); + return; + } + + using (var playersClient = getPlayersClient()) + { + object countLock = new object(); + int count = userIds.Length; + int resultCount = 0; + IUserProfile[] users = new IUserProfile[count]; + for (int i = 0; i < count; ++i) + { + using (var task = playersClient.Call("loadPlayer", userIds[i])) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var player = annotatedData.Call("get")) + { + string playerId = player.Call("getPlayerId"); + for (int j = 0; j < count; ++j) + { + if (playerId == userIds[j]) + { + users[j] = AndroidJavaConverter.ToPlayer(player); + break; + } + } + + lock (countLock) + { + ++resultCount; + if (resultCount == count) + { + InvokeCallbackOnGameThread(callback, users); + } + } + } + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("LoadUsers failed for index " + i + + " with: " + exception.Call("toString")); + lock (countLock) + { + ++resultCount; + if (resultCount == count) + { + InvokeCallbackOnGameThread(callback, users); + } + } + }); + } + } + } + } + + public void LoadAchievements(Action callback) + { + using (var achievementsClient = getAchievementsClient()) + using (var task = achievementsClient.Call("load", /* forceReload= */ false)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var achievementBuffer = annotatedData.Call("get")) + { + int count = achievementBuffer.Call("getCount"); + Achievement[] result = new Achievement[count]; + for (int i = 0; i < count; ++i) + { + Achievement achievement = new Achievement(); + using (var javaAchievement = achievementBuffer.Call("get", i)) + { + achievement.Id = javaAchievement.Call("getAchievementId"); + achievement.Description = javaAchievement.Call("getDescription"); + achievement.Name = javaAchievement.Call("getName"); + achievement.Points = javaAchievement.Call("getXpValue"); + + long timestamp = javaAchievement.Call("getLastUpdatedTimestamp"); + achievement.LastModifiedTime = AndroidJavaConverter.ToDateTime(timestamp); + + achievement.RevealedImageUrl = javaAchievement.Call("getRevealedImageUrl"); + achievement.UnlockedImageUrl = javaAchievement.Call("getUnlockedImageUrl"); + achievement.IsIncremental = + javaAchievement.Call("getType") == 1 /* TYPE_INCREMENTAL */; + if (achievement.IsIncremental) + { + achievement.CurrentSteps = javaAchievement.Call("getCurrentSteps"); + achievement.TotalSteps = javaAchievement.Call("getTotalSteps"); + } + + int state = javaAchievement.Call("getState"); + achievement.IsUnlocked = state == 0 /* STATE_UNLOCKED */; + achievement.IsRevealed = state == 1 /* STATE_REVEALED */; + } + + result[i] = achievement; + } + + achievementBuffer.Call("release"); + InvokeCallbackOnGameThread(callback, result); + } + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("LoadAchievements failed: " + exception.Call("toString")); + InvokeCallbackOnGameThread(callback, new Achievement[0]); + }); + } + } + + public void UnlockAchievement(string achId, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + return; + } + + using (var achievementsClient = getAchievementsClient()) + { + achievementsClient.Call("unlock", achId); + InvokeCallbackOnGameThread(callback, true); + } + } + + public void RevealAchievement(string achId, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + return; + } + + using (var achievementsClient = getAchievementsClient()) + { + achievementsClient.Call("reveal", achId); + InvokeCallbackOnGameThread(callback, true); + } + } + + public void IncrementAchievement(string achId, int steps, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + return; + } + + using (var achievementsClient = getAchievementsClient()) + { + achievementsClient.Call("increment", achId, steps); + InvokeCallbackOnGameThread(callback, true); + } + } + + public void SetStepsAtLeast(string achId, int steps, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + return; + } + + using (var achievementsClient = getAchievementsClient()) + { + achievementsClient.Call("setSteps", achId, steps); + InvokeCallbackOnGameThread(callback, true); + } + } + + public void ShowAchievementsUI(Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, UIStatus.NotAuthorized); + return; + } + + AndroidHelperFragment.ShowAchievementsUI(AsOnGameThreadCallback(callback)); + } + + public int LeaderboardMaxResults() + { + return mLeaderboardMaxResults; + } + + public void ShowLeaderboardUI(string leaderboardId, LeaderboardTimeSpan span, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, UIStatus.NotAuthorized); + return; + } + + if (leaderboardId == null) + { + AndroidHelperFragment.ShowAllLeaderboardsUI(AsOnGameThreadCallback(callback)); + } + else + { + AndroidHelperFragment.ShowLeaderboardUI(leaderboardId, span, + AsOnGameThreadCallback(callback)); + } + } + + public void LoadScores(string leaderboardId, LeaderboardStart start, + int rowCount, LeaderboardCollection collection, + LeaderboardTimeSpan timeSpan, + Action callback) + { + using (var client = getLeaderboardsClient()) + { + string loadScoresMethod = + start == LeaderboardStart.TopScores ? "loadTopScores" : "loadPlayerCenteredScores"; + using (var task = client.Call( + loadScoresMethod, + leaderboardId, + AndroidJavaConverter.ToLeaderboardVariantTimeSpan(timeSpan), + AndroidJavaConverter.ToLeaderboardVariantCollection(collection), + rowCount)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var leaderboardScores = annotatedData.Call("get")) + { + InvokeCallbackOnGameThread(callback, CreateLeaderboardScoreData( + leaderboardId, + collection, + timeSpan, + annotatedData.Call("isStale") + ? ResponseStatus.SuccessWithStale + : ResponseStatus.Success, + leaderboardScores)); + leaderboardScores.Call("release"); + } + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + AndroidHelperFragment.IsResolutionRequired( + exception, resolutionRequired => + { + if (resolutionRequired) + { + mFriendsResolutionException = exception.Call( + "getResolution"); + InvokeCallbackOnGameThread( + callback, new LeaderboardScoreData(leaderboardId, + ResponseStatus.ResolutionRequired)); + } + else + { + mFriendsResolutionException = null; + } + }); + OurUtils.Logger.e("LoadScores failed: " + exception.Call("toString")); + InvokeCallbackOnGameThread( + callback, new LeaderboardScoreData(leaderboardId, + ResponseStatus.InternalError)); + }); + } + } + } + + public void LoadMoreScores(ScorePageToken token, int rowCount, + Action callback) + { + using (var client = getLeaderboardsClient()) + using (var task = client.Call("loadMoreScores", + token.InternalObject, rowCount, AndroidJavaConverter.ToPageDirection(token.Direction))) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var leaderboardScores = annotatedData.Call("get")) + { + InvokeCallbackOnGameThread(callback, CreateLeaderboardScoreData( + token.LeaderboardId, + token.Collection, + token.TimeSpan, + annotatedData.Call("isStale") + ? ResponseStatus.SuccessWithStale + : ResponseStatus.Success, + leaderboardScores)); + leaderboardScores.Call("release"); + } + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + AndroidHelperFragment.IsResolutionRequired(exception, resolutionRequired => + { + if (resolutionRequired) + { + mFriendsResolutionException = + exception.Call("getResolution"); + InvokeCallbackOnGameThread( + callback, new LeaderboardScoreData(token.LeaderboardId, + ResponseStatus.ResolutionRequired)); + } + else + { + mFriendsResolutionException = null; + } + }); + OurUtils.Logger.e("LoadMoreScores failed: " + exception.Call("toString")); + InvokeCallbackOnGameThread( + callback, new LeaderboardScoreData(token.LeaderboardId, + ResponseStatus.InternalError)); + }); + } + } + + private LeaderboardScoreData CreateLeaderboardScoreData( + string leaderboardId, + LeaderboardCollection collection, + LeaderboardTimeSpan timespan, + ResponseStatus status, + AndroidJavaObject leaderboardScoresJava) + { + LeaderboardScoreData leaderboardScoreData = new LeaderboardScoreData(leaderboardId, status); + var scoresBuffer = leaderboardScoresJava.Call("getScores"); + int count = scoresBuffer.Call("getCount"); + for (int i = 0; i < count; ++i) + { + using (var leaderboardScore = scoresBuffer.Call("get", i)) + { + long timestamp = leaderboardScore.Call("getTimestampMillis"); + System.DateTime date = AndroidJavaConverter.ToDateTime(timestamp); + + ulong rank = (ulong) leaderboardScore.Call("getRank"); + string scoreHolderId = ""; + using (var scoreHolder = leaderboardScore.Call("getScoreHolder")) + { + scoreHolderId = scoreHolder.Call("getPlayerId"); + } + + ulong score = (ulong) leaderboardScore.Call("getRawScore"); + string metadata = leaderboardScore.Call("getScoreTag"); + + leaderboardScoreData.AddScore(new PlayGamesScore(date, leaderboardId, + rank, scoreHolderId, score, metadata)); + } + } + + leaderboardScoreData.NextPageToken = new ScorePageToken(scoresBuffer, leaderboardId, collection, + timespan, ScorePageDirection.Forward); + leaderboardScoreData.PrevPageToken = new ScorePageToken(scoresBuffer, leaderboardId, collection, + timespan, ScorePageDirection.Backward); + + using (var leaderboard = leaderboardScoresJava.Call("getLeaderboard")) + using (var variants = leaderboard.Call("getVariants")) + using (var variant = variants.Call("get", 0)) + { + leaderboardScoreData.Title = leaderboard.Call("getDisplayName"); + if (variant.Call("hasPlayerInfo")) + { + System.DateTime date = AndroidJavaConverter.ToDateTime(0); + ulong rank = (ulong) variant.Call("getPlayerRank"); + ulong score = (ulong) variant.Call("getRawPlayerScore"); + string metadata = variant.Call("getPlayerScoreTag"); + leaderboardScoreData.PlayerScore = new PlayGamesScore(date, leaderboardId, + rank, mUser.id, score, metadata); + } + + leaderboardScoreData.ApproximateCount = (ulong) variant.Call("getNumScores"); + } + + return leaderboardScoreData; + } + + public void SubmitScore(string leaderboardId, long score, Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + } + + using (var client = getLeaderboardsClient()) + { + client.Call("submitScore", leaderboardId, score); + InvokeCallbackOnGameThread(callback, true); + } + } + + public void SubmitScore(string leaderboardId, long score, string metadata, + Action callback) + { + if (!IsAuthenticated()) + { + InvokeCallbackOnGameThread(callback, false); + } + + using (var client = getLeaderboardsClient()) + { + client.Call("submitScore", leaderboardId, score, metadata); + InvokeCallbackOnGameThread(callback, true); + } + } + + public ISavedGameClient GetSavedGameClient() + { + lock (GameServicesLock) + { + return mSavedGameClient; + } + } + + public IEventsClient GetEventsClient() + { + lock (GameServicesLock) + { + return mEventsClient; + } + } + + private AndroidJavaObject getAchievementsClient() + { + return mGamesClass.CallStatic("getAchievementsClient", + AndroidHelperFragment.GetActivity()); + } + + private AndroidJavaObject getPlayersClient() + { + return mGamesClass.CallStatic("getPlayersClient", AndroidHelperFragment.GetActivity()); + } + + private AndroidJavaObject getLeaderboardsClient() + { + return mGamesClass.CallStatic("getLeaderboardsClient", + AndroidHelperFragment.GetActivity()); + } + + private AndroidJavaObject getPlayerStatsClient() + { + return mGamesClass.CallStatic("getPlayerStatsClient", + AndroidHelperFragment.GetActivity()); + } + + private AndroidJavaObject getGamesSignInClient() + { + return mGamesClass.CallStatic("getGamesSignInClient", + AndroidHelperFragment.GetActivity()); + } + + private AndroidJavaObject getRecallClient() + { + return mGamesClass.CallStatic("getRecallClient", + AndroidHelperFragment.GetActivity()); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs.meta new file mode 100644 index 0000000..bc55a0a --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 32e99ad5da22248a28a9ca51282b121f +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs new file mode 100644 index 0000000..799205d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs @@ -0,0 +1,136 @@ +#if UNITY_ANDROID +namespace GooglePlayGames.Android +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.Events; + using GooglePlayGames.OurUtils; + using UnityEngine; + internal class AndroidEventsClient : IEventsClient + { + private volatile AndroidJavaObject mEventsClient; + + public AndroidEventsClient() + { + using (var gamesClass = new AndroidJavaClass("com.google.android.gms.games.PlayGames")) + { + mEventsClient = gamesClass.CallStatic("getEventsClient", + AndroidHelperFragment.GetActivity()); + } + } + + public void FetchAllEvents(DataSource source, Action> callback) + { + callback = ToOnGameThread(callback); + using (var task = + mEventsClient.Call("load", source == DataSource.ReadNetworkOnly ? true : false)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var buffer = annotatedData.Call("get")) + { + int count = buffer.Call("getCount"); + List result = new List(); + for (int i = 0; i < count; ++i) + { + using (var eventJava = buffer.Call("get", i)) + { + result.Add(CreateEvent(eventJava)); + } + } + buffer.Call("release"); + callback.Invoke( + annotatedData.Call("isStale") + ? ResponseStatus.SuccessWithStale + : ResponseStatus.Success, + result + ); + } + }); + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + Debug.Log("FetchAllEvents failed"); + callback.Invoke(ResponseStatus.InternalError, null); + }); + } + } + + public void FetchEvent(DataSource source, string eventId, Action callback) + { + callback = ToOnGameThread(callback); + string[] ids = new string[1]; + ids[0] = eventId; + using (var task = mEventsClient.Call("loadByIds", + source == DataSource.ReadNetworkOnly ? true : false, ids)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var buffer = annotatedData.Call("get")) + { + int count = buffer.Call("getCount"); + if (count > 0) + { + using (var eventJava = buffer.Call("get", 0)) + { + callback.Invoke( + annotatedData.Call("isStale") + ? ResponseStatus.SuccessWithStale + : ResponseStatus.Success, + CreateEvent(eventJava) + ); + } + } + else + { + callback.Invoke( + annotatedData.Call("isStale") + ? ResponseStatus.SuccessWithStale + : ResponseStatus.Success, + null + ); + } + buffer.Call("release"); + } + }); + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + Debug.Log("FetchEvent failed"); + callback.Invoke(ResponseStatus.InternalError, null); + }); + } + } + + public void IncrementEvent(string eventId, uint stepsToIncrement) + { + mEventsClient.Call("increment", eventId, (int) stepsToIncrement); + } + + private static Action ToOnGameThread(Action toConvert) + { + return (val1, val2) => PlayGamesHelperObject.RunOnGameThread(() => toConvert(val1, val2)); + } + + private static BasicApi.Events.Event CreateEvent(AndroidJavaObject eventJava) + { + string id = eventJava.Call("getEventId"); + string name = eventJava.Call("getName"); + string description = eventJava.Call("getDescription"); + string imageUrl = eventJava.Call("getIconImageUrl"); + ulong currentCount = (ulong) eventJava.Call("getValue"); + EventVisibility visibility = eventJava.Call("isVisible") + ? EventVisibility.Revealed + : EventVisibility.Hidden; + return new BasicApi.Events.Event(id, name, description, imageUrl, currentCount, visibility); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs.meta new file mode 100644 index 0000000..96e8524 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidEventsClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 311e1761661a341bebebd422a144b5e8 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs new file mode 100644 index 0000000..4b770e1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs @@ -0,0 +1,223 @@ +// +// Copyright (C) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID +namespace GooglePlayGames.Android +{ + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.SavedGame; + using OurUtils; + using UnityEngine; + using System; + using System.Collections.Generic; + + internal class AndroidHelperFragment + { + private const string HelperFragmentClass = "com.google.games.bridge.HelperFragment"; + + public static AndroidJavaObject GetActivity() + { + using (var jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + return jc.GetStatic("currentActivity"); + } + } + + public static AndroidJavaObject GetDefaultPopupView() + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using (var activity = AndroidHelperFragment.GetActivity()) + { + return helperFragment.CallStatic("getDecorView", activity); + } + } + + public static void ShowAchievementsUI(Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using (var task = + helperFragment.CallStatic("showAchievementUi", AndroidHelperFragment.GetActivity())) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + uiCode => + { + OurUtils.Logger.d("ShowAchievementsUI result " + uiCode); + cb.Invoke((UIStatus) uiCode); + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + OurUtils.Logger.e("ShowAchievementsUI failed with exception"); + cb.Invoke(UIStatus.InternalError); + }); + } + } + + public static void ShowCaptureOverlayUI() + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + { + helperFragment.CallStatic("showCaptureOverlayUi", AndroidHelperFragment.GetActivity()); + } + } + + public static void ShowAllLeaderboardsUI(Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using (var task = + helperFragment.CallStatic("showAllLeaderboardsUi", + AndroidHelperFragment.GetActivity())) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + uiCode => + { + OurUtils.Logger.d("ShowAllLeaderboardsUI result " + uiCode); + cb.Invoke((UIStatus) uiCode); + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + OurUtils.Logger.e("ShowAllLeaderboardsUI failed with exception"); + cb.Invoke(UIStatus.InternalError); + }); + } + } + + public static void ShowLeaderboardUI(string leaderboardId, LeaderboardTimeSpan timeSpan, Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using (var task = helperFragment.CallStatic("showLeaderboardUi", + AndroidHelperFragment.GetActivity(), leaderboardId, + AndroidJavaConverter.ToLeaderboardVariantTimeSpan(timeSpan))) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + uiCode => + { + OurUtils.Logger.d("ShowLeaderboardUI result " + uiCode); + cb.Invoke((UIStatus) uiCode); + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + OurUtils.Logger.e("ShowLeaderboardUI failed with exception"); + cb.Invoke(UIStatus.InternalError); + }); + } + } + + public static void ShowCompareProfileWithAlternativeNameHintsUI( + string playerId, string otherPlayerInGameName, string currentPlayerInGameName, + Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using ( + var task = helperFragment.CallStatic( + "showCompareProfileWithAlternativeNameHintsUI", + AndroidHelperFragment.GetActivity(), playerId, otherPlayerInGameName, + currentPlayerInGameName)) + { + AndroidTaskUtils.AddOnSuccessListener(task, uiCode => + { + OurUtils.Logger.d("ShowCompareProfileWithAlternativeNameHintsUI result " + uiCode); + cb.Invoke((UIStatus) uiCode); + }); + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("ShowCompareProfileWithAlternativeNameHintsUI failed with exception"); + cb.Invoke(UIStatus.InternalError); + }); + } + } + + public static void IsResolutionRequired( + AndroidJavaObject friendsSharingConsentException, Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + { + var isResolutionRequired = helperFragment.CallStatic( + "isResolutionRequired", friendsSharingConsentException); + cb.Invoke(isResolutionRequired); + } + } + + public static void AskForLoadFriendsResolution( + AndroidJavaObject friendsSharingConsentException, Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using ( + var task = helperFragment.CallStatic( + "askForLoadFriendsResolution", AndroidHelperFragment.GetActivity(), + friendsSharingConsentException)) + { + AndroidTaskUtils.AddOnSuccessListener(task, uiCode => + { + OurUtils.Logger.d("AskForLoadFriendsResolution result " + uiCode); + cb.Invoke((UIStatus) uiCode); + }); + + AndroidTaskUtils.AddOnFailureListener(task, exception => + { + OurUtils.Logger.e("AskForLoadFriendsResolution failed with exception"); + cb.Invoke(UIStatus.InternalError); + }); + } + } + + public static void ShowSelectSnapshotUI(bool showCreateSaveUI, bool showDeleteSaveUI, + int maxDisplayedSavedGames, string uiTitle, Action cb) + { + using (var helperFragment = new AndroidJavaClass(HelperFragmentClass)) + using (var task = helperFragment.CallStatic("showSelectSnapshotUi", + AndroidHelperFragment.GetActivity(), uiTitle, showCreateSaveUI, showDeleteSaveUI, + maxDisplayedSavedGames)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + result => + { + SelectUIStatus status = (SelectUIStatus) result.Get("status"); + OurUtils.Logger.d("ShowSelectSnapshotUI result " + status); + + AndroidJavaObject javaMetadata = result.Get("metadata"); + AndroidSnapshotMetadata metadata = + javaMetadata == null + ? null + : new AndroidSnapshotMetadata(javaMetadata, /* contents= */null); + + cb.Invoke(status, metadata); + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + OurUtils.Logger.e("ShowSelectSnapshotUI failed with exception"); + cb.Invoke(SelectUIStatus.InternalError, null); + }); + } + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs.meta new file mode 100644 index 0000000..74a1dc1 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidHelperFragment.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 6eb353a6ffa554bacb374cfaf0cc45e7 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs new file mode 100644 index 0000000..f4bd067 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs @@ -0,0 +1,165 @@ +// +// Copyright (C) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID +namespace GooglePlayGames.Android +{ + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.SavedGame; + using OurUtils; + using UnityEngine; + using UnityEngine.SocialPlatforms; + using System; + using System.Collections.Generic; + + internal class AndroidJavaConverter + { + internal static System.DateTime ToDateTime(long milliseconds) + { + System.DateTime result = new System.DateTime(1970, 1, 1, 0, 0, 0, 0); + return result.AddMilliseconds(milliseconds); + } + + // Convert to LeaderboardVariant.java#TimeSpan + internal static int ToLeaderboardVariantTimeSpan(LeaderboardTimeSpan span) + { + switch (span) + { + case LeaderboardTimeSpan.Daily: + return 0 /* TIME_SPAN_DAILY */; + case LeaderboardTimeSpan.Weekly: + return 1 /* TIME_SPAN_WEEKLY */; + case LeaderboardTimeSpan.AllTime: + default: + return 2 /* TIME_SPAN_ALL_TIME */; + } + } + + // Convert to LeaderboardVariant.java#Collection + internal static int ToLeaderboardVariantCollection(LeaderboardCollection collection) + { + switch (collection) + { + case LeaderboardCollection.Social: + return 3 /* COLLECTION_FRIENDS */; + case LeaderboardCollection.Public: + default: + return 0 /* COLLECTION_PUBLIC */; + } + } + + // Convert to PageDirection.java#Direction + internal static int ToPageDirection(ScorePageDirection direction) + { + switch (direction) + { + case ScorePageDirection.Forward: + return 0 /* NEXT */; + case ScorePageDirection.Backward: + return 1 /* PREV */; + default: + return -1 /* NONE */; + } + } + + internal static Player ToPlayer(AndroidJavaObject player) + { + if (player == null) + { + return null; + } + + string displayName = player.Call("getDisplayName"); + string playerId = player.Call("getPlayerId"); + string avatarUrl = player.Call("getIconImageUrl"); + return new Player(displayName, playerId, avatarUrl); + } + + internal static PlayerProfile ToPlayerProfile(AndroidJavaObject player) { + if (player == null) { + return null; + } + + string displayName = player.Call("getDisplayName"); + string playerId = player.Call("getPlayerId"); + string avatarUrl = player.Call("getIconImageUrl"); + bool isFriend = + player.Call("getRelationshipInfo").Call("getFriendStatus") == + 4 /* PlayerFriendStatus.Friend*/; + return new PlayerProfile(displayName, playerId, avatarUrl, isFriend); + } + + internal static List ToStringList(AndroidJavaObject stringList) + { + if (stringList == null) + { + return new List(); + } + + int size = stringList.Call("size"); + List converted = new List(size); + + for (int i = 0; i < size; i++) + { + converted.Add(stringList.Call("get", i)); + } + + return converted; + } + + // from C#: List to Java: ArrayList + internal static AndroidJavaObject ToJavaStringList(List list) + { + AndroidJavaObject converted = new AndroidJavaObject("java.util.ArrayList"); + for (int i = 0; i < list.Count; i++) + { + converted.Call("add", list[i]); + } + + return converted; + } + + internal static FriendsListVisibilityStatus ToFriendsListVisibilityStatus(int playerListVisibility) { + switch (playerListVisibility) + { + case /* FriendsListVisibilityStatus.UNKNOWN */ 0: + return FriendsListVisibilityStatus.Unknown; + case /* FriendsListVisibilityStatus.VISIBLE */ 1: + return FriendsListVisibilityStatus.Visible; + case /* FriendsListVisibilityStatus.REQUEST_REQUIRED */ 2: + return FriendsListVisibilityStatus.ResolutionRequired; + case /* FriendsListVisibilityStatus.FEATURE_UNAVAILABLE */ 3: + return FriendsListVisibilityStatus.Unavailable; + default: + return FriendsListVisibilityStatus.Unknown; + } + } + + internal static IUserProfile[] playersBufferToArray(AndroidJavaObject playersBuffer) { + int count = playersBuffer.Call("getCount"); + IUserProfile[] users = new IUserProfile[count]; + for (int i = 0; i < count; ++i) { + using (var player = playersBuffer.Call("get", i)) { + users[i] = AndroidJavaConverter.ToPlayerProfile(player); + } + } + + playersBuffer.Call("release"); + return users; + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs.meta new file mode 100644 index 0000000..6c15f8b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidJavaConverter.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: d498c17d61b504b4f984a99b4542d02f +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs new file mode 100644 index 0000000..654488c --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs @@ -0,0 +1,443 @@ +#if UNITY_ANDROID +#pragma warning disable 0642 // Possible mistaken empty statement + +namespace GooglePlayGames.Android +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.Nearby; + using GooglePlayGames.OurUtils; + using UnityEngine; + + public class AndroidNearbyConnectionClient : INearbyConnectionClient + { + private volatile AndroidJavaObject mClient; + private readonly static long NearbyClientId = 0L; + private readonly static int ApplicationInfoFlags = 0x00000080; + private readonly static string ServiceId = ReadServiceId(); + protected IMessageListener mAdvertisingMessageListener; + + public AndroidNearbyConnectionClient() + { + PlayGamesHelperObject.CreateObject(); + NearbyHelperObject.CreateObject(this); + using (var nearbyClass = new AndroidJavaClass("com.google.android.gms.nearby.Nearby")) + { + mClient = nearbyClass.CallStatic("getConnectionsClient", + AndroidHelperFragment.GetActivity()); + } + } + + public int MaxUnreliableMessagePayloadLength() + { + return NearbyConnectionConfiguration.MaxUnreliableMessagePayloadLength; + } + + public int MaxReliableMessagePayloadLength() + { + return NearbyConnectionConfiguration.MaxReliableMessagePayloadLength; + } + + public void SendReliable(List recipientEndpointIds, byte[] payload) + { + InternalSend(recipientEndpointIds, payload); + } + + public void SendUnreliable(List recipientEndpointIds, byte[] payload) + { + InternalSend(recipientEndpointIds, payload); + } + + private void InternalSend(List recipientEndpointIds, byte[] payload) + { + Misc.CheckNotNull(recipientEndpointIds); + Misc.CheckNotNull(payload); + + using (var payloadClass = new AndroidJavaClass("com.google.android.gms.nearby.connection.Payload")) + using (var payloadObject = payloadClass.CallStatic("fromBytes", payload)) + using (var task = mClient.Call("sendPayload", + AndroidJavaConverter.ToJavaStringList(recipientEndpointIds), + payloadObject)) + ; + } + + public void StartAdvertising(string name, List appIdentifiers, + TimeSpan? advertisingDuration, Action resultCallback, + Action connectionRequestCallback) + { + Misc.CheckNotNull(resultCallback, "resultCallback"); + Misc.CheckNotNull(connectionRequestCallback, "connectionRequestCallback"); + + if (advertisingDuration.HasValue && advertisingDuration.Value.Ticks < 0) + { + throw new InvalidOperationException("advertisingDuration must be positive"); + } + + connectionRequestCallback = ToOnGameThread(connectionRequestCallback); + resultCallback = ToOnGameThread(resultCallback); + + AdvertisingConnectionLifecycleCallbackProxy callbackProxy = + new AdvertisingConnectionLifecycleCallbackProxy(resultCallback, connectionRequestCallback, this); + using (var connectionLifecycleCallback = + new AndroidJavaObject("com.google.games.bridge.ConnectionLifecycleCallbackProxy", callbackProxy)) + using (var advertisingOptions = CreateAdvertisingOptions()) + using (var task = mClient.Call("startAdvertising", name, GetServiceId(), + connectionLifecycleCallback, advertisingOptions)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + v => NearbyHelperObject.StartAdvertisingTimer(advertisingDuration) + ); + } + } + + private AndroidJavaObject CreateAdvertisingOptions() + { + using (var strategy = new AndroidJavaClass("com.google.android.gms.nearby.connection.Strategy") + .GetStatic("P2P_CLUSTER")) + using (var builder = + new AndroidJavaObject("com.google.android.gms.nearby.connection.AdvertisingOptions$Builder")) + using (builder.Call("setStrategy", strategy)) + { + return builder.Call("build"); + } + } + + private class AdvertisingConnectionLifecycleCallbackProxy : AndroidJavaProxy + { + private Action mResultCallback; + private Action mConnectionRequestCallback; + private AndroidNearbyConnectionClient mClient; + private string mLocalEndpointName; + + public AdvertisingConnectionLifecycleCallbackProxy(Action resultCallback, + Action connectionRequestCallback, AndroidNearbyConnectionClient client) : base( + "com/google/games/bridge/ConnectionLifecycleCallbackProxy$Callback") + { + mResultCallback = resultCallback; + mConnectionRequestCallback = connectionRequestCallback; + mClient = client; + } + + public void onConnectionInitiated(string endpointId, AndroidJavaObject connectionInfo) + { + mLocalEndpointName = connectionInfo.Call("getEndpointName"); + mConnectionRequestCallback(new ConnectionRequest(endpointId, mLocalEndpointName, mClient.GetServiceId(), + new byte[0])); + } + + public void onConnectionResult(string endpointId, AndroidJavaObject connectionResolution) + { + int statusCode; + using (var status = connectionResolution.Call("getStatus")) + { + statusCode = status.Call("getStatusCode"); + } + + if (statusCode == 0) // STATUS_OK + { + mResultCallback(new AdvertisingResult(ResponseStatus.Success, mLocalEndpointName)); + return; + } + + if (statusCode == 8001) // STATUS_ALREADY_ADVERTISING + { + mResultCallback(new AdvertisingResult(ResponseStatus.NotAuthorized, mLocalEndpointName)); + return; + } + + mResultCallback(new AdvertisingResult(ResponseStatus.InternalError, mLocalEndpointName)); + } + + public void onDisconnected(string endpointId) + { + if (mClient.mAdvertisingMessageListener != null) + { + mClient.mAdvertisingMessageListener.OnRemoteEndpointDisconnected(endpointId); + } + } + } + + public void StopAdvertising() + { + mClient.Call("stopAdvertising"); + mAdvertisingMessageListener = null; + } + + public void SendConnectionRequest(string name, string remoteEndpointId, byte[] payload, + Action responseCallback, IMessageListener listener) + { + Misc.CheckNotNull(listener, "listener"); + var listenerOnGameThread = new OnGameThreadMessageListener(listener); + DiscoveringConnectionLifecycleCallback cb = + new DiscoveringConnectionLifecycleCallback(responseCallback, listenerOnGameThread, mClient); + using (var connectionLifecycleCallback = + new AndroidJavaObject("com.google.games.bridge.ConnectionLifecycleCallbackProxy", cb)) + using (mClient.Call("requestConnection", name, remoteEndpointId, + connectionLifecycleCallback)) + ; + } + + public void AcceptConnectionRequest(string remoteEndpointId, byte[] payload, IMessageListener listener) + { + Misc.CheckNotNull(listener, "listener"); + mAdvertisingMessageListener = new OnGameThreadMessageListener(listener); + + using (var payloadCallback = new AndroidJavaObject("com.google.games.bridge.PayloadCallbackProxy", + new PayloadCallback(listener))) + using (mClient.Call("acceptConnection", remoteEndpointId, payloadCallback)) + ; + } + + private class PayloadCallback : AndroidJavaProxy + { + private IMessageListener mListener; + + public PayloadCallback(IMessageListener listener) : base( + "com/google/games/bridge/PayloadCallbackProxy$Callback") + { + mListener = listener; + } + + public void onPayloadReceived(String endpointId, AndroidJavaObject payload) + { + if (payload.Call("getType") != 1) // 1 for BYTES + { + return; + } + + mListener.OnMessageReceived(endpointId, payload.Call("asBytes"), /* isReliableMessage */ true); + } + } + + public void StartDiscovery(string serviceId, TimeSpan? advertisingDuration, + IDiscoveryListener listener) + { + Misc.CheckNotNull(serviceId, "serviceId"); + Misc.CheckNotNull(listener, "listener"); + + var listenerOnGameThread = new OnGameThreadDiscoveryListener(listener); + + if (advertisingDuration.HasValue && advertisingDuration.Value.Ticks < 0) + { + throw new InvalidOperationException("advertisingDuration must be positive"); + } + + using (var endpointDiscoveryCallback = new AndroidJavaObject( + "com.google.games.bridge.EndpointDiscoveryCallbackProxy", + new EndpointDiscoveryCallback(listenerOnGameThread))) + using (var discoveryOptions = CreateDiscoveryOptions()) + using (var task = mClient.Call("startDiscovery", serviceId, endpointDiscoveryCallback, + discoveryOptions)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + v => NearbyHelperObject.StartDiscoveryTimer(advertisingDuration) + ); + } + } + + private class DiscoveringConnectionLifecycleCallback : AndroidJavaProxy + { + private Action mResponseCallback; + private IMessageListener mListener; + private AndroidJavaObject mClient; + + public DiscoveringConnectionLifecycleCallback(Action responseCallback, + IMessageListener listener, AndroidJavaObject client) : base( + "com/google/games/bridge/ConnectionLifecycleCallbackProxy$Callback") + { + mResponseCallback = responseCallback; + mListener = listener; + mClient = client; + } + + public void onConnectionInitiated(string endpointId, AndroidJavaObject connectionInfo) + { + using (var payloadCallback = new AndroidJavaObject("com.google.games.bridge.PayloadCallbackProxy", + new PayloadCallback(mListener))) + using (mClient.Call("acceptConnection", endpointId, payloadCallback)) + ; + } + + public void onConnectionResult(string endpointId, AndroidJavaObject connectionResolution) + { + int statusCode; + using (var status = connectionResolution.Call("getStatus")) + { + statusCode = status.Call("getStatusCode"); + } + + if (statusCode == 0) // STATUS_OK + { + mResponseCallback(ConnectionResponse.Accepted(NearbyClientId, endpointId, new byte[0])); + return; + } + + if (statusCode == 8002) // STATUS_ALREADY_DISCOVERING + { + mResponseCallback(ConnectionResponse.AlreadyConnected(NearbyClientId, endpointId)); + return; + } + + mResponseCallback(ConnectionResponse.Rejected(NearbyClientId, endpointId)); + } + + public void onDisconnected(string endpointId) + { + mListener.OnRemoteEndpointDisconnected(endpointId); + } + } + + private AndroidJavaObject CreateDiscoveryOptions() + { + using (var strategy = + new AndroidJavaClass("com.google.android.gms.nearby.connection.Strategy").GetStatic( + "P2P_CLUSTER")) + using (var builder = + new AndroidJavaObject("com.google.android.gms.nearby.connection.DiscoveryOptions$Builder")) + using (builder.Call("setStrategy", strategy)) + { + return builder.Call("build"); + } + } + + private class EndpointDiscoveryCallback : AndroidJavaProxy + { + private IDiscoveryListener mListener; + + public EndpointDiscoveryCallback(IDiscoveryListener listener) : base( + "com/google/games/bridge/EndpointDiscoveryCallbackProxy$Callback") + { + mListener = listener; + } + + public void onEndpointFound(string endpointId, AndroidJavaObject endpointInfo) + { + mListener.OnEndpointFound(CreateEndPointDetails(endpointId, endpointInfo)); + } + + public void onEndpointLost(string endpointId) + { + mListener.OnEndpointLost(endpointId); + } + + private EndpointDetails CreateEndPointDetails(string endpointId, AndroidJavaObject endpointInfo) + { + return new EndpointDetails( + endpointId, + endpointInfo.Call("getEndpointName"), + endpointInfo.Call("getServiceId") + ); + } + } + + private class OnGameThreadMessageListener : IMessageListener + { + private readonly IMessageListener mListener; + + public OnGameThreadMessageListener(IMessageListener listener) + { + mListener = Misc.CheckNotNull(listener); + } + + public void OnMessageReceived(string remoteEndpointId, byte[] data, + bool isReliableMessage) + { + PlayGamesHelperObject.RunOnGameThread(() => mListener.OnMessageReceived( + remoteEndpointId, data, isReliableMessage)); + } + + public void OnRemoteEndpointDisconnected(string remoteEndpointId) + { + PlayGamesHelperObject.RunOnGameThread( + () => mListener.OnRemoteEndpointDisconnected(remoteEndpointId)); + } + } + + private class OnGameThreadDiscoveryListener : IDiscoveryListener + { + private readonly IDiscoveryListener mListener; + + public OnGameThreadDiscoveryListener(IDiscoveryListener listener) + { + mListener = listener; + } + + public void OnEndpointFound(EndpointDetails discoveredEndpoint) + { + PlayGamesHelperObject.RunOnGameThread(() => mListener.OnEndpointFound(discoveredEndpoint)); + } + + public void OnEndpointLost(string lostEndpointId) + { + PlayGamesHelperObject.RunOnGameThread(() => mListener.OnEndpointLost(lostEndpointId)); + } + } + + public void StopDiscovery(string serviceId) + { + mClient.Call("stopDiscovery"); + } + + public void RejectConnectionRequest(string requestingEndpointId) + { + Misc.CheckNotNull(requestingEndpointId, "requestingEndpointId"); + using (var task = mClient.Call("rejectConnection", requestingEndpointId)) ; + } + + public void DisconnectFromEndpoint(string remoteEndpointId) + { + mClient.Call("disconnectFromEndpoint", remoteEndpointId); + } + + public void StopAllConnections() + { + mClient.Call("stopAllEndpoints"); + mAdvertisingMessageListener = null; + } + + public string GetAppBundleId() + { + using (var activity = AndroidHelperFragment.GetActivity()) + { + return activity.Call("getPackageName"); + } + } + + public string GetServiceId() + { + return ServiceId; + } + + private static string ReadServiceId() + { + using (var activity = AndroidHelperFragment.GetActivity()) + { + string packageName = activity.Call("getPackageName"); + using (var pm = activity.Call("getPackageManager")) + using (var appInfo = + pm.Call("getApplicationInfo", packageName, ApplicationInfoFlags)) + using (var bundle = appInfo.Get("metaData")) + { + string sysId = bundle.Call("getString", + "com.google.android.gms.nearby.connection.SERVICE_ID"); + OurUtils.Logger.d("SystemId from Manifest: " + sysId); + return sysId; + } + } + } + + private static Action ToOnGameThread(Action toConvert) + { + return (val) => PlayGamesHelperObject.RunOnGameThread(() => toConvert(val)); + } + + private static Action ToOnGameThread(Action toConvert) + { + return (val1, val2) => PlayGamesHelperObject.RunOnGameThread(() => toConvert(val1, val2)); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs.meta new file mode 100644 index 0000000..f0d961e --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidNearbyConnectionClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: d69ac0a61e8943ff82b14f7469f0fe97 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs new file mode 100644 index 0000000..0a0616f --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs @@ -0,0 +1,526 @@ +#if UNITY_ANDROID +#pragma warning disable 0642 // Possible mistaken empty statement + +namespace GooglePlayGames.Android +{ + using System; + using System.Collections.Generic; + using System.Text.RegularExpressions; + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.SavedGame; + using GooglePlayGames.OurUtils; + using UnityEngine; + + internal class AndroidSavedGameClient : ISavedGameClient + { + // Regex for a valid filename. Valid file names are between 1 and 100 characters (inclusive) + // and only include URL-safe characters: a-z, A-Z, 0-9, or the symbols "-", ".", "_", or "~". + // This regex is guarded by \A and \Z which guarantee that the entire string matches this + // regex. If these were omitted, then illegal strings containing legal subsequences would be + // allowed (since the regex would match those subsequences). + private static readonly Regex ValidFilenameRegex = new Regex(@"\A[a-zA-Z0-9-._~]{1,100}\Z"); + + private volatile AndroidJavaObject mSnapshotsClient; + private volatile AndroidClient mAndroidClient; + + public AndroidSavedGameClient(AndroidClient androidClient) + { + mAndroidClient = androidClient; + using (var gamesClass = new AndroidJavaClass("com.google.android.gms.games.PlayGames")) + { + mSnapshotsClient = gamesClass.CallStatic("getSnapshotsClient", + AndroidHelperFragment.GetActivity()); + } + } + + public void OpenWithAutomaticConflictResolution(string filename, DataSource source, + ConflictResolutionStrategy resolutionStrategy, + Action completedCallback) + { + Misc.CheckNotNull(filename); + Misc.CheckNotNull(completedCallback); + bool prefetchDataOnConflict = false; + ConflictCallback conflictCallback = null; + completedCallback = ToOnGameThread(completedCallback); + + if (conflictCallback == null) + { + conflictCallback = (resolver, original, originalData, unmerged, unmergedData) => + { + switch (resolutionStrategy) + { + case ConflictResolutionStrategy.UseOriginal: + resolver.ChooseMetadata(original); + return; + case ConflictResolutionStrategy.UseUnmerged: + resolver.ChooseMetadata(unmerged); + return; + case ConflictResolutionStrategy.UseLongestPlaytime: + if (original.TotalTimePlayed >= unmerged.TotalTimePlayed) + { + resolver.ChooseMetadata(original); + } + else + { + resolver.ChooseMetadata(unmerged); + } + + return; + default: + OurUtils.Logger.e("Unhandled strategy " + resolutionStrategy); + completedCallback(SavedGameRequestStatus.InternalError, null); + return; + } + }; + } + + conflictCallback = ToOnGameThread(conflictCallback); + + if (!IsValidFilename(filename)) + { + OurUtils.Logger.e("Received invalid filename: " + filename); + completedCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + InternalOpen(filename, source, resolutionStrategy, prefetchDataOnConflict, conflictCallback, + completedCallback); + } + + public void OpenWithManualConflictResolution(string filename, DataSource source, bool prefetchDataOnConflict, + ConflictCallback conflictCallback, Action completedCallback) + { + Misc.CheckNotNull(filename); + Misc.CheckNotNull(conflictCallback); + Misc.CheckNotNull(completedCallback); + + conflictCallback = ToOnGameThread(conflictCallback); + completedCallback = ToOnGameThread(completedCallback); + + if (!IsValidFilename(filename)) + { + OurUtils.Logger.e("Received invalid filename: " + filename); + completedCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + InternalOpen(filename, source, ConflictResolutionStrategy.UseManual, prefetchDataOnConflict, + conflictCallback, completedCallback); + } + + private void InternalOpen(string filename, DataSource source, ConflictResolutionStrategy resolutionStrategy, + bool prefetchDataOnConflict, ConflictCallback conflictCallback, + Action completedCallback) + { + int conflictPolicy; // SnapshotsClient.java#RetentionPolicy + switch (resolutionStrategy) + { + case ConflictResolutionStrategy.UseLastKnownGood: + conflictPolicy = 2 /* RESOLUTION_POLICY_LAST_KNOWN_GOOD */; + break; + case ConflictResolutionStrategy.UseMostRecentlySaved: + conflictPolicy = 3 /* RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED */; + break; + case ConflictResolutionStrategy.UseLongestPlaytime: + conflictPolicy = 1 /* RESOLUTION_POLICY_LONGEST_PLAYTIME*/; + break; + case ConflictResolutionStrategy.UseManual: + conflictPolicy = -1 /* RESOLUTION_POLICY_MANUAL */; + break; + default: + conflictPolicy = 3 /* RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED */; + break; + } + + using (var task = + mSnapshotsClient.Call("open", filename, /* createIfNotFound= */ true, + conflictPolicy)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + dataOrConflict => + { + if (dataOrConflict.Call("isConflict")) + { + var conflict = dataOrConflict.Call("getConflict"); + AndroidSnapshotMetadata original = + new AndroidSnapshotMetadata(conflict.Call("getSnapshot")); + AndroidSnapshotMetadata unmerged = + new AndroidSnapshotMetadata( + conflict.Call("getConflictingSnapshot")); + + // Instantiate the conflict resolver. Note that the retry callback closes over + // all the parameters we need to retry the open attempt. Once the conflict is + // resolved by invoking the appropriate resolution method on + // AndroidConflictResolver, the resolver will invoke this callback, which will + // result in this method being re-executed. This recursion will continue until + // all conflicts are resolved or an error occurs. + AndroidConflictResolver resolver = new AndroidConflictResolver( + this, + mSnapshotsClient, + conflict, + original, + unmerged, + completedCallback, + () => InternalOpen(filename, source, resolutionStrategy, + prefetchDataOnConflict, + conflictCallback, completedCallback)); + + var originalBytes = original.JavaContents.Call("readFully"); + var unmergedBytes = unmerged.JavaContents.Call("readFully"); + conflictCallback(resolver, original, originalBytes, unmerged, unmergedBytes); + } + else + { + using (var snapshot = dataOrConflict.Call("getData")) + { + AndroidJavaObject metadata = snapshot.Call("freeze"); + completedCallback(SavedGameRequestStatus.Success, + new AndroidSnapshotMetadata(metadata)); + } + } + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => { + OurUtils.Logger.d("InternalOpen has failed: " + exception.Call("toString")); + var status = mAndroidClient.IsAuthenticated() ? + SavedGameRequestStatus.InternalError : + SavedGameRequestStatus.AuthenticationError; + completedCallback(status, null); + } + ); + } + } + + public void ReadBinaryData(ISavedGameMetadata metadata, + Action completedCallback) + { + Misc.CheckNotNull(metadata); + Misc.CheckNotNull(completedCallback); + completedCallback = ToOnGameThread(completedCallback); + + AndroidSnapshotMetadata convertedMetadata = metadata as AndroidSnapshotMetadata; + + if (convertedMetadata == null) + { + OurUtils.Logger.e("Encountered metadata that was not generated by this ISavedGameClient"); + completedCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + if (!convertedMetadata.IsOpen) + { + OurUtils.Logger.e("This method requires an open ISavedGameMetadata."); + completedCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + byte[] data = convertedMetadata.JavaContents.Call("readFully"); + if (data == null) + { + completedCallback(SavedGameRequestStatus.BadInputError, null); + } + else + { + completedCallback(SavedGameRequestStatus.Success, data); + } + } + + public void ShowSelectSavedGameUI(string uiTitle, uint maxDisplayedSavedGames, bool showCreateSaveUI, + bool showDeleteSaveUI, Action callback) + { + Misc.CheckNotNull(uiTitle); + Misc.CheckNotNull(callback); + + callback = ToOnGameThread(callback); + + if (!(maxDisplayedSavedGames > 0)) + { + OurUtils.Logger.e("maxDisplayedSavedGames must be greater than 0"); + callback(SelectUIStatus.BadInputError, null); + return; + } + + AndroidHelperFragment.ShowSelectSnapshotUI( + showCreateSaveUI, showDeleteSaveUI, (int) maxDisplayedSavedGames, uiTitle, callback); + } + + public void CommitUpdate(ISavedGameMetadata metadata, SavedGameMetadataUpdate updateForMetadata, + byte[] updatedBinaryData, Action callback) + { + Misc.CheckNotNull(metadata); + Misc.CheckNotNull(updatedBinaryData); + Misc.CheckNotNull(callback); + + callback = ToOnGameThread(callback); + + AndroidSnapshotMetadata convertedMetadata = metadata as AndroidSnapshotMetadata; + + if (convertedMetadata == null) + { + OurUtils.Logger.e("Encountered metadata that was not generated by this ISavedGameClient"); + callback(SavedGameRequestStatus.BadInputError, null); + return; + } + + if (!convertedMetadata.IsOpen) + { + OurUtils.Logger.e("This method requires an open ISavedGameMetadata."); + callback(SavedGameRequestStatus.BadInputError, null); + return; + } + + if (!convertedMetadata.JavaContents.Call("writeBytes", updatedBinaryData)) + { + OurUtils.Logger.e("This method requires an open ISavedGameMetadata."); + callback(SavedGameRequestStatus.BadInputError, null); + } + + using (var convertedMetadataChange = AsMetadataChange(updateForMetadata)) + using (var task = mSnapshotsClient.Call("commitAndClose", convertedMetadata.JavaSnapshot, + convertedMetadataChange)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + /* disposeResult= */ false, + snapshotMetadata => + { + OurUtils.Logger.d("commitAndClose.succeed"); + callback(SavedGameRequestStatus.Success, + new AndroidSnapshotMetadata(snapshotMetadata, /* contents= */null)); + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => + { + OurUtils.Logger.e("commitAndClose.failed: " + exception.Call("toString")); + var status = mAndroidClient.IsAuthenticated() ? + SavedGameRequestStatus.InternalError : + SavedGameRequestStatus.AuthenticationError; + callback(status, null); + }); + } + } + + public void FetchAllSavedGames(DataSource source, + Action> callback) + { + Misc.CheckNotNull(callback); + + callback = ToOnGameThread(callback); + + using (var task = + mSnapshotsClient.Call("load", /* forecReload= */ + source == DataSource.ReadNetworkOnly)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + annotatedData => + { + using (var buffer = annotatedData.Call("get")) + { + int count = buffer.Call("getCount"); + List result = new List(); + for (int i = 0; i < count; ++i) + { + using (var metadata = buffer.Call("get", i)) + { + result.Add(new AndroidSnapshotMetadata( + metadata.Call("freeze"), /* contents= */null)); + } + } + + buffer.Call("release"); + callback(SavedGameRequestStatus.Success, result); + } + }); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => { + OurUtils.Logger.d("FetchAllSavedGames failed: " + exception.Call("toString")); + var status = mAndroidClient.IsAuthenticated() ? + SavedGameRequestStatus.InternalError : + SavedGameRequestStatus.AuthenticationError; + callback(status, new List()); + } + ); + } + } + + public void Delete(ISavedGameMetadata metadata) + { + AndroidSnapshotMetadata androidMetadata = metadata as AndroidSnapshotMetadata; + Misc.CheckNotNull(androidMetadata); + using (mSnapshotsClient.Call("delete", androidMetadata.JavaMetadata)) ; + } + + private ConflictCallback ToOnGameThread(ConflictCallback conflictCallback) + { + return (resolver, original, originalData, unmerged, unmergedData) => + { + OurUtils.Logger.d("Invoking conflict callback"); + PlayGamesHelperObject.RunOnGameThread(() => + conflictCallback(resolver, original, originalData, unmerged, unmergedData)); + }; + } + + /// + /// A helper class that encapsulates the state around resolving a file conflict. It holds all + /// the state that is necessary to invoke as well as a + /// callback that will re-attempt to open the file after the resolution concludes. + /// + private class AndroidConflictResolver : IConflictResolver + { + private readonly AndroidJavaObject mSnapshotsClient; + private readonly AndroidJavaObject mConflict; + private readonly AndroidSnapshotMetadata mOriginal; + private readonly AndroidSnapshotMetadata mUnmerged; + private readonly Action mCompleteCallback; + private readonly Action mRetryFileOpen; + + private readonly AndroidSavedGameClient mAndroidSavedGameClient; + + internal AndroidConflictResolver(AndroidSavedGameClient androidSavedGameClient, AndroidJavaObject snapshotClient, AndroidJavaObject conflict, + AndroidSnapshotMetadata original, AndroidSnapshotMetadata unmerged, + Action completeCallback, Action retryOpen) + { + this.mAndroidSavedGameClient = androidSavedGameClient; + this.mSnapshotsClient = Misc.CheckNotNull(snapshotClient); + this.mConflict = Misc.CheckNotNull(conflict); + this.mOriginal = Misc.CheckNotNull(original); + this.mUnmerged = Misc.CheckNotNull(unmerged); + this.mCompleteCallback = Misc.CheckNotNull(completeCallback); + this.mRetryFileOpen = Misc.CheckNotNull(retryOpen); + } + + public void ResolveConflict(ISavedGameMetadata chosenMetadata, SavedGameMetadataUpdate metadataUpdate, + byte[] updatedData) + { + AndroidSnapshotMetadata convertedMetadata = chosenMetadata as AndroidSnapshotMetadata; + + if (convertedMetadata != mOriginal && convertedMetadata != mUnmerged) + { + OurUtils.Logger.e("Caller attempted to choose a version of the metadata that was not part " + + "of the conflict"); + mCompleteCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + using (var contentUpdate = mConflict.Call("getResolutionSnapshotContents")) + { + if (!contentUpdate.Call("writeBytes", updatedData)) + { + OurUtils.Logger.e("Can't update snapshot contents during conflict resolution."); + mCompleteCallback(SavedGameRequestStatus.BadInputError, null); + } + + using (var convertedMetadataChange = AsMetadataChange(metadataUpdate)) + using (var task = mSnapshotsClient.Call( + "resolveConflict", + mConflict.Call("getConflictId"), + convertedMetadata.JavaMetadata.Call("getSnapshotId"), + convertedMetadataChange, + contentUpdate)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + dataOrConflict => mRetryFileOpen()); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => { + OurUtils.Logger.d("ResolveConflict failed: " + exception.Call("toString")); + var status = mAndroidSavedGameClient.mAndroidClient.IsAuthenticated() ? + SavedGameRequestStatus.InternalError : + SavedGameRequestStatus.AuthenticationError; + mCompleteCallback(status, null); + } + ); + } + } + } + + public void ChooseMetadata(ISavedGameMetadata chosenMetadata) + { + AndroidSnapshotMetadata convertedMetadata = chosenMetadata as AndroidSnapshotMetadata; + + if (convertedMetadata != mOriginal && convertedMetadata != mUnmerged) + { + OurUtils.Logger.e("Caller attempted to choose a version of the metadata that was not part " + + "of the conflict"); + mCompleteCallback(SavedGameRequestStatus.BadInputError, null); + return; + } + + using (var task = mSnapshotsClient.Call( + "resolveConflict", mConflict.Call("getConflictId"), convertedMetadata.JavaSnapshot)) + { + AndroidTaskUtils.AddOnSuccessListener( + task, + dataOrConflict => mRetryFileOpen()); + + AndroidTaskUtils.AddOnFailureListener( + task, + exception => { + OurUtils.Logger.d("ChooseMetadata failed: " + exception.Call("toString")); + var status = mAndroidSavedGameClient.mAndroidClient.IsAuthenticated() ? + SavedGameRequestStatus.InternalError : + SavedGameRequestStatus.AuthenticationError; + mCompleteCallback(status, null); + } + ); + } + } + } + + internal static bool IsValidFilename(string filename) + { + if (filename == null) + { + return false; + } + + return ValidFilenameRegex.IsMatch(filename); + } + + private static AndroidJavaObject AsMetadataChange(SavedGameMetadataUpdate update) + { + using (var builder = + new AndroidJavaObject("com.google.android.gms.games.snapshot.SnapshotMetadataChange$Builder")) + { + if (update.IsCoverImageUpdated) + { + using (var bitmapFactory = new AndroidJavaClass("android.graphics.BitmapFactory")) + using (var bitmap = bitmapFactory.CallStatic( + "decodeByteArray", update.UpdatedPngCoverImage, /* offset= */0, + update.UpdatedPngCoverImage.Length)) + using (builder.Call("setCoverImage", bitmap)) + ; + } + + if (update.IsDescriptionUpdated) + { + using (builder.Call("setDescription", update.UpdatedDescription)) ; + } + + if (update.IsPlayedTimeUpdated) + { + using (builder.Call("setPlayedTimeMillis", + Convert.ToInt64(update.UpdatedPlayedTime.Value.TotalMilliseconds))) ; + } + + return builder.Call("build"); + } + } + + private static Action ToOnGameThread(Action toConvert) + { + return (val1, val2) => PlayGamesHelperObject.RunOnGameThread(() => toConvert(val1, val2)); + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs.meta new file mode 100644 index 0000000..e42a073 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSavedGameClient.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a52ca79a06d83464e89d0d052c9af7d9 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs new file mode 100644 index 0000000..23623fb --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs @@ -0,0 +1,90 @@ +#if UNITY_ANDROID + +namespace GooglePlayGames.Android +{ + using System; + using System.Collections.Generic; + using GooglePlayGames.BasicApi; + using GooglePlayGames.BasicApi.SavedGame; + using UnityEngine; + + internal class AndroidSnapshotMetadata : ISavedGameMetadata + { + private AndroidJavaObject mJavaSnapshot; + private AndroidJavaObject mJavaMetadata; + private AndroidJavaObject mJavaContents; + + public AndroidSnapshotMetadata(AndroidJavaObject javaSnapshot) + { + mJavaSnapshot = javaSnapshot; + mJavaMetadata = javaSnapshot.Call("getMetadata"); + mJavaContents = javaSnapshot.Call("getSnapshotContents"); + } + + public AndroidSnapshotMetadata(AndroidJavaObject javaMetadata, AndroidJavaObject javaContents) + { + mJavaSnapshot = null; + mJavaMetadata = javaMetadata; + mJavaContents = javaContents; + } + + public AndroidJavaObject JavaSnapshot + { + get { return mJavaSnapshot; } + } + + public AndroidJavaObject JavaMetadata + { + get { return mJavaMetadata; } + } + + public AndroidJavaObject JavaContents + { + get { return mJavaContents; } + } + + public bool IsOpen + { + get + { + if (mJavaContents == null) + { + return false; + } + + return !mJavaContents.Call("isClosed"); + } + } + + public string Filename + { + get { return mJavaMetadata.Call("getUniqueName"); } + } + + public string Description + { + get { return mJavaMetadata.Call("getDescription"); } + } + + public string CoverImageURL + { + get { return mJavaMetadata.Call("getCoverImageUrl"); } + } + + public TimeSpan TotalTimePlayed + { + get { return TimeSpan.FromMilliseconds(mJavaMetadata.Call("getPlayedTime")); } + } + + public DateTime LastModifiedTimestamp + { + get + { + long timestamp = mJavaMetadata.Call("getLastModifiedTimestamp"); + System.DateTime lastModifiedTime = AndroidJavaConverter.ToDateTime(timestamp); + return lastModifiedTime; + } + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs.meta new file mode 100644 index 0000000..b6112b3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidSnapshotMetadata.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 330ac7fa11d9a4bc099f0db5a3c26ad7 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs new file mode 100644 index 0000000..4740cae --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs @@ -0,0 +1,111 @@ +#if UNITY_ANDROID +#pragma warning disable 0642 // Possible mistaken empty statement + +namespace GooglePlayGames.Android +{ + using UnityEngine; + using System; + + class AndroidTaskUtils + { + private AndroidTaskUtils() + { + } + + public static void AddOnSuccessListener(AndroidJavaObject task, Action callback) + { + using (task.Call("addOnSuccessListener", + new TaskOnSuccessProxy(callback, /* disposeResult= */ true))) ; + } + + public static void AddOnSuccessListener(AndroidJavaObject task, bool disposeResult, Action callback) + { + using (task.Call("addOnSuccessListener", + new TaskOnSuccessProxy(callback, disposeResult))) ; + } + + public static void AddOnFailureListener(AndroidJavaObject task, Action callback) + { + using (task.Call("addOnFailureListener", new TaskOnFailedProxy(callback))) ; + } + + public static void AddOnCompleteListener(AndroidJavaObject task, Action callback) + { + using (task.Call("addOnCompleteListener", new TaskOnCompleteProxy(callback))) ; + } + + private class TaskOnCompleteProxy : AndroidJavaProxy + { + private Action mCallback; + + public TaskOnCompleteProxy(Action callback) + : base("com/google/android/gms/tasks/OnCompleteListener") + { + mCallback = callback; + } + + public void onComplete(T result) + { + if (result is IDisposable) + { + using ((IDisposable) result) + { + mCallback(result); + } + } + else + { + mCallback(result); + } + } + } + + private class TaskOnSuccessProxy : AndroidJavaProxy + { + private Action mCallback; + private bool mDisposeResult; + + public TaskOnSuccessProxy(Action callback, bool disposeResult) + : base("com/google/android/gms/tasks/OnSuccessListener") + { + mCallback = callback; + mDisposeResult = disposeResult; + } + + public void onSuccess(T result) + { + if (result is IDisposable && mDisposeResult) + { + using ((IDisposable) result) + { + mCallback(result); + } + } + else + { + mCallback(result); + } + } + } + + private class TaskOnFailedProxy : AndroidJavaProxy + { + private Action mCallback; + + public TaskOnFailedProxy(Action callback) + : base("com/google/android/gms/tasks/OnFailureListener") + { + mCallback = callback; + } + + public void onFailure(AndroidJavaObject exception) + { + using (exception) + { + mCallback(exception); + } + } + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs.meta new file mode 100644 index 0000000..97db5a0 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/Android/AndroidTaskUtils.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 5d045a29538404b2da664bb55de949de +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs new file mode 100644 index 0000000..2122714 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs @@ -0,0 +1,41 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Android only feature + +#if (UNITY_ANDROID) +namespace GooglePlayGames +{ + using UnityEngine; + using System; + using GooglePlayGames.OurUtils; + using GooglePlayGames.BasicApi.Nearby; + + public static class NearbyConnectionClientFactory + { + public static void Create(Action callback) + { + if (Application.isEditor) + { + GooglePlayGames.OurUtils.Logger.d("Creating INearbyConnection in editor, using DummyClient."); + callback.Invoke(new GooglePlayGames.BasicApi.Nearby.DummyNearbyConnectionClient()); + } + + callback.Invoke(new GooglePlayGames.Android.AndroidNearbyConnectionClient()); + } + } +} +#endif //UNITY_ANDROID \ No newline at end of file diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs.meta new file mode 100644 index 0000000..421f95d --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/NearbyConnectionClientFactory.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ff1201bd0205943ba9c881e50e38156b +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs new file mode 100644 index 0000000..0c1ca52 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs @@ -0,0 +1,44 @@ +// +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if UNITY_ANDROID + +namespace GooglePlayGames +{ + using UnityEngine; + using GooglePlayGames.BasicApi; + using GooglePlayGames.OurUtils; + + internal class PlayGamesClientFactory + { + internal static IPlayGamesClient GetPlatformPlayGamesClient() + { + if (Application.isEditor) + { + GooglePlayGames.OurUtils.Logger.d("Creating IPlayGamesClient in editor, using DummyClient."); + return new GooglePlayGames.BasicApi.DummyClient(); + } +#if UNITY_ANDROID + GooglePlayGames.OurUtils.Logger.d("Creating Android IPlayGamesClient Client"); + return new GooglePlayGames.Android.AndroidClient(); +#else + GooglePlayGames.OurUtils.Logger.d("Cannot create IPlayGamesClient for unknown platform, returning DummyClient"); + return new GooglePlayGames.BasicApi.DummyClient(); +#endif + } + } +} +#endif diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs.meta new file mode 100644 index 0000000..322e1f3 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/Platforms/PlayGamesClientFactory.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 435fc2d0dc0ba475e9c8b0796303d6dd +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs new file mode 100644 index 0000000..becc1c2 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs @@ -0,0 +1,26 @@ +// +// Copyright (C) 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace GooglePlayGames +{ + public class PluginVersion + { + // Current Version. + public const int VersionInt = 0x20000; + public const string VersionString = "2.1.0"; + public const string VersionKey = "20100" ; + } +} diff --git a/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs.meta b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs.meta new file mode 100644 index 0000000..ff061ce --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/Runtime/Scripts/PluginVersion.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 4539142948daf4a26bf9cd6870ffa0b2 +labels: +- gvh +- gvh_version-2.1.0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/current-build.meta b/Assets/GooglePlayGames/com.google.play.games/current-build.meta new file mode 100644 index 0000000..fc87307 --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/current-build.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6681e4838fac4335aefe237b6962051 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GooglePlayGames/com.google.play.games/package.json b/Assets/GooglePlayGames/com.google.play.games/package.json new file mode 100644 index 0000000..7a3461b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/package.json @@ -0,0 +1,11 @@ +{ + "name": "com.google.play.games", + "displayName": "Google Play Games", + "description": "The Google Play Games plugin for Unity allows you to access the Google Play Games API through Unity's social interface.", + "version": "2.1.0", + "unity": "2018.4", + "author": { + "name": "Google LLC" + }, + "dependencies": {} +} diff --git a/Assets/GooglePlayGames/com.google.play.games/package.json.meta b/Assets/GooglePlayGames/com.google.play.games/package.json.meta new file mode 100644 index 0000000..a712c9b --- /dev/null +++ b/Assets/GooglePlayGames/com.google.play.games/package.json.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 51dd7d46faed94b31a71d5f4cec6ce14 +labels: +- gvh +- gvh_version-2.1.0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Memo.txt b/Assets/Memo.txt index 332fb3d..92bec1b 100644 --- a/Assets/Memo.txt +++ b/Assets/Memo.txt @@ -28,7 +28,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -세이브 데이터 암호화 -데이터 저장, 불러오기 (구글 플레이센터로 변경) +데이터 저장, 불러오기 (구글 플레이센터로 변경) - 확인 필요 원스토어 검수 빌드 후 원스토어 결제 추가 \ No newline at end of file diff --git a/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib.meta b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib.meta new file mode 100644 index 0000000..fa07451 --- /dev/null +++ b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 44f4150f398dc4f22b230f8c74866383 +folderAsset: yes +timeCreated: 1504033921 +licenseType: Pro +PluginImporter: + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + data: + first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 0 + Exclude Linux: 0 + Exclude Linux64: 0 + Exclude LinuxUniversal: 0 + Exclude OSXIntel: 0 + Exclude OSXIntel64: 0 + Exclude OSXUniversal: 0 + Exclude WebGL: 0 + Exclude Win: 0 + Exclude Win64: 0 + Exclude iOS: 0 + data: + first: + '': Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + OS: AnyOS + data: + first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + data: + first: + Any: + second: + enabled: 1 + settings: {} + data: + first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + data: + first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + data: + first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + data: + first: + Standalone: Linux + second: + enabled: 1 + settings: + CPU: x86 + data: + first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + data: + first: + Standalone: LinuxUniversal + second: + enabled: 1 + settings: {} + data: + first: + Standalone: OSXIntel + second: + enabled: 1 + settings: + CPU: AnyCPU + data: + first: + Standalone: OSXIntel64 + second: + enabled: 1 + settings: + CPU: AnyCPU + data: + first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: {} + data: + first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + data: + first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + data: + first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + data: + first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/AndroidManifest.xml b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/AndroidManifest.xml new file mode 100644 index 0000000..f5b4246 --- /dev/null +++ b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/project.properties b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/project.properties new file mode 100644 index 0000000..f438126 --- /dev/null +++ b/Assets/Plugins/Android/GooglePlayGamesManifest.androidlib/project.properties @@ -0,0 +1,2 @@ +target=android-16 +android.library=true diff --git a/Assets/Plugins/Android/mainTemplate.gradle b/Assets/Plugins/Android/mainTemplate.gradle index 60e0442..c0b6778 100644 --- a/Assets/Plugins/Android/mainTemplate.gradle +++ b/Assets/Plugins/Android/mainTemplate.gradle @@ -11,6 +11,7 @@ dependencies { implementation 'com.google.android.gms:play-services-ads:23.6.0' // Packages/com.google.ads.mobile/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7 implementation 'com.google.android.gms:play-services-auth:16+' // Assets/GoogleSignIn/Editor/GoogleSignInDependencies.xml:10 implementation 'com.google.android.ump:user-messaging-platform:3.1.0' // Packages/com.google.ads.mobile/GoogleMobileAds/Editor/GoogleUmpDependencies.xml:7 + implementation 'com.google.games:gpgs-plugin-support:2.1.0' // Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml:11 implementation 'com.google.signin:google-signin-support:1.0.4' // Assets/GoogleSignIn/Editor/GoogleSignInSupportDependencies.xml:9 implementation 'com.onestorecorp.sdk:sdk-iap:21.01.00' // Assets/OneStoreCorpPlugins/Purchase/Editor/PurchaseDependencies.xml:6 implementation 'com.onestorecorp.sdk:sdk-licensing:2.1.0' // Assets/OneStoreCorpPlugins/AppLicenseChecker/Editor/AppLicenseCheckerDependencies.xml:6 diff --git a/Assets/Plugins/Android/mainTemplate.gradle.backup3 b/Assets/Plugins/Android/mainTemplate.gradle.backup3 new file mode 100644 index 0000000..c08644e --- /dev/null +++ b/Assets/Plugins/Android/mainTemplate.gradle.backup3 @@ -0,0 +1,67 @@ +apply plugin: 'com.android.library' +apply from: '../shared/keepUnitySymbols.gradle' +**APPLY_PLUGINS** + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +// Android Resolver Dependencies Start + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' // Packages/com.google.ads.mobile/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:12 + implementation 'com.google.ads.mediation:facebook:6.18.0.0' // Packages/com.google.ads.mobile.mediation.metaaudiencenetwork/source/plugin/Assets/GoogleMobileAds/Mediation/MetaAudienceNetwork/Editor/MetaAudienceNetworkMediationDependencies.xml:24 + implementation 'com.google.ads.mediation:unity:4.12.3.0' // Assets/GoogleMobileAds/Mediation/UnityAds/Editor/UnityMediationDependencies.xml:25 + implementation 'com.google.android.gms:play-services-ads:23.6.0' // Packages/com.google.ads.mobile/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7 + implementation 'com.google.android.gms:play-services-auth:16+' // Assets/GoogleSignIn/Editor/GoogleSignInDependencies.xml:10 + implementation 'com.google.android.ump:user-messaging-platform:3.1.0' // Packages/com.google.ads.mobile/GoogleMobileAds/Editor/GoogleUmpDependencies.xml:7 + implementation 'com.google.games:gpgs-plugin-support:2.1.0' // Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml:11 + implementation 'com.google.signin:google-signin-support:1.0.4' // Assets/GoogleSignIn/Editor/GoogleSignInSupportDependencies.xml:9 + implementation 'com.onestorecorp.sdk:sdk-iap:21.01.00' // Assets/OneStoreCorpPlugins/Purchase/Editor/PurchaseDependencies.xml:6 + implementation 'com.onestorecorp.sdk:sdk-licensing:2.1.0' // Assets/OneStoreCorpPlugins/AppLicenseChecker/Editor/AppLicenseCheckerDependencies.xml:6 + implementation 'com.unity3d.ads:unity-ads:4.12.3' // Assets/GoogleMobileAds/Mediation/UnityAds/Editor/UnityMediationDependencies.xml:33 +// Android Resolver Dependencies End +**DEPS**} + +// Android Resolver Exclusions Start +android { + packagingOptions { + exclude ('/lib/armeabi/*' + '*') + exclude ('/lib/mips/*' + '*') + exclude ('/lib/mips64/*' + '*') + exclude ('/lib/x86/*' + '*') + exclude ('/lib/x86_64/*' + '*') + } +} +// Android Resolver Exclusions End +android { + ndkPath "**NDKPATH**" + + compileSdk **APIVERSION** + buildToolsVersion '**BUILDTOOLS**' + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + defaultConfig { + minSdk **MINSDK** + targetSdk **TARGETSDK** + ndk { + debugSymbolLevel **DEBUGSYMBOLLEVEL** + abiFilters **ABIFILTERS** + } + versionCode **VERSIONCODE** + versionName '**VERSIONNAME**' + consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD** + } + + lint { + abortOnError false + } + + androidResources { + noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ') + ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~" + }**PACKAGING** +} +**IL_CPP_BUILD_SETUP** +**SOURCE_BUILD_SETUP** +**EXTERNAL_SOURCES** diff --git a/Assets/Plugins/Android/mainTemplate.gradle.backup3.meta b/Assets/Plugins/Android/mainTemplate.gradle.backup3.meta new file mode 100644 index 0000000..84e868a --- /dev/null +++ b/Assets/Plugins/Android/mainTemplate.gradle.backup3.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 10885133b1498294eb547f60323118b9 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Android/settingsTemplate.gradle b/Assets/Plugins/Android/settingsTemplate.gradle index cc8205c..7ec1441 100644 --- a/Assets/Plugins/Android/settingsTemplate.gradle +++ b/Assets/Plugins/Android/settingsTemplate.gradle @@ -24,6 +24,9 @@ dependencyResolutionManagement { maven { url "https://repo.maven.apache.org/maven2/" // Assets/GoogleMobileAds/Mediation/UnityAds/Editor/UnityMediationDependencies.xml:25, Assets/GoogleMobileAds/Mediation/UnityAds/Editor/UnityMediationDependencies.xml:33, Packages/com.google.ads.mobile.mediation.metaaudiencenetwork/source/plugin/Assets/GoogleMobileAds/Mediation/MetaAudienceNetwork/Editor/MetaAudienceNetworkMediationDependencies.xml:24 } + maven { + url (unityProjectPath + "/Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository") // Assets/GooglePlayGames/com.google.play.games/Editor/GooglePlayGamesPluginDependencies.xml:11 + } maven { url (unityProjectPath + "/Assets/GeneratedLocalRepo/GoogleSignIn/Editor/m2repository") // Assets/GoogleSignIn/Editor/GoogleSignInSupportDependencies.xml:9 } diff --git a/Assets/Plugins/Easy Save 3/Resources/ES3/ES3Defaults.asset b/Assets/Plugins/Easy Save 3/Resources/ES3/ES3Defaults.asset index 61d7701..687a3f5 100644 --- a/Assets/Plugins/Easy Save 3/Resources/ES3/ES3Defaults.asset +++ b/Assets/Plugins/Easy Save 3/Resources/ES3/ES3Defaults.asset @@ -34,6 +34,7 @@ MonoBehaviour: - Assembly-CSharp-firstpass - CFXRDemo - CFXRRuntime + - Google.Play.Games - GoogleMobileAds.Mediation.UnityAds.Android - GoogleMobileAds.Mediation.UnityAds.Api - GoogleMobileAds.Mediation.UnityAds.Common diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab b/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab new file mode 100644 index 0000000..e7e92f1 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab @@ -0,0 +1,634 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB370\uC774\uD130\uB97C \uB0B4\uB824\uBC1B\uC558\uC2B5\uB2C8\uB2E4.\r\n\uAC8C\uC784\uC744 + \uC7AC\uC2DC\uC791 \uD574\uC8FC\uC138\uC694." + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &2146986294350315589 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1313316559661637386} + - component: {fileID: 2903463085084729646} + - component: {fileID: 3511040308576275676} + - component: {fileID: 115976426752958718} + m_Layer: 5 + m_Name: AgreedButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1313316559661637386 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6403968303874475723} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2903463085084729646 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_CullTransparentMesh: 1 +--- !u!114 &3511040308576275676 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 6facc842ead05744184e7db7ba064b48, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &115976426752958718 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1463953945109322297} + m_TargetAssemblyTypeName: CloudLoadPopup, Assembly-CSharp + m_MethodName: OnClick_Quit + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!1 &5771424763395209068 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3770730671028469677} + - component: {fileID: 4583093844719226905} + - component: {fileID: 6672885542466119970} + m_Layer: 5 + m_Name: New Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3770730671028469677 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5771424763395209068} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4583093844719226905 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5771424763395209068} + m_CullTransparentMesh: 1 +--- !u!114 &6672885542466119970 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5771424763395209068} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 1313316559661637386} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 1463953945109322297} + m_Layer: 5 + m_Name: CloudLoadCompletePopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3770730671028469677} + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1463953945109322297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 82ee710e8852a0848bf4835ead2706dc, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7740939426781283448 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6403968303874475723} + - component: {fileID: 2313491179682301191} + - component: {fileID: 5779080122213389523} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6403968303874475723 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1313316559661637386} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2313491179682301191 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + m_CullTransparentMesh: 1 +--- !u!114 &5779080122213389523 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB3D9\uC758" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab.meta new file mode 100644 index 0000000..61e9d92 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadCompletePopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 023362dc80af9d240b589e1c9ce0751f +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab b/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab new file mode 100644 index 0000000..71b29fa --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab @@ -0,0 +1,558 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB370\uC774\uD130 \uB0B4\uB824\uBC1B\uAE30\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.\r\n\uB098\uC911\uC5D0 + \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694." + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &4847793638731525687 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3691371889073614225} + - component: {fileID: 1386677856161751151} + - component: {fileID: 3037916600926297404} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3691371889073614225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6919250392876316429} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1386677856161751151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_CullTransparentMesh: 1 +--- !u!114 &3037916600926297404 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB2EB\uAE30" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 6919250392876316429} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 1463953945109322297} + m_Layer: 5 + m_Name: CloudLoadFailPopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1463953945109322297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 82ee710e8852a0848bf4835ead2706dc, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7796128296011831133 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6919250392876316429} + - component: {fileID: 8377537973582531916} + - component: {fileID: 5693105889486739670} + - component: {fileID: 4672751859202181045} + m_Layer: 5 + m_Name: CloseButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6919250392876316429 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3691371889073614225} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8377537973582531916 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_CullTransparentMesh: 1 +--- !u!114 &5693105889486739670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 2 +--- !u!114 &4672751859202181045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1463953945109322297} + m_TargetAssemblyTypeName: CloudLoadPopup, Assembly-CSharp + m_MethodName: OnClick_Cancel + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab.meta new file mode 100644 index 0000000..692cb6f --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadFailPopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4104469e9124e7049b80ba47ed4db859 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab b/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab new file mode 100644 index 0000000..51c9ed8 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab @@ -0,0 +1,558 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uC800\uC7A5\uB41C \uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\r\n\uC800\uC7A5\uC744 + \uBA3C\uC800 \uD574\uC8FC\uC138\uC694." + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &4847793638731525687 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3691371889073614225} + - component: {fileID: 1386677856161751151} + - component: {fileID: 3037916600926297404} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3691371889073614225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6919250392876316429} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1386677856161751151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_CullTransparentMesh: 1 +--- !u!114 &3037916600926297404 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB2EB\uAE30" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 6919250392876316429} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 1463953945109322297} + m_Layer: 5 + m_Name: CloudLoadNoDataPopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1463953945109322297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 82ee710e8852a0848bf4835ead2706dc, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7796128296011831133 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6919250392876316429} + - component: {fileID: 8377537973582531916} + - component: {fileID: 5693105889486739670} + - component: {fileID: 4672751859202181045} + m_Layer: 5 + m_Name: CloseButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6919250392876316429 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3691371889073614225} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8377537973582531916 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_CullTransparentMesh: 1 +--- !u!114 &5693105889486739670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 2 +--- !u!114 &4672751859202181045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1463953945109322297} + m_TargetAssemblyTypeName: CloudLoadPopup, Assembly-CSharp + m_MethodName: OnClick_Cancel + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab.meta new file mode 100644 index 0000000..306694d --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadNoDataPopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4c3ac99fc5d91ca41b06afb2aa16efb2 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/AgreeConditionsPopup.prefab b/Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab similarity index 63% rename from Assets/Resources/Prefabs/Popups/AgreeConditionsPopup.prefab rename to Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab index 45fe0c3..d047dd7 100644 --- a/Assets/Resources/Prefabs/Popups/AgreeConditionsPopup.prefab +++ b/Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab @@ -34,7 +34,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} - m_AnchoredPosition: {x: 0, y: 106} + m_AnchoredPosition: {x: 0, y: 84} m_SizeDelta: {x: -50, y: 250} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4623288986574023431 @@ -65,10 +65,9 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: "\uC9C4\uD589\uB41C \uB370\uC774\uD2B8\uB97C \uC800\uC7A5\uD558\uAE30 \uC704\uD574\uC11C\uB294 - \uACC4\uC815 \uB4F1\uB85D\uC744 \uD574\uC57C \uD569\uB2C8\uB2E4.\n\uACC4\uC815 - \uB4F1\uB85D\uC5D0 \uD544\uC694\uD55C \uC57D\uAD00\uC5D0 \uB3D9\uC758\uB97C \uD558\uC2DC\uBA74 - \uB3D9\uC758\uD558\uAE30 \uBC84\uD2BC\uC744 \uC120\uD0DD\uD574 \uC8FC\uC2ED\uC2DC\uC624." + m_text: "\uB85C\uADF8\uC778 \uD6C4 \uD074\uB77C\uC6B0\uB4DC \uB370\uC774\uD130\uB97C + \uB0B4\uB824\uBC1B\uC2B5\uB2C8\uB2E4.\r\n\uC644\uB8CC \uD6C4 \uAC8C\uC784\uC744 + \uC7AC\uC2DC\uC791 \uD574\uC8FC\uC138\uC694." m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} @@ -77,8 +76,8 @@ MonoBehaviour: m_fontMaterials: [] m_fontColor32: serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} m_enableVertexGradient: 0 m_colorMode: 3 m_fontColorGradient: @@ -102,158 +101,26 @@ MonoBehaviour: m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 - m_HorizontalAlignment: 1 - m_VerticalAlignment: 512 - m_textAlignment: 65535 - m_characterSpacing: 0 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 0 - m_linkedTextComponent: {fileID: 0} - parentLinkedComponent: {fileID: 0} - m_enableKerning: 1 - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 0 - m_parseCtrlCharacters: 0 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_IsTextObjectScaleStatic: 0 - m_VertexBufferAutoSizeReduction: 0 - m_useMaxVisibleDescender: 0 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!1 &1729771318282731778 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 6108701293695219724} - - component: {fileID: 734259679684768732} - - component: {fileID: 3682277623935672778} - m_Layer: 5 - m_Name: Text (TMP) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &6108701293695219724 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1729771318282731778} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 7955650568122257587} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 5} - m_SizeDelta: {x: 0, y: -10} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &734259679684768732 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1729771318282731778} - m_CullTransparentMesh: 1 ---- !u!114 &3682277623935672778 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1729771318282731778} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_text: "\uAC1C\uC778\uC815\uBCF4\uCC98\uB9AC\uBC29\uCE68, \uC774\uC6A9\uC57D\uAD00" - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_colorMode: 3 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_StyleSheet: {fileID: 0} - m_TextStyleHashCode: -1183493901 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_fontSize: 45 - m_fontSizeBase: 45 - m_fontWeight: 400 - m_enableAutoSizing: 0 - m_fontSizeMin: 18 - m_fontSizeMax: 72 - m_fontStyle: 0 m_HorizontalAlignment: 2 m_VerticalAlignment: 512 m_textAlignment: 65535 m_characterSpacing: 0 m_wordSpacing: 0 - m_lineSpacing: 0 + m_lineSpacing: 30 m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} - m_enableKerning: 0 + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 0 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 0 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -307,8 +174,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 171, y: -292} - m_SizeDelta: {x: 250, y: 120} + m_AnchoredPosition: {x: 171, y: -138} + m_SizeDelta: {x: 250, y: 100} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2903463085084729646 CanvasRenderer: @@ -338,8 +205,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: cb37917483ee24fea8fab306393441e5, type: 3} - m_Type: 1 + m_Sprite: {fileID: 21300000, guid: 6facc842ead05744184e7db7ba064b48, type: 3} + m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -347,7 +214,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 2 + m_PixelsPerUnitMultiplier: 1 --- !u!114 &115976426752958718 MonoBehaviour: m_ObjectHideFlags: 0 @@ -365,115 +232,9 @@ MonoBehaviour: callback: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 778818077049193411} - m_TargetAssemblyTypeName: AgreeConditionsPopup, Assembly-CSharp - m_MethodName: ClickAgreedButton - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 ---- !u!1 &3312392719446229288 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7955650568122257587} - - component: {fileID: 7221257200398869766} - - component: {fileID: 6518562206873050239} - - component: {fileID: 1037621559045878288} - m_Layer: 5 - m_Name: PrivacyPolicyButton - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &7955650568122257587 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3312392719446229288} - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 6108701293695219724} - m_Father: {fileID: 3914003348280645851} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: -127} - m_SizeDelta: {x: 570, y: 120} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &7221257200398869766 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3312392719446229288} - m_CullTransparentMesh: 1 ---- !u!114 &6518562206873050239 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3312392719446229288} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 804461bef59b141dba258fc997c8ca15, type: 3} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 2 ---- !u!114 &1037621559045878288 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3312392719446229288} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Delegates: - - eventID: 4 - callback: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 778818077049193411} - m_TargetAssemblyTypeName: AgreeConditionsPopup, Assembly-CSharp - m_MethodName: ClickPrivacyPolicyButton + - m_Target: {fileID: 1463953945109322297} + m_TargetAssemblyTypeName: CloudLoadPopup, Assembly-CSharp + m_MethodName: OnClick_OK m_Mode: 1 m_Arguments: m_ObjectArgument: {fileID: 0} @@ -591,149 +352,17 @@ MonoBehaviour: m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 - m_wordWrappingRatios: 0.4 - m_overflowMode: 0 - m_linkedTextComponent: {fileID: 0} - parentLinkedComponent: {fileID: 0} - m_enableKerning: 0 - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 0 - m_parseCtrlCharacters: 0 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_IsTextObjectScaleStatic: 0 - m_VertexBufferAutoSizeReduction: 0 - m_useMaxVisibleDescender: 0 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_hasFontAssetChanged: 0 - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!1 &5942974085134851686 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5820604775903360758} - - component: {fileID: 8265334662623583627} - - component: {fileID: 7263975805417817899} - m_Layer: 5 - m_Name: Title - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &5820604775903360758 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5942974085134851686} - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 3914003348280645851} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 323} - m_SizeDelta: {x: 200, y: 50} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &8265334662623583627 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5942974085134851686} - m_CullTransparentMesh: 1 ---- !u!114 &7263975805417817899 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5942974085134851686} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_text: "\uC57D\uAD00\uC5D0 \uB3D9\uC758\uD558\uACE0 \uACC4\uC815 \uB4F1\uB85D\uD558\uAE30" - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_colorMode: 3 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_StyleSheet: {fileID: 0} - m_TextStyleHashCode: -1183493901 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_fontSize: 50 - m_fontSizeBase: 50 - m_fontWeight: 400 - m_enableAutoSizing: 0 - m_fontSizeMin: 18 - m_fontSizeMax: 72 - m_fontStyle: 0 - m_HorizontalAlignment: 2 - m_VerticalAlignment: 512 - m_textAlignment: 65535 - m_characterSpacing: 0 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 0 + m_ActiveFontFeatures: m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 0 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 0 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -781,17 +410,15 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 5820604775903360758} - {fileID: 3827274076957746089} - {fileID: 1313316559661637386} - {fileID: 6919250392876316429} - - {fileID: 7955650568122257587} m_Father: {fileID: 9007310997297665168} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: 0, y: 72} - m_SizeDelta: {x: 900, y: 800} + m_SizeDelta: {x: 900, y: 500} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &9204485070799621501 CanvasRenderer: @@ -821,7 +448,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: eb3db5b0868bc4f348e3d3a1dfbf32a8, type: 3} + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 @@ -843,9 +470,9 @@ GameObject: - component: {fileID: 2517309549320446724} - component: {fileID: 6495025563002481046} - component: {fileID: 4130399851895737701} - - component: {fileID: 778818077049193411} + - component: {fileID: 1463953945109322297} m_Layer: 5 - m_Name: AgreeConditionsPopup + m_Name: CloudLoadPopup m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -919,7 +546,7 @@ MonoBehaviour: m_BlockingMask: serializedVersion: 2 m_Bits: 4294967295 ---- !u!114 &778818077049193411 +--- !u!114 &1463953945109322297 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -928,10 +555,9 @@ MonoBehaviour: m_GameObject: {fileID: 7406854172275695763} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9c1b79bfe5b04b846bfc6231a1f9e3da, type: 3} + m_Script: {fileID: 11500000, guid: 82ee710e8852a0848bf4835ead2706dc, type: 3} m_Name: m_EditorClassIdentifier: - type: 0 --- !u!1 &7740939426781283448 GameObject: m_ObjectHideFlags: 0 @@ -1040,15 +666,17 @@ MonoBehaviour: m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 0 + m_TextWrappingMode: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} parentLinkedComponent: {fileID: 0} m_enableKerning: 0 + m_ActiveFontFeatures: m_enableExtraPadding: 0 checkPaddingRequired: 0 m_isRichText: 0 + m_EmojiFallbackSupport: 1 m_parseCtrlCharacters: 0 m_isOrthographic: 1 m_isCullingEnabled: 0 @@ -1102,8 +730,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -171, y: -292} - m_SizeDelta: {x: 250, y: 120} + m_AnchoredPosition: {x: -171, y: -138} + m_SizeDelta: {x: 250, y: 100} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &8377537973582531916 CanvasRenderer: @@ -1133,8 +761,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 2bc701b63b63f40e0893a9fabeaa0a78, type: 3} - m_Type: 1 + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -1160,9 +788,9 @@ MonoBehaviour: callback: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 778818077049193411} - m_TargetAssemblyTypeName: AgreeConditionsPopup, Assembly-CSharp - m_MethodName: ClickCloseButton + - m_Target: {fileID: 1463953945109322297} + m_TargetAssemblyTypeName: CloudLoadPopup, Assembly-CSharp + m_MethodName: OnClick_Cancel m_Mode: 1 m_Arguments: m_ObjectArgument: {fileID: 0} diff --git a/Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab.meta new file mode 100644 index 0000000..59206aa --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudLoadPopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dd5cdfdf4e3dc59478c53011cc0ecab7 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab b/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab new file mode 100644 index 0000000..5ba7a6b --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab @@ -0,0 +1,557 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uD074\uB77C\uC6B0\uB4DC \uC800\uC7A5\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4." + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &4847793638731525687 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3691371889073614225} + - component: {fileID: 1386677856161751151} + - component: {fileID: 3037916600926297404} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3691371889073614225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6919250392876316429} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1386677856161751151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_CullTransparentMesh: 1 +--- !u!114 &3037916600926297404 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB2EB\uAE30" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 6919250392876316429} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 4263868023533981332} + m_Layer: 5 + m_Name: CloudSaveCompletePopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &4263868023533981332 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 03d765c5d298d664e9a000eb38547051, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7796128296011831133 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6919250392876316429} + - component: {fileID: 8377537973582531916} + - component: {fileID: 5693105889486739670} + - component: {fileID: 4672751859202181045} + m_Layer: 5 + m_Name: CloseButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6919250392876316429 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3691371889073614225} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8377537973582531916 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_CullTransparentMesh: 1 +--- !u!114 &5693105889486739670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 2 +--- !u!114 &4672751859202181045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 4263868023533981332} + m_TargetAssemblyTypeName: CloudSavePopup, Assembly-CSharp + m_MethodName: OnClick_Cancel + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 diff --git a/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab.meta new file mode 100644 index 0000000..b139d2e --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudSaveCompletePopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 601c9fcfccaa05a4f92d2ae5cb5e328e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab b/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab new file mode 100644 index 0000000..8228644 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab @@ -0,0 +1,558 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uD074\uB77C\uC6B0\uB4DC \uC800\uC7A5\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4.\n\uB098\uC911\uC5D0 + \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694." + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &4847793638731525687 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3691371889073614225} + - component: {fileID: 1386677856161751151} + - component: {fileID: 3037916600926297404} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3691371889073614225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6919250392876316429} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1386677856161751151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_CullTransparentMesh: 1 +--- !u!114 &3037916600926297404 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB2EB\uAE30" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 6919250392876316429} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 4263868023533981332} + m_Layer: 5 + m_Name: CloudSaveFailPopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &4263868023533981332 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 03d765c5d298d664e9a000eb38547051, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7796128296011831133 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6919250392876316429} + - component: {fileID: 8377537973582531916} + - component: {fileID: 5693105889486739670} + - component: {fileID: 4672751859202181045} + m_Layer: 5 + m_Name: CloseButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6919250392876316429 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3691371889073614225} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8377537973582531916 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_CullTransparentMesh: 1 +--- !u!114 &5693105889486739670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 2 +--- !u!114 &4672751859202181045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 4263868023533981332} + m_TargetAssemblyTypeName: CloudSavePopup, Assembly-CSharp + m_MethodName: OnClick_Cancel + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 diff --git a/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab.meta new file mode 100644 index 0000000..7311c78 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudSaveFailPopup.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a50fc59a68458404995a5eafa7912dd0 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Popups/CloudSavePopup.prefab b/Assets/Resources/Prefabs/Popups/CloudSavePopup.prefab new file mode 100644 index 0000000..3713267 --- /dev/null +++ b/Assets/Resources/Prefabs/Popups/CloudSavePopup.prefab @@ -0,0 +1,801 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1324829693003538644 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3827274076957746089} + - component: {fileID: 4623288986574023431} + - component: {fileID: 6256073739779036531} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3827274076957746089 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 84} + m_SizeDelta: {x: -50, y: 250} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4623288986574023431 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_CullTransparentMesh: 1 +--- !u!114 &6256073739779036531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1324829693003538644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB85C\uADF8\uC778 \uD6C4 \uD074\uB77C\uC6B0\uB4DC \uC800\uC7A5\uC744 + \uD569\uB2C8\uB2E4.\n\uACC4\uC18D\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: -6508382273668546854, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 40 + m_fontSizeBase: 40 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 30 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &2146986294350315589 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1313316559661637386} + - component: {fileID: 2903463085084729646} + - component: {fileID: 3511040308576275676} + - component: {fileID: 115976426752958718} + m_Layer: 5 + m_Name: AgreedButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1313316559661637386 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6403968303874475723} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 171, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2903463085084729646 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_CullTransparentMesh: 1 +--- !u!114 &3511040308576275676 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 6facc842ead05744184e7db7ba064b48, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &115976426752958718 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2146986294350315589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 4263868023533981332} + m_TargetAssemblyTypeName: CloudSavePopup, Assembly-CSharp + m_MethodName: OnClick_OK + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!1 &4847793638731525687 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3691371889073614225} + - component: {fileID: 1386677856161751151} + - component: {fileID: 3037916600926297404} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3691371889073614225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6919250392876316429} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1386677856161751151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_CullTransparentMesh: 1 +--- !u!114 &3037916600926297404 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4847793638731525687} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB2EB\uAE30" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6165355080912743286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3914003348280645851} + - component: {fileID: 9204485070799621501} + - component: {fileID: 3864653881773320085} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3914003348280645851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3827274076957746089} + - {fileID: 1313316559661637386} + - {fileID: 6919250392876316429} + m_Father: {fileID: 9007310997297665168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 72} + m_SizeDelta: {x: 900, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9204485070799621501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_CullTransparentMesh: 1 +--- !u!114 &3864653881773320085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165355080912743286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5f7fd8185eb11854b9a83301264d3454, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7406854172275695763 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9007310997297665168} + - component: {fileID: 2517309549320446724} + - component: {fileID: 6495025563002481046} + - component: {fileID: 4130399851895737701} + - component: {fileID: 4263868023533981332} + m_Layer: 5 + m_Name: CloudSavePopup + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9007310997297665168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3914003348280645851} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2517309549320446724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_CullTransparentMesh: 1 +--- !u!223 &6495025563002481046 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &4130399851895737701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &4263868023533981332 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7406854172275695763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 03d765c5d298d664e9a000eb38547051, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7740939426781283448 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6403968303874475723} + - component: {fileID: 2313491179682301191} + - component: {fileID: 5779080122213389523} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6403968303874475723 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + 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_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1313316559661637386} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 5} + m_SizeDelta: {x: 0, y: -10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2313491179682301191 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + m_CullTransparentMesh: 1 +--- !u!114 &5779080122213389523 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7740939426781283448} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uB3D9\uC758" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: cf1ae75e65a967946b23286a5ffbb812, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 1cd9f54883d04fa4a8273aaf06ef64e9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 45 + m_fontSizeBase: 45 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 0 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 0 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 0 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &7796128296011831133 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6919250392876316429} + - component: {fileID: 8377537973582531916} + - component: {fileID: 5693105889486739670} + - component: {fileID: 4672751859202181045} + m_Layer: 5 + m_Name: CloseButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6919250392876316429 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + 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_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3691371889073614225} + m_Father: {fileID: 3914003348280645851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -171, y: -138} + m_SizeDelta: {x: 250, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8377537973582531916 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_CullTransparentMesh: 1 +--- !u!114 &5693105889486739670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1c01f2ab08fa29249b1abe0a7243c0c0, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 2 +--- !u!114 &4672751859202181045 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7796128296011831133} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 14a02640485dabf4d8eeab6b8d0e1f37, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 4263868023533981332} + m_TargetAssemblyTypeName: CloudSavePopup, Assembly-CSharp + m_MethodName: OnClick_Cancel + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 diff --git a/Assets/Resources/Prefabs/Popups/AgreeConditionsPopup.prefab.meta b/Assets/Resources/Prefabs/Popups/CloudSavePopup.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/Popups/AgreeConditionsPopup.prefab.meta rename to Assets/Resources/Prefabs/Popups/CloudSavePopup.prefab.meta diff --git a/Assets/Resources/Prefabs/Popups/SettingPopup.prefab b/Assets/Resources/Prefabs/Popups/SettingPopup.prefab index 17f392b..9d0ac1f 100644 --- a/Assets/Resources/Prefabs/Popups/SettingPopup.prefab +++ b/Assets/Resources/Prefabs/Popups/SettingPopup.prefab @@ -2915,7 +2915,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] m_Sprite: {fileID: 21300000, guid: 6facc842ead05744184e7db7ba064b48, type: 3} - m_Type: 0 + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -3157,7 +3157,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] m_Sprite: {fileID: 21300000, guid: 6facc842ead05744184e7db7ba064b48, type: 3} - m_Type: 0 + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 diff --git a/Assets/Resources/VersionCode.txt b/Assets/Resources/VersionCode.txt index d8263ee..e440e5c 100644 --- a/Assets/Resources/VersionCode.txt +++ b/Assets/Resources/VersionCode.txt @@ -1 +1 @@ -2 \ No newline at end of file +3 \ No newline at end of file diff --git a/Assets/Scenes/Title.unity b/Assets/Scenes/Title.unity index 5a8107e..0580c72 100644 --- a/Assets/Scenes/Title.unity +++ b/Assets/Scenes/Title.unity @@ -6437,6 +6437,7 @@ GameObject: m_Component: - component: {fileID: 1711243446} - component: {fileID: 1711243445} + - component: {fileID: 1711243447} m_Layer: 0 m_Name: Time m_TagString: Untagged @@ -6471,6 +6472,18 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1711243447 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1711243444} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 49032e4e4cb45df43ad8eb85861bc35f, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &1732641636 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/My/GPGSInfo.cs b/Assets/Scripts/My/GPGSInfo.cs new file mode 100644 index 0000000..41af93c --- /dev/null +++ b/Assets/Scripts/My/GPGSInfo.cs @@ -0,0 +1,128 @@ +using CodeJay.Classes; +using GooglePlayGames; +using GooglePlayGames.BasicApi; +using GooglePlayGames.BasicApi.SavedGame; +using Newtonsoft.Json; +using System; +using UnityEngine; + +public class GPGSInfo : MonoBehaviour +{ + public static GPGSInfo Ins; + private void Awake() { Ins = this; } + + private ISavedGameClient savedGameClient; + + string str_savedata; + Action act_save, act_load; + string gamedataname = "mygamedata"; + + void Run_act(int status) + { + if (act_save != null) act_save(status); + act_save = null; + + if (act_load != null) act_load(status); + act_load = null; + } + + internal void ProcessAuthentication(SignInStatus status) + { + if (status == SignInStatus.Success) + { + // Continue with Play Games Services + savedGameClient = PlayGamesPlatform.Instance.SavedGame; + if (act_save != null) SaveGameAfterLogin(); + else if (act_load != null) LoadGameAfterLogin(); + } + else + { + // Disable your integration with Play Games Services or show a login button + // to ask users to sign-in. Clicking it should call + // PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication). + + Run_act(-1); + } + } + + public void SaveGame(string data, Action act) + { + str_savedata = data; + act_save = act; + act_load = null; + PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication); + } + void SaveGameAfterLogin() + { + if (savedGameClient != null) + { + byte[] byteData = System.Text.Encoding.UTF8.GetBytes(str_savedata); + + savedGameClient.OpenWithAutomaticConflictResolution( + gamedataname, + DataSource.ReadCacheOrNetwork, + ConflictResolutionStrategy.UseLongestPlaytime, + (status, metadata) => OnSavedGameOpenedForSave(status, metadata, byteData)); + } + else + Run_act(-1); + } + + private void OnSavedGameOpenedForSave(SavedGameRequestStatus status, ISavedGameMetadata game, byte[] data) + { + if (status == SavedGameRequestStatus.Success) + savedGameClient.CommitUpdate(game, new SavedGameMetadataUpdate.Builder().Build(), data, OnGameSaved); + else + Run_act(-1); + } + + private void OnGameSaved(SavedGameRequestStatus status, ISavedGameMetadata game) + { + Run_act(status == SavedGameRequestStatus.Success ? 0 : -1); + } + + public void LoadGame(Action act) + { + act_save = null; + act_load = act; + PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication); + } + void LoadGameAfterLogin() + { + if (savedGameClient != null) + { + savedGameClient.OpenWithAutomaticConflictResolution( + gamedataname, + DataSource.ReadCacheOrNetwork, + ConflictResolutionStrategy.UseLongestPlaytime, + (status, metadata) => OnSavedGameOpenedForLoad(status, metadata)); + } + else + Run_act(-1); + } + + private void OnSavedGameOpenedForLoad(SavedGameRequestStatus status, ISavedGameMetadata game) + { + if (status == SavedGameRequestStatus.Success) + savedGameClient.ReadBinaryData(game, OnGameLoaded); + else + Run_act(-1); + } + + private void OnGameLoaded(SavedGameRequestStatus status, byte[] data) + { + if (status == SavedGameRequestStatus.Success) + { + if (data != null && data.Length > 0) + { + string loadedData = System.Text.Encoding.UTF8.GetString(data); + GameManager.DB.Set_SaveData(JsonConvert.DeserializeObject(loadedData)); + Run_act(0); + } + else + Run_act(-2); + } + else + Run_act(-1); + } +} diff --git a/Assets/Scripts/My/GPGSInfo.cs.meta b/Assets/Scripts/My/GPGSInfo.cs.meta new file mode 100644 index 0000000..1e9e8ea --- /dev/null +++ b/Assets/Scripts/My/GPGSInfo.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 49032e4e4cb45df43ad8eb85861bc35f \ No newline at end of file diff --git a/Assets/Scripts/SingletonManagers/Managers/DBManager.cs b/Assets/Scripts/SingletonManagers/Managers/DBManager.cs index b2c590b..42743c4 100644 --- a/Assets/Scripts/SingletonManagers/Managers/DBManager.cs +++ b/Assets/Scripts/SingletonManagers/Managers/DBManager.cs @@ -1,6 +1,7 @@ using BansheeGz.BGDatabase; using CodeJay.Classes; using CodeJay.Defines; +using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; @@ -309,6 +310,9 @@ public partial class DBManager : MonoBehaviour } } + public string Get_SaveData() { return JsonConvert.SerializeObject(saveData); } + public void Set_SaveData(SaveData saveData) { this.saveData = saveData; SaveDatas(); } + private void LoadDatas() { StartCoroutine(eLoadDatas()); diff --git a/Assets/Scripts/SingletonManagers/Managers/UIManager.cs b/Assets/Scripts/SingletonManagers/Managers/UIManager.cs index 0e615dc..c30426d 100644 --- a/Assets/Scripts/SingletonManagers/Managers/UIManager.cs +++ b/Assets/Scripts/SingletonManagers/Managers/UIManager.cs @@ -44,6 +44,13 @@ public enum EPopupType PreViewPopup, PreViewUIPopup, MissionOpenPopup, + CloudSavePopup, + CloudSaveCompletePopup, + CloudSaveFailPopup, + CloudLoadPopup, + CloudLoadCompletePopup, + CloudLoadFailPopup, + CloudLoadNoDataPopup, } public enum EGraphicRaycasterType @@ -396,6 +403,22 @@ public class UIManager : MonoBehaviour return Instantiate(Resources.Load(path + "PreViewUIPopup"), PopupCanvasTransform); case EPopupType.MissionOpenPopup: return Instantiate(Resources.Load(path + "MissionOpenPopup"), PopupCanvasTransform); + + case EPopupType.CloudSavePopup: + return Instantiate(Resources.Load(path + "CloudSavePopup"), PopupCanvasTransform); + case EPopupType.CloudSaveCompletePopup: + return Instantiate(Resources.Load(path + "CloudSaveCompletePopup"), PopupCanvasTransform); + case EPopupType.CloudSaveFailPopup: + return Instantiate(Resources.Load(path + "CloudSaveFailPopup"), PopupCanvasTransform); + case EPopupType.CloudLoadPopup: + return Instantiate(Resources.Load(path + "CloudLoadPopup"), PopupCanvasTransform); + case EPopupType.CloudLoadCompletePopup: + return Instantiate(Resources.Load(path + "CloudLoadCompletePopup"), PopupCanvasTransform); + case EPopupType.CloudLoadFailPopup: + return Instantiate(Resources.Load(path + "CloudLoadFailPopup"), PopupCanvasTransform); + case EPopupType.CloudLoadNoDataPopup: + return Instantiate(Resources.Load(path + "CloudLoadNoDataPopup"), PopupCanvasTransform); + default: return null; } diff --git a/Assets/Scripts/UI/Popup/CloudLoadPopup.cs b/Assets/Scripts/UI/Popup/CloudLoadPopup.cs new file mode 100644 index 0000000..071f319 --- /dev/null +++ b/Assets/Scripts/UI/Popup/CloudLoadPopup.cs @@ -0,0 +1,19 @@ +public class CloudLoadPopup : PopupBase +{ + public void OnClick_OK() + { + GPGSInfo.Ins.LoadGame(status => + { + OnClick_Cancel(); + if (status == 0) + GameManager.UI.ShowNStackPopup(EPopupType.CloudLoadCompletePopup); + else if (status == -1) + GameManager.UI.ShowNStackPopup(EPopupType.CloudLoadFailPopup); + else + GameManager.UI.ShowNStackPopup(EPopupType.CloudLoadNoDataPopup); + }); + } + + public void OnClick_Cancel() { GameManager.UI.HideTopPopup(); } + public void OnClick_Quit() { DSUtil.Quit(); } +} \ No newline at end of file diff --git a/Assets/Scripts/UI/Popup/CloudLoadPopup.cs.meta b/Assets/Scripts/UI/Popup/CloudLoadPopup.cs.meta new file mode 100644 index 0000000..a3f1e3e --- /dev/null +++ b/Assets/Scripts/UI/Popup/CloudLoadPopup.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 82ee710e8852a0848bf4835ead2706dc \ No newline at end of file diff --git a/Assets/Scripts/UI/Popup/CloudSavePopup.cs b/Assets/Scripts/UI/Popup/CloudSavePopup.cs new file mode 100644 index 0000000..6d3f98e --- /dev/null +++ b/Assets/Scripts/UI/Popup/CloudSavePopup.cs @@ -0,0 +1,17 @@ +public class CloudSavePopup : PopupBase +{ + public void OnClick_OK() + { + GameManager.DB.SaveDatas(); + GPGSInfo.Ins.SaveGame(GameManager.DB.Get_SaveData(), status => + { + OnClick_Cancel(); + if (status == 0) + GameManager.UI.ShowNStackPopup(EPopupType.CloudSaveCompletePopup); + else + GameManager.UI.ShowNStackPopup(EPopupType.CloudSaveFailPopup); + }); + } + + public void OnClick_Cancel() { GameManager.UI.HideTopPopup(); } +} \ No newline at end of file diff --git a/Assets/Scripts/UI/Popup/CloudSavePopup.cs.meta b/Assets/Scripts/UI/Popup/CloudSavePopup.cs.meta new file mode 100644 index 0000000..8dab6c7 --- /dev/null +++ b/Assets/Scripts/UI/Popup/CloudSavePopup.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 03d765c5d298d664e9a000eb38547051 \ No newline at end of file diff --git a/Assets/Scripts/UI/Popup/SettingPopup.cs b/Assets/Scripts/UI/Popup/SettingPopup.cs index c2fca10..dcb74fb 100644 --- a/Assets/Scripts/UI/Popup/SettingPopup.cs +++ b/Assets/Scripts/UI/Popup/SettingPopup.cs @@ -149,7 +149,7 @@ public class SettingPopup : PopupBase public void ClickSaveButton() { GameManager.Sound.PlaySFX(ESFXType.Button_Hit); - GameManager.DB.SaveDatas(); + GameManager.UI.ShowNStackPopup(EPopupType.CloudSavePopup); //if (GameManager.Account.IsUserLogin == false) //{ @@ -168,6 +168,7 @@ public class SettingPopup : PopupBase public void ClickDataLoadButton() { GameManager.Sound.PlaySFX(ESFXType.Button_Hit); + GameManager.UI.ShowNStackPopup(EPopupType.CloudLoadPopup); //if (GameManager.Account.IsUserLogin == false) //{ diff --git a/Assets/UI/고스톱 수집 목록 스샷.png b/Assets/UI/고스톱 수집 목록 스샷.png deleted file mode 100644 index 5382c2c..0000000 Binary files a/Assets/UI/고스톱 수집 목록 스샷.png and /dev/null differ diff --git a/Assets/UI/고스톱 수집 목록 스샷.png.meta b/Assets/UI/고스톱 수집 목록 스샷.png.meta deleted file mode 100644 index c9749be..0000000 --- a/Assets/UI/고스톱 수집 목록 스샷.png.meta +++ /dev/null @@ -1,156 +0,0 @@ -fileFormatVersion: 2 -guid: 5317e0cd4fb899241b96bb40c6a83b57 -TextureImporter: - internalIDToNameTable: - - first: - 213: 3349175872593865827 - second: "\uACE0\uC2A4\uD1B1 \uC218\uC9D1 \uBAA9\uB85D \uC2A4\uC0F7_0" - externalObjects: {} - serializedVersion: 13 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - flipGreenChannel: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - vTOnly: 0 - ignoreMipmapLimit: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 1 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - 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: 1 - spriteTessellationDetail: -1 - textureType: 8 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - swizzle: 50462976 - cookieLightType: 0 - platformSettings: - - serializedVersion: 4 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 4 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 4 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: - - serializedVersion: 2 - name: "\uACE0\uC2A4\uD1B1 \uC218\uC9D1 \uBAA9\uB85D \uC2A4\uC0F7_0" - rect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1096 - height: 1920 - alignment: 0 - pivot: {x: 0, y: 0} - border: {x: 0, y: 0, z: 0, w: 0} - customData: - outline: [] - physicsShape: [] - tessellationDetail: -1 - bones: [] - spriteID: 36c244026b9aa7e20800000000000000 - internalID: 3349175872593865827 - vertices: [] - indices: - edges: [] - weights: [] - outline: [] - customData: - physicsShape: [] - bones: [] - spriteID: 5e97eb03825dee720800000000000000 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spriteCustomMetadata: - entries: [] - nameFileIdTable: - "\uACE0\uC2A4\uD1B1 \uC218\uC9D1 \uBAA9\uB85D \uC2A4\uC0F7_0": 3349175872593865827 - mipmapLimitGroupName: - pSDRemoveMatte: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/ProjectSettings/AndroidResolverDependencies.xml b/ProjectSettings/AndroidResolverDependencies.xml index 944ba06..4f5fc0b 100644 --- a/ProjectSettings/AndroidResolverDependencies.xml +++ b/ProjectSettings/AndroidResolverDependencies.xml @@ -6,12 +6,15 @@ com.google.android.gms:play-services-ads:23.6.0 com.google.android.gms:play-services-auth:16+ com.google.android.ump:user-messaging-platform:3.1.0 + com.google.games:gpgs-plugin-support:2.1.0 com.google.signin:google-signin-support:1.0.4 com.onestorecorp.sdk:sdk-iap:21.01.00 com.onestorecorp.sdk:sdk-licensing:2.1.0 com.unity3d.ads:unity-ads:4.12.3 + Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.aar + Assets/GeneratedLocalRepo/GooglePlayGames/com.google.play.games/Editor/m2repository/com/google/games/gpgs-plugin-support/2.1.0/gpgs-plugin-support-2.1.0.pom Assets/GeneratedLocalRepo/GoogleSignIn/Editor/m2repository/com/google/signin/google-signin-support/1.0.4/google-signin-support-1.0.4.aar Assets/GeneratedLocalRepo/GoogleSignIn/Editor/m2repository/com/google/signin/google-signin-support/1.0.4/google-signin-support-1.0.4.pom diff --git a/ProjectSettings/GvhProjectSettings.xml b/ProjectSettings/GvhProjectSettings.xml index 88f2c37..801043b 100644 --- a/ProjectSettings/GvhProjectSettings.xml +++ b/ProjectSettings/GvhProjectSettings.xml @@ -1,5 +1,7 @@ + + \ No newline at end of file diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index c641716..7ec1da0 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -140,7 +140,7 @@ PlayerSettings: loadStoreDebugModeEnabled: 0 visionOSBundleVersion: 1.0 tvOSBundleVersion: 1.0 - bundleVersion: 0.0.1 + bundleVersion: 9.9.9 preloadedAssets: [] metroInputSource: 0 wsaTransparentSwapchain: 0 @@ -174,7 +174,7 @@ PlayerSettings: iPhone: 0 tvOS: 0 overrideDefaultApplicationIdentifier: 1 - AndroidBundleVersionCode: 2 + AndroidBundleVersionCode: 3 AndroidMinSdkVersion: 24 AndroidTargetSdkVersion: 35 AndroidPreferredInstallLocation: 1 @@ -269,7 +269,7 @@ PlayerSettings: AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} AndroidKeystoreName: '{inproject}: AndroidData/RandomGFGoStop.keystore' - AndroidKeyaliasName: + AndroidKeyaliasName: fgb AndroidEnableArmv9SecurityFeatures: 0 AndroidEnableArm64MTE: 0 AndroidBuildApkPerCpuArchitecture: 0