void OnReceiptVerificationComplete() { Debug.Log("OnReceiptVerificationComplete"); KongregateAPI kongregate = KongregateAPI.GetAPI(); // we keep a list of transactions here so that we don't run into race conditions Dictionary <string, object> stillInVerification = new Dictionary <string, object> (); foreach (var transactionId in mTransactionsInVerification.Keys) { string status = kongregate.Mtx.ReceiptVerificationStatus(transactionId); if (status != KongregateAPI.RECEIPT_VERIFICATION_STATUS_PROCESSING) { Debug.Log("Verification for " + transactionId + " is " + status); #if UNITY_IPHONE if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { StoreKitTransaction transaction = (StoreKitTransaction)mTransactionsInVerification[transactionId]; KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, transactionId, getPurchaseFields()); // Below is an alternative iOS FinishPurchase() call. This version may be used if your plugin // does not make the transaction Id available or finishes the transaction before passing control // back to Unity. FinishPurchase() is preferred because purchase details may be pulled directly from // the transaction. // KongregateAPI.GetAPI().Analytics.FinishPurchaseWithProductId(KongregateAPI.PURCHASE_SUCCESS, // transaction.productIdentifier, transaction.base64EncodedTransactionReceipt, getPurchaseFields()); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, transactionId, getPurchaseFields()); } // call to finish the transaction regardless of it we are valid or not StoreKitBinding.finishPendingTransaction(transactionId); #elif UNITY_ANDROID GooglePurchase transaction = (GooglePurchase)mTransactionsInVerification [transactionId]; if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, transaction.originalJson, getPurchaseFields(), transaction.signature); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, transaction.originalJson, getPurchaseFields()); } // call to finish transaction regardless of it we are valid or not GoogleIAB.consumeProduct(transaction.productId); #endif mPurchaseReady = true; } else { Debug.Log("Still waiting on verification for " + transactionId); stillInVerification [transactionId] = mTransactionsInVerification [transactionId]; } } mTransactionsInVerification = stillInVerification; }
/** * Handle the KONGREGATE_EVENT_SWRVE_RESOURCES_UPDATES update which is fired by the Swrve SDK when * resources setup for A/B testing are ready to be loaded. */ void OnSwrveResourcesUpdated() { // A handful of accessors are supported to retrieve resources and values Debug.Log("Got Swrve resources: " + KongregateAPI.GetAPI().Analytics.GetResourceNames()); Debug.Log("abtest string value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsString("test_resource", "string_attr", "n/a")); Debug.Log(" abtest int value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsInt("test_resource", "int_attr", 0)); Debug.Log(" abtest float value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsFloat("test_resource", "float_attr", 0)); Debug.Log(" abtest bool value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsBool("test_resource", "bool_attr", false)); }
// Demonstrate how to retrieve Swrve resources void DemoSwrveResources() { // the following resources should be configured in teh Swrve dashboard Debug.Log("Got Swrve resources: " + KongregateAPI.GetAPI().Analytics.GetResourceNames()); Debug.Log("abtest string value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsString("test_resource", "string_attr", "n/a")); Debug.Log(" abtest int value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsInt("test_resource", "int_attr", 0)); Debug.Log(" abtest float value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsFloat("test_resource", "float_attr", 0)); Debug.Log(" abtest bool value: " + KongregateAPI.GetAPI().Analytics.GetResourceAsBool("test_resource", "bool_attr", false)); }
// Use this for initialization void Start() { KongregateManager.eventUserChanged += OnUserChanged; KongregateManager.eventGameAuthChanged += OnGameAuthChanged; KongregateManager.eventUserInventory += OnUserInventory; KongregateManager.eventReady += () => { // request the user's items KongregateAPI.GetAPI().Mtx.RequestUserItemList(); }; }
void OnGUI() { KongregateAPI kongregate = KongregateAPI.GetAPI(); if (!kongregate.IsReady()) { // don't display purchase UI until Kongregate is ready return; } KongDemoHelper.PrepareGUI(); // if our button is not hidden, we need to draw it Rect kButtonRect = new Rect(10, 10, 100, 100); // draw the K button if (GUI.Button(kButtonRect, _kongButtonTexture)) { Debug.Log("You clicked the Kong button!"); kongregate.Mobile.OpenKongregateWindow(); } if (_notificationCountTexture) { GUI.Label(new Rect(90, 20, 50, 50), _notificationCountTexture, KongDemoHelper.labelStyle); } // add buttons for the deep links Rect deepLinkButtonsRect = new Rect(kButtonRect.x, kButtonRect.x + kButtonRect.height + 20, 300, 200); Rect targetIdLabelRect = new Rect(deepLinkButtonsRect.x, deepLinkButtonsRect.y + deepLinkButtonsRect.height + 20, 100, 50); Rect targetIdTextRect = new Rect(targetIdLabelRect.x + targetIdLabelRect.width, targetIdLabelRect.y, 100, 50); GUI.Label(targetIdLabelRect, "TargetId:", KongDemoHelper.labelStyle); _targetIdText = GUI.TextField(targetIdTextRect, _targetIdText, KongDemoHelper.textFieldStyle); int deepLinkClick = GUI.SelectionGrid(deepLinkButtonsRect, -1, _deepLinkTargets, 2, KongDemoHelper.buttonStyle); if (deepLinkClick >= 0) { KongregateAPI.GetAPI().Mobile.OpenKongregateWindow(_deepLinkTargets [deepLinkClick], _targetIdText); } // add guild chat button Rect guildChatRect = new Rect(kButtonRect.x + kButtonRect.width + 20, kButtonRect.y + 20, 200, 50); GUIStyle guildChatStyle = new GUIStyle(KongDemoHelper.buttonStyle); if (_unreadGuildChat) { guildChatStyle.fontStyle = FontStyle.Bold; guildChatStyle.normal.textColor = Color.red; } if (GUI.Button(guildChatRect, "Guild Chat", guildChatStyle)) { KongregateAPI.GetAPI().Mobile.OpenKongregateWindow(Mobile.TARGET_GUILD_CHAT); } }
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { // A consumable product has been purchased by this user. if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal)) { Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));//If the consumable item has been successfully purchased, add 100 coins to the player's in-game score. // The code below demonstrates how to use Kongregate's Receipt Validation // API. Only do this step if you're server does not have it's own receipt validation. // See OnReceiptVerificationComplete() for what to do after the receipt is validated // either on your server or through our API. #if UNITY_ANDROID // parse the receipt json, orderID and data signature Dictionary <string, object> receipt = Json.Deserialize(args.purchasedProduct.receipt) as Dictionary <string, object>; Dictionary <string, object> payload = Json.Deserialize(receipt["Payload"] as string) as Dictionary <string, object>; Dictionary <string, object> json = Kongregate.Json.Deserialize(payload["json"] as string) as Dictionary <string, object>; string googleReceiptJSON = payload["json"] as string; string googleSignature = payload["signature"] as string; string orderId = json.ContainsKey("orderId") ? json["orderId"] as string : string.Empty; // for Android we key the purchase using the orderID which is later used to retrieve // the verification status. mPendingPurchases[orderId] = args.purchasedProduct; // ...and start the receipt validation request. KongregateAPI.GetAPI().Mtx.VerifyGoogleReceipt(googleReceiptJSON, googleSignature); #elif UNITY_IPHONE // for iOS we key purchases on the the transactionID which is later used to retrieve // verification status mPendingPurchases[args.purchasedProduct.transactionID] = args.purchasedProduct; // for iOS, simply pass the transaction ID to our API KongregateAPI.GetAPI().Mtx.VerifyTransactionId(args.purchasedProduct.transactionID); #endif // return pending so the transaction is not completed until after we validate the receipt return(PurchaseProcessingResult.Pending); } else { Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id)); KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, "Unrecognized product", new Dictionary <string, object>() { { "type", "Gold Pack" } }); // return complete to finish the transaction return(PurchaseProcessingResult.Complete); } }
void BuyProductID(string productId) { Dictionary <string, object> purchaseFields = new Dictionary <string, object>() { { "type", "Gold Pack" } }; // If the stores throw an unexpected exception, use try..catch to protect my logic here. try { // If Purchasing has been initialized ... if (IsInitialized()) { // ... look up the Product reference with the general product identifier and the Purchasing system's products collection. Product product = mStoreController.products.WithID(productId); // If the look up found a product for this device's store and that product is ready to be sold ... if (product != null && product.availableToPurchase) { // Notify Kongregate a purchase is starting KongregateAPI.GetAPI().Analytics.StartPurchase(product.definition.storeSpecificId, 1, purchaseFields); Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.storeSpecificId));// ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed asynchronously. mStoreController.InitiatePurchase(product); } // Otherwise ... else { // ... report the product look-up failure situation Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, "product not found or available", purchaseFields); } } // Otherwise ... else { // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or retrying initiailization. Debug.Log("BuyProductID FAIL. Not initialized."); KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, "purchasing not initialized", purchaseFields); } } // Complete the unexpected exception handling ... catch (Exception e) { // ... by reporting any unexpected exception for later diagnosis. Debug.Log("BuyProductID: FAIL. Exception during purchase. " + e); KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, e.Message, purchaseFields); } }
void SetupAnalyticsCallbacks() { // The following listeners can only be set after Initialize is invoked, though it is not necessary // to wait for the ready event. KongregateAPI kongregate = KongregateAPI.GetAPI(); // Set the callback that will include fields sent with all events kongregate.Analytics.SetCommonPropsCallback(CommonPropsCallback); // NOTE: if deferred analytics is enabled, you may only SetSwrveButtonListener after Analytics.Start() // is invoked kongregate.Analytics.SetSwrveButtonListener(gameObject.name, "HandleSwrveAction"); }
// Demonstrates how to update game user data in SWRVE. void DemoUpdateGameUserData() { // you may specify game user data as either a dictonary of string values Dictionary <string, object> gameUserProps = new Dictionary <string, object>() { { "user_prop_1", "one" }, { "user_prop_2", "two" } }; KongregateAPI.GetAPI().Analytics.GameUserUpdate(gameUserProps); // or a json string KongregateAPI.GetAPI().Analytics.GameUserUpdate("{ \"json_prop_1\" : \"json_value_1\", \"json_prop_2\" : \"json_value_2\" }"); }
// Use this for initialization void Awake() { KongregateAPI kongregate = KongregateAPI.GetAPI(); if (kongregate != null) { SetupAnalyticsCallbacks(); } else { KongregateManager.eventInitializing += SetupAnalyticsCallbacks; } KongregateManager.eventSwrveResourceUpdate += OnSwrveResourcesUpdated; }
} // OnGUI void UpdateNotificationCount() { // Draw the notification icon, if needed. Not currently supported by native rendering int notificationCount = KongregateAPI.GetAPI().Services.GetNotificationCount(); if (notificationCount > 0) { mNotificationCountTexture = (Texture2D)Resources.Load("Kongregate/notification_" + Math.Min(notificationCount, 9), typeof(Texture2D)); } else { mNotificationCountTexture = null; } Debug.Log("has unread guild messages: " + KongregateAPI.GetAPI().Services.HasUnreadGuildMessages()); }
void OnGUI() { KongregateAPI kongregate = KongregateAPI.GetAPI(); if (!kongregate.IsReady()) { // don't display purchase UI until Kongregate is ready return; } KongDemoHelper.PrepareGUI(); if (GUI.Button(new Rect(1280 / 2 - 150, 150, 300, 40), "Send Custom play_ends Events", KongDemoHelper.buttonStyle)) { SendCustomEvents(); } }
void OnUserChanged() { Debug.Log("OnUserChange"); // update user details KongregateAPI kongregate = KongregateAPI.GetAPI(); if (kongregate.Services.IsGuest()) { _username = "******"; } else { _username = kongregate.Services.GetUsername(); } _userId = kongregate.Services.GetUserId(); _hasPlus = kongregate.Services.HasKongPlus(); }
void SetupPurchases() { Debug.Log("KongStoreKitDemo: Setting up purchases..."); #if UNITY_IPHONE Debug.Log("KongStoreKitDemo: requesting products"); StoreKitBinding.requestProductData(new string[] { "com.kongregate.mobile.games.angryBots.t05_coins" }); #elif UNITY_ANDROID GoogleIABManager.billingSupportedEvent += () => { Debug.Log("KongStoreKitDemo: billing is supported query inventory"); mPurchaseReady = true; var skus = new string[] { "com.kongregate.android.games.angrybots.t03_hard" }; GoogleIAB.queryInventory(skus); }; GoogleIABManager.queryInventorySucceededEvent += (purchases, skus) => { Debug.Log("KongStoreKitDemo: queryInventory succeeded"); foreach (GooglePurchase purchase in purchases) { Debug.Log("KongStoreKitDemo: queryInventory succeeded: " + purchase.productId); verifyGoogleReceipt(purchase); } }; GoogleIABManager.queryInventoryFailedEvent += (sku) => { Debug.Log("KongStoreKitDemo: queryInventoryFailedEvent: " + sku); }; GoogleIABManager.purchaseSucceededEvent += purchase => { Debug.Log("Google IAB callback - purchased product: " + purchase); verifyGoogleReceipt(purchase); }; GoogleIABManager.purchaseFailedEvent += message => { Debug.Log("Google IAB callback - purchase failed: " + message); KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, message, getPurchaseFields()); mPurchaseReady = true; }; GoogleIABManager.consumePurchaseSucceededEvent += purchase => { Debug.Log("KongStoreKitDemo: Google IAB callback - consume succeeded: " + purchase); }; GoogleIABManager.consumePurchaseFailedEvent += message => { Debug.Log("Google IAB callback - consume failed: " + message); }; GoogleIAB.init(_GooglePublicKey); #elif UNITY_WEBPLAYER || UNITY_WEBGL mPurchaseReady = true; #endif }
void OnGUI() { if (!KongregateAPI.GetAPI().IsReady()) { // don't display purchase UI until Kongregate is ready return; } // Present a simple GUI to purchase an item KongDemoHelper.PrepareGUI(); if (IsInitialized()) { if (GUI.Button(new Rect(1280 / 2 - 55, 100, 150, 40), "Unity Purchase", KongDemoHelper.buttonStyle)) { BuyConsumable(); } } }
// Use this for initialization void Start() { ConfigureStoreKitManager(); KongregateManager.eventReady += delegate() { SetupPurchases(); if (mTransactionsInVerification.Count > 0) { // verify any transactions that were finished before the SDK finished initializing foreach (var transactionId in mTransactionsInVerification.Keys) { Debug.Log("KongStoreKitDemo:: verifying pending transactions: " + transactionId); KongregateAPI.GetAPI().Mtx.VerifyTransactionId(transactionId); } } }; KongregateManager.eventReceiptVerificationComplete += OnReceiptVerificationComplete; }
void OnGUI() { KongregateAPI kongregate = KongregateAPI.GetAPI(); if (!kongregate.IsReady()) { // don't display purchase UI until Kongregate is ready return; } KongDemoHelper.PrepareGUI(); if (mPurchaseReady) { if (GUI.Button(new Rect(1280 / 2 - 100, 50, 240, 80), "P31 Purchase", KongDemoHelper.buttonStyle)) { StartPurchase(); } } }
// Update is called once per frame void OnGUI() { KongDemoHelper.PrepareGUI(); KongregateAPI kongregate = KongregateAPI.GetAPI(); GUI.Label(new Rect(1000, 10, 200, 20), _username + (_hasPlus ? " (K+)" : "") + " (" + _userId + ")", KongDemoHelper.labelStyle); if (GUI.Button(new Rect(1080, 40, 100, 40), "Inventory", KongDemoHelper.buttonStyle)) { _inventory = false; kongregate.Mtx.RequestUserItemList(); } if (_inventory) { GUI.Label(new Rect(1000, 120, 250, 80), "Has AWESOME GUN: " + _hasGun, KongDemoHelper.labelStyle); } else { GUI.Label(new Rect(1000, 120, 250, 80), "Requesting inventory...", KongDemoHelper.labelStyle); } // a simple button to demonstrate submitting stats if (GUI.Button(new Rect(Screen.width - 200, 150, 150, 40), "Submit Win", KongDemoHelper.buttonStyle)) { kongregate.Stats.Submit("Wins", 1); } GUI.Label(new Rect(1000, 220, 50, 40), "Stat:", KongDemoHelper.labelStyle); _statId = GUI.TextField(new Rect(1120, 200, 80, 40), _statId); GUI.Label(new Rect(1000, 260, 100, 40), "Value:", KongDemoHelper.labelStyle); _statValue = GUI.TextField(new Rect(1120, 250, 80, 40), _statValue); if (GUI.Button(new Rect(1120, 300, 80, 40), "Submit", KongDemoHelper.buttonStyle)) { long value = 0; if (long.TryParse(_statValue, out value)) { kongregate.Stats.Submit(_statId, long.Parse(_statValue)); } } }
/** * Initialize the Kongregate SDK if it isn't already initialized. */ void InitializeKongregate() { Debug.Log("KongregateManager.InitializeKongregate"); if (KongregateAPI.GetAPI() != null) { Debug.Log("KongregateAPI already initialized"); return; } ConfigureAPISettings(); KongregateAPI kongregate = KongregateAPI.Initialize(kongregateGameID, kongregateAPIKey); if (eventInitializing != null) { // not an official Kongregate API event, but used here to notify other components that initialize // has been invoked. eventInitializing(); } kongregate.SetEventBundleListener(gameObject, HandleKongregateEvent); }
void SendCustomEvents() { KongregateAPI kongregate = KongregateAPI.GetAPI(); // Send a custom event. Event will be sent through Swrve as Kongregate.RawData.play_ends and // extracted through Kongregate's ETL system. Since the event is also sent to Swrve, it may // also be used for Swrve features such as in-app messages and A/B tests. Dictionary <string, object> eventMap = new Dictionary <string, object>() { { "play_id", "550e8400-e29b-41d4-a716-446655440000" }, { "pve_energy_used", 24 }, { "is_pvp", true }, { "resources_change", new string[] { "cards +1", "PvE energy +20" } }, }; kongregate.Analytics.AddEvent("play_ends", eventMap); // Sends a custom event to Swrve only. It will not go through Kongregate ETL, but may be used // for Swrve features such as in-app messages and A/B tests. Dictionary <string, object> swrveEventMap = new Dictionary <string, object>() { { "play_time", 60 }, { "mode", "Mission" } }; kongregate.Analytics.AddEvent("swrve.game_over", swrveEventMap); // Update Swrve user properties which may be used to create user segments to // target A/B tests, in-app messages, and Push Notifications. The Kongregate SDK // automatically updates a set of user properties, you may use this method to add // additional custom user properties. Dictionary <string, object> customUserProps = new Dictionary <string, object> { { "level", 4 }, { "type", "theif" } }; kongregate.Analytics.GameUserUpdate(customUserProps); }
void OnApplicationPause(bool pausing) { Debug.Log("OnApplicationPause: " + pausing); KongregateAPI kongregate = KongregateAPI.GetAPI(); if (pausing) { kongregate.OnPause(); } else { kongregate.OnResume(); if (mKongregateWindowOpen) { #if UNITY_IPHONE // Android closes the panel when the app goes to the background, so iOS only. Debug.Log("Kongregate Panel is still open, game should remain paused"); Time.timeScale = 0; AudioListener.pause = true; #endif } } }
void StartPurchase() { mPurchaseReady = false; // disable button when clicked KongregateAPI kongregate = KongregateAPI.GetAPI(); Dictionary <string, object> fields = new Dictionary <string, object> () { { "type", "Gold Pack" }, { "discount_percent", 12.5 }, { "context_of_offer", "StoreFront" } }; #if UNITY_IPHONE kongregate.Analytics.StartPurchase("com.kongregate.mobile.games.angryBots.t05_coins", 1, fields); StoreKitBinding.purchaseProduct("com.kongregate.mobile.games.angryBots.t05_coins", 1); #elif UNITY_ANDROID kongregate.Analytics.StartPurchase("com.kongregate.android.games.angrybots.t03_hard", 1, fields); GoogleIAB.purchaseProduct("com.kongregate.android.games.angrybots.t03_hard"); #elif UNITY_WEBPLAYER || UNITY_WEBGL kongregate.Analytics.StartPurchase("com.kongregate.web.angrybots.t05_hard", 1, fields); // Use the Javascript API to initiate the purchase. Notice in this flow we call finishPurchase via // the Javascript API after the purchase is completed by serializing the game fields needed. You // could also save the game fields into a variable in your Unity script and then call // kongregate.Analytics.FinishPurchase(...) in the Unity callback as well. Application.ExternalEval(string.Format( @"kongregate.mtx.purchaseItems(['com.kongregate.web.angrybots.t05_hard'], function(result){{ var status = result.success ? 'SUCCESS' : 'FAIL'; var data = result.success ? '{0}' : '{1}'; kongregate.analytics.finishPurchase(status, result.purchase_id, data); // Fire the callback in the Unity code kongregateUnitySupport.getUnityObject().SendMessage('Kongregate', 'OnKredPurchaseResult', status); }});" , Analytics.toAnalyticEventJSON(getPurchaseFields()), Analytics.toAnalyticEventJSON(fields))); #endif }
void OnUserInventory() { _inventory = true; _hasGun = KongregateAPI.GetAPI().Mtx.HasItem("promo-gun"); Debug.Log("Kongregate inventory received, has gun: " + _hasGun); }
void verifyGoogleReceipt(GooglePurchase purchase) { mTransactionsInVerification [purchase.orderId != null ? purchase.orderId : string.Empty] = purchase; KongregateAPI.GetAPI().Mtx.VerifyGoogleReceipt(purchase.originalJson, purchase.signature); }
// Demonstarte how to handle Kongregate Events void HandleKongregateEvent(string eventName) { Debug.Log("HandleKongregateEvent: " + eventName); KongregateAPI kongregate = KongregateAPI.GetAPI(); switch (eventName) { case KongregateAPI.KONGREGATE_EVENT_READY: // Kongregate API is ready to go // You may now access the current Kongregate User, submit stats, etc. // You may also check to see if the game auth token is available. If this is the first time // the user lauched your game, they may not have an AuthToken yet. A // KONGEGATE_EVENT_GAME_AUTH_CHANGED will follow (if they have an internet connection). You only // need the Game Auth Token, if you plan to perform server-side verification. Debug.Log("Kongregate API is ready"); Debug.Log("Kongregate Auto props as JSON: " + kongregate.Analytics.GetAutoPropertiesJSON()); UpdateNotificationCount(); // If you're implementing guild chat, you can update your character token at this time // if it is available: // kongregate.Services.SetCharacterToken("server-generated-token"); DemoRequestUserItems(); DemoUpdateGameUserData(); Debug.Log("app opened using deep link: " + kongregate.Mobile.GetOpenURL()); break; case KongregateAPI.KONGREGATE_EVENT_USER_CHANGED: // this could be one of: // 1) user was a guest and then logged in/registered // 2) user was logged in and then logged out and is now guest // 3) user was logged in and then logged out and is now a different user // Note that the user id will come back for Guests as well. To check for a // guest, use the IsGuest() method. // if you are also concerned about the Auth Token, you should instead listen // for KONGREGATE_EVENT_USER_AUTH_CHANGED as it is a superset of this event mUserId = kongregate.Services.GetUserId(); mUsername = kongregate.Services.GetUsername(); mGuest = kongregate.Services.IsGuest(); mHasKongPlus = kongregate.Services.HasKongPlus(); Debug.Log("user " + mUserId + " " + (mGuest ? "is" : "is not") + " a guest"); DemoRequestUserItems(); break; case KongregateAPI.KONGREGATE_EVENT_GAME_AUTH_CHANGED: // User's game auth token has changed, either by way of login, logout, or if their password changes. // This event will always follow KONGREGATE_EVENT_USER_CHANGED (if they have intenet access). // Note that Guests will also have an Auth Token and will cause this to event to fire as well. // Guest token is the same for all Guests. you can check if the user is a Guest using the // isGuest() method. Their is no need to perform server-side verification for the Guests token. // If you want to listen for a single event that covers all the scenarios of a user change or // an auth token change, this is the event to listen for mUserId = kongregate.Services.GetUserId(); mAuthToken = kongregate.Services.GetGameAuthToken(); mGuest = kongregate.Services.IsGuest(); Debug.Log("user " + mUserId + " " + (mGuest ? "is" : "is not") + " a guest"); Debug.Log("game auth has changed to:" + mAuthToken); break; case KongregateAPI.KONGREGATE_EVENT_OPEN_DEEP_LINK: Debug.Log("app opened using deep link: " + kongregate.Mobile.GetOpenURL()); break; case KongregateAPI.KONGREGATE_EVENT_OPENING: // Kongregate Window is opening Debug.Log("Kongregate Window is opening - pausing logic and sound"); mKongregateWindowOpen = true; #if UNITY_IPHONE // Android closes the panel when the app goes to the background, so iOS only. Time.timeScale = 0; AudioListener.pause = true; #endif break; case KongregateAPI.KONGREGATE_EVENT_CLOSED: // Kongregate Window is clsoed Debug.Log("Kongregate Window is closed - resuming logic and sound"); mKongregateWindowOpen = false; #if UNITY_IPHONE // Android closes the panel when the app goes to the background, so iOS only. Time.timeScale = 1; AudioListener.pause = false; #endif break; case KongregateAPI.KONGREGATE_EVENT_USER_INVENTORY: // User inventory is now available, we can call hasItem to check for promotional items mInventory = true; DemoGetUserItems(); break; case KongregateAPI.KONGREGATE_EVENT_SERVICE_UNAVAILABLE: // A request to Kongregate failed. This will typically occur when the user does not // have a network connection or Kongregate is experiencing a scheduled downtime. Requests // will be stored locally until the service becomes available again. Game clients // should only need to handle this event if they require server side auth, // do not have a game auth token yet, and wish to message to the user that they are unable // to validate them. Debug.Log("Kongregate Service Unavailable"); break; case KongregateAPI.KONGREGATE_EVENT_RECEIPT_VERIFICATION_COMPLETE: // A purchase receipt has been verified, we can now check the result for our transaction Debug.Log("A receipt has finished verification"); // we keep a list of transactions here so that we don't run into race conditions Dictionary <string, object> stillInVerification = new Dictionary <string, object>(); foreach (var transactionId in mTransactionsInVerification.Keys) { string status = kongregate.Mtx.ReceiptVerificationStatus(transactionId); if (status != KongregateAPI.RECEIPT_VERIFICATION_STATUS_PROCESSING) { Debug.Log("Verification for " + transactionId + " is " + status); #if UNITY_IPHONE && PRIME31_STOREKIT if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { StoreKitTransaction transaction = (StoreKitTransaction)mTransactionsInVerification[transactionId]; KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, transactionId, getPurchaseFields()); // Below is an alternative iOS FinishPurchase() call. This version may be used if your plugin // does not make the transaction Id available or finishes the transaction before passing control // back to Unity. FinishPurchase() is preferred because purchase details may be pulled directly from // the transaction. // KongregateAPI.GetAPI().Analytics.FinishPurchaseWithProductId(KongregateAPI.PURCHASE_SUCCESS, // transaction.productIdentifier, transaction.base64EncodedTransactionReceipt, getPurchaseFields()); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, transactionId, getPurchaseFields()); } // call to finish the transaction regardless of it we are valid or not StoreKitBinding.finishPendingTransaction(transactionId); #elif UNITY_ANDROID && PRIME31_STOREKIT GooglePurchase transaction = (GooglePurchase)mTransactionsInVerification[transactionId]; if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, transaction.originalJson, getPurchaseFields(), transaction.signature); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, transaction.originalJson, getPurchaseFields()); } // call to finish transaction regardless of it we are valid or not GoogleIAB.consumeProduct(transaction.productId); #endif mPurchaseReady = true; } else { Debug.Log("Still waiting on verification for " + transactionId); stillInVerification[transactionId] = mTransactionsInVerification[transactionId]; } } mTransactionsInVerification = stillInVerification; break; case KongregateAPI.KONGREGATE_EVENT_SWRVE_RESOURCES_UPDATES: DemoSwrveResources(); break; case KongregateAPI.KONGREGATE_EVENT_NOTIFICATION_COUNT_UPDATED: Debug.Log("notification count updated: " + kongregate.Services.GetNotificationCount()); UpdateNotificationCount(); break; } // the following should be called to let the API know processing is complete // this is particularly important for when pausing the game via iOS (default) kongregate.MessageReceived(eventName); }
// Demostrate how to retreive User items after KONGREGATE_EVENT_USER_INVENTORY is retrieved void DemoGetUserItems() { mHasGun = KongregateAPI.GetAPI().Mtx.HasItem("promo-gun"); Debug.Log("Kongregate inventory received, has gun: " + mHasGun); }
/** * Handle the KongregateAPI.KONGREGATE_EVENT_RECEIPT_VERIFICATION_COMPLETE event. */ void OnReceiptVerificationComplete() { Debug.Log("OnReceiptVerificationComplete"); // dummy purchase field values to pass to the Kongregate SDK. replace // these with any non-auto fields from your schema for the // iap_transactions/iap_fails events. Dictionary <string, object> purchaseFields = new Dictionary <string, object> () { { "hard_currency_change", 5 }, { "soft_currency_change", 10 }, { "type", "Gold Pack" } }; // Iterate over the list of pending transactions and resolve any that have // completed receipt validation. Dictionary <string, Product> stillInVerification = new Dictionary <string, Product> (); foreach (string transactionId in mPendingPurchases.Keys) { string status = KongregateAPI.GetAPI().Mtx.ReceiptVerificationStatus(transactionId); if (status != KongregateAPI.RECEIPT_VERIFICATION_STATUS_PROCESSING) { Debug.Log("Verification for " + transactionId + " is " + status); Product purchasedProduct = mPendingPurchases[transactionId]; string fullReceipt = purchasedProduct.receipt; #if UNITY_ANDROID // Parse the Google receipt to pass to the Kongregate API Dictionary <string, object> receipt = Json.Deserialize(fullReceipt) as Dictionary <string, object>; Dictionary <string, object> payload = Json.Deserialize(receipt["Payload"] as string) as Dictionary <string, object>; string googleReceiptJSON = payload["json"] as string; string googleSignature = payload["signature"] as string; if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, googleReceiptJSON, purchaseFields, googleSignature); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, googleReceiptJSON, purchaseFields); } #elif UNITY_IPHONE // For iOS we simply need the transactionId if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_VALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_SUCCESS, transactionId, purchaseFields); } else if (status == KongregateAPI.RECEIPT_VERIFICATION_STATUS_INVALID) { KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_RECEIPT_FAIL, transactionId, purchaseFields); } #endif // Notify the Unity Purchasing API to finish/consume the purchase mStoreController.ConfirmPendingPurchase(purchasedProduct); } else { Debug.Log("Still waiting on verification for " + transactionId); stillInVerification[transactionId] = mPendingPurchases[transactionId]; } } mPendingPurchases = stillInVerification; }
void OnGameAuthChanged() { // use the auth token to valid the user using our REST API _gameAuthToken = KongregateAPI.GetAPI().Services.GetGameAuthToken(); Debug.Log("OnGameAuthToken: " + _gameAuthToken); }
void ConfigureStoreKitManager() { //queue of transactions needing to be verified mTransactionsInVerification = new Dictionary <string, object> (); #if UNITY_IPHONE //don't autoconfirm transactions until we have verified the receipt StoreKitBinding.enableHighDetailLogs(true); StoreKitManager.autoConfirmTransactions = false; StoreKitBinding.setShouldSendTransactionUpdateEvents(true); StoreKitManager.productListReceivedEvent += allProducts => { Debug.Log("KongStoreKitDemo:: received total products: " + allProducts.Count); mPurchaseReady = true; }; // the following handles receipt verification StoreKitManager.productPurchaseAwaitingConfirmationEvent += transaction => { Debug.Log("KongStoreKitDemo: productPurchaseAwaitingConfirmationEvent: " + transaction.transactionState); mTransactionsInVerification[transaction.transactionIdentifier] = transaction; //add this transaction to the queue if (KongregateAPI.GetAPI() != null && KongregateAPI.GetAPI().IsReady()) { Debug.Log("KongStoreKitDemo: verifiying: " + transaction); KongregateAPI.GetAPI().Mtx.VerifyTransactionId(transaction.transactionIdentifier); } else { Debug.Log("KongStoreKitDemo: delay verify until READY event: " + transaction); } }; StoreKitManager.restoreTransactionsFailedEvent += errorMsg => { Debug.Log("KongStoreKitDemo: restoreTransactionsFailedEvent: " + errorMsg); }; StoreKitManager.restoreTransactionsFinishedEvent += () => { Debug.Log("KongStoreKitDemo: restoreTransactionsFinishedEvent"); }; StoreKitManager.purchaseSuccessfulEvent += transaction => { Debug.Log("KongStoreKitDemo: purchaseSuccessfulEvent: " + transaction.transactionIdentifier); }; StoreKitManager.purchaseFailedEvent += errorMsg => { Debug.Log("KongStoreKitDemo: purchase failed: " + errorMsg); // pass null, if you do not have the transaction id. KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, null, getPurchaseFields()); mPurchaseReady = true; }; StoreKitManager.purchaseCancelledEvent += errorMsg => { Debug.Log("KongStoreKitDemo: purchase cancelled: " + errorMsg); // pass null, if you do not have the transaction id. KongregateAPI.GetAPI().Analytics.FinishPurchase(KongregateAPI.PURCHASE_FAIL, null, getPurchaseFields()); mPurchaseReady = true; }; StoreKitManager.transactionUpdatedEvent += transaction => { Debug.Log("KongStoreKitDemo: transactionUpdated: " + transaction.transactionState); }; Debug.Log("KongStoreKitDemo: listeners configured"); #endif }
// Demonstrate how to request the user items void DemoRequestUserItems() { KongregateAPI.GetAPI().Mtx.RequestUserItemList(); }