예제 #1
0
 /// <summary>
 /// Sets an item to 'deselected' in the database.
 /// </summary>
 public static void SetToDeselected(IAPItem item)
 {
     //pass argument to DBManager and invoke deselect event
     DBManager.SetDeselected(item.productId);
     if (itemDeselectedEvent != null)
     {
         itemDeselectedEvent(item.productId);
     }
 }
예제 #2
0
        /// <summary>
        /// Sets an item to 'selected' in the database.
        /// </summary>
        public static void SetToSelected(IAPItem item)
        {
            //check if the item allows for single or multi selection,
            //this depends on whether the item has a deselect button
            bool single = item.deselectButton ? false : true;
            //pass arguments to DBManager and invoke select event
            bool changed = DBManager.SetSelected(item.productId, single);

            if (changed && itemSelectedEvent != null)
            {
                itemSelectedEvent(item.productId);
            }
        }
        /// <summary>
        /// Unlocks items if the requirement for them has been met. You can
        /// call this method at runtime whenever the player made some
        /// progress, to ensure your shop items reflect the current state.
        /// </summary>
        public static void UnlockItems()
        {
            //this method is based on data from the database,
            //so if we don't have a DBManager instance don't continue
            if (!DBManager.GetInstance())
            {
                return;
            }

            //get list of all shop groups from IAPManager
            List <IAPGroup> list = IAPManager.GetInstance().IAPs;

            //loop over groups
            for (int i = 0; i < list.Count; i++)
            {
                //cache current group
                IAPGroup group = list[i];

                //loop over items
                for (int j = 0; j < group.items.Count; j++)
                {
                    //cache IAP object
                    IAPObject obj = group.items[j];
                    if (obj.req == null)
                    {
                        continue;
                    }

                    //cache reference to IAP item instance
                    IAPItem item = GetIAPItem(obj.id);

                    //check if the item reference is empty or set to purchased already
                    if (item == null || DBManager.isPurchased(obj.id))
                    {
                        continue;
                    }

                    //check if a requirement is set up for this item,
                    //then unlock if the requirement has been met
                    if (!string.IsNullOrEmpty(obj.req.entry) &&
                        DBManager.isRequirementMet(obj.req))
                    {
                        if (IAPManager.isDebug)
                        {
                            Debug.Log("requirement met for: " + obj.id);
                        }
                        item.Unlock();
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Refreshes the visual representation of a specific shop item.
        /// This is called automatically because of subscribing to the DBManager update event.
        /// It also means saving performance due to not refreshing all items every time.
        /// </summary>
        public void Refresh(string id)
        {
            //this method is based on data from the database,
            //so if we don't have a DBManager instance don't continue
            if (!DBManager.GetInstance())
            {
                return;
            }

            IAPObject obj  = IAPManager.GetIAPObject(id);
            IAPItem   item = instance.IAPItems.ContainsKey(id) ? instance.IAPItems[id] : null;

            if (obj == null || item == null || item.productId != id)
            {
                return;
            }

            bool isSelected  = DBManager.GetSelected(id);
            bool isPurchased = DBManager.GetPurchase(id) > 0;

            //double check that selected items are actually owned
            //if not, correct the entry by setting it to deselected
            if (isSelected && !isPurchased)
            {
                DBManager.SetDeselected(id);
                isSelected = false;
            }

            if (isPurchased)
            {
                item.Purchased(true);

                //in case the item has been selected before, but also auto-select one item per group
                //more items per group can be pre-selected manually e.g. on app launch
                if (isSelected || (item.selectButton && !item.deselectButton &&
                                   DBManager.GetSelectedGroup(IAPManager.GetIAPObjectGroupName(id)).Count == 0))
                {
                    item.IsSelected(true);
                }
            }
            else if (!string.IsNullOrEmpty(obj.req.entry) && DBManager.isRequirementMet(obj.req))
            {
                //check if a requirement is set up for this item,
                //then unlock if the requirement has been met
                if (IAPManager.isDebug)
                {
                    Debug.Log("requirement met for: " + obj.id);
                }
                item.Unlock();
            }
        }
예제 #5
0
        // check for purchases on online servers at billing initialization.
        // If a purchase is not registered, set local purchase state back to false
        private void VerifyReceipts()
        {
            //get list of old purchases: on iOS the saved transactions,
            //on Android we use the old purchases list received from Google
            if (inventory == null || inventory.GetAllPurchases().Count == 0)
            {
                return;
            }

            //loop over all IAP items to check if a valid receipt exists
            for (int i = 0; i < ids.Length; i++)
            {
                //cache IAP id,
                //only verify purchased items
                string localId  = ids[i];
                string globalId = GetIAPIdentifier(localId);
                if (DBManager.isPurchased(globalId))
                {
                    //initialize item as faked and loop over receipts
                    bool     faked   = true;
                    Purchase receipt = inventory.GetPurchase(localId);

                    if (receipt != null)
                    {
                        //we found a receipt for this product on the device,
                        //unset fake purchase and let our external
                        //server decide what happens with this transaction
                        faked = false;
                        MakeRequest(receipt);
                        break;
                    }

                    //we haven't found a receipt for this item, yet it is
                    //set to purchased. This can't be, maybe our external server
                    //response or the database has been hacked with fake data
                    if (faked)
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(globalId);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(globalId);
                    }
                }
            }
        }
예제 #6
0
 /// <summary>
 /// sets an item to 'selected' in the database
 /// </summary>
 public static void SetToSelected(IAPItem item)
 {
     //check if the item allows for single or multi selection,
     //this depends on whether the item has a deselect button
     bool single = item.deselectButton ? false : true;
     //pass arguments to DBManager and invoke select event
     bool changed = DBManager.SetToSelected(item.productId, single);
     if(changed && itemSelectedEvent != null)
         itemSelectedEvent(item.productId);
 }
예제 #7
0
 /// <summary>
 /// sets an item to 'deselected' in the database
 /// </summary>
 public static void SetToDeselected(IAPItem item)
 {
     //pass argument to DBManager and invoke deselect event
     DBManager.SetToDeselected(item.productId);
     if(itemDeselectedEvent != null)
         itemDeselectedEvent(item.productId);
 }
예제 #8
0
        /// <summary>
        /// Initializes all IAPItem in the scene and instantiates them with their correct state.
        /// Called by IAPManager.
        /// </summary>
        public void Init()
        {
            instance = this;
            IAPItems.Clear();
            DBManager.updatedDataEvent += Refresh;

            //get manually placed items in the scene
            IAPItem[] sceneItems = Resources.FindObjectsOfTypeAll(typeof(IAPItem)) as IAPItem[];
            for (int i = 0; i < sceneItems.Length; i++)
            {
                if (string.IsNullOrEmpty(sceneItems[i].productId))
                {
                    continue;
                }

                #if UNITY_EDITOR
                if (UnityEditor.EditorUtility.IsPersistent(sceneItems[i].gameObject))
                {
                    continue;
                }
                #endif

                IAPItems.Add(sceneItems[i].productId, sceneItems[i]);
            }


            //get list of all shop groups from IAPManager
            List <IAPGroup> list  = IAPManager.GetInstance().IAPs;
            int             index = 0;

            //loop over groups
            for (int i = 0; i < list.Count; i++)
            {
                //cache current group
                IAPGroup      group     = list[i];
                ShopContainer container = GetContainer(group.id);

                //skip group if prefab or parent wasn't set
                if (container == null || container.prefab == null || container.parent == null)
                {
                    continue;
                }

                //loop over items
                for (int j = 0; j < group.items.Count; j++)
                {
                    //cache item
                    IAPObject obj = group.items[j];
                    //the item has already been placed in the scene manually
                    //dont instantiate it in a container then
                    if (IAPItems.ContainsKey(obj.id))
                    {
                        continue;
                    }

                    //instantiate shop item in the scene and attach it to the defined parent transform
                    GameObject newItem = (GameObject)Instantiate(container.prefab);
                    newItem.transform.SetParent(container.parent.transform, false);
                    newItem.GetComponent <RectTransform>().anchoredPosition = Vector2.zero;
                    //rename item to force ordering as set in the IAP Settings editor
                    newItem.name = "IAPItem " + string.Format("{0:000}", index + j);
                    //get IAPItem component of the instantiated item
                    IAPItem item = newItem.GetComponent <IAPItem>();
                    if (item == null)
                    {
                        continue;
                    }

                    //add IAPItem to dictionary for later lookup
                    IAPItems.Add(obj.id, item);

                    //upgrades overwrite, an IAP Item gets replaced with its current level
                    List <string> upgrades = IAPManager.GetIAPUpgrades(obj.id);
                    if (upgrades != null && upgrades.Count > 0)
                    {
                        for (int k = 0; k < upgrades.Count; k++)
                        {
                            IAPItems.Add(upgrades[k], item);
                        }

                        string currentUpgrade = IAPManager.GetNextUpgrade(obj.id);

                        if (!string.IsNullOrEmpty(currentUpgrade))
                        {
                            obj = IAPManager.GetIAPObject(currentUpgrade);
                        }
                    }

                    //initialize and set up item properties based on the associated IAPObject
                    //they could get overwritten by online data later
                    item.Init(obj);
                }

                index += group.items.Count;
            }

            //refresh all products initially
            RefreshAll();
        }
        //instantiates shop item prefabs
        void InitShop()
        {
            //reset
            IAPItems.Clear();

            //get list of all shop groups from IAPManager
            List <IAPGroup> list  = IAPManager.GetInstance().IAPs;
            int             index = 0;

            //loop over groups
            for (int i = 0; i < list.Count; i++)
            {
                //cache current group
                IAPGroup      group     = list[i];
                ShopContainer container = GetContainer(group.id);

                //skip group if prefab or parent wasn't set
                if (container == null || container.prefab == null || container.parent == null)
                {
                    if (IAPManager.isDebug)
                    {
                        Debug.LogWarning("Setting up Shop, but prefab or parent of Group: '"
                                         + group.name + "' isn't set. Skipping group.");
                    }
                    continue;
                }

                //loop over items
                for (int j = 0; j < group.items.Count; j++)
                {
                    //cache item
                    IAPObject obj = group.items[j];
                    //instantiate shop item in the scene and attach it to the defined parent transform
                    GameObject newItem = (GameObject)Instantiate(container.prefab);
                    newItem.transform.SetParent(container.parent.transform, false);
                    newItem.GetComponent <RectTransform>().anchoredPosition = Vector2.zero;
                    //rename item to force ordering as set in the IAP Settings editor
                    newItem.name = "IAPItem " + string.Format("{0:000}", index + j);
                    //get IAPItem component of the instantiated item
                    IAPItem item = newItem.GetComponent <IAPItem>();
                    if (item == null)
                    {
                        continue;
                    }

                    //add IAPItem to dictionary for later lookup
                    IAPItems.Add(obj.id, item);

                    //upgrades overwrite, an IAP Item gets replaced with its current level
                    List <string> upgrades = IAPManager.GetIAPUpgrades(obj.id);
                    if (upgrades != null && upgrades.Count > 0)
                    {
                        for (int k = 0; k < upgrades.Count; k++)
                        {
                            IAPItems.Add(upgrades[k], item);
                        }

                        string currentUpgrade = IAPManager.GetNextUpgrade(obj.id);

                        if (!string.IsNullOrEmpty(currentUpgrade))
                        {
                            obj = IAPManager.GetIAPObject(currentUpgrade);
                        }
                    }

                    //initialize and set up item properties based on the associated IAPObject
                    //they could get overwritten by online data later
                    item.Init(obj);
                }

                index += group.items.Count;
            }
        }
예제 #10
0
        /// <summary>
        /// handle purchases, for real money or ingame currency
        /// </summary>
        public void HandleSuccessfulPurchase(string id)
        {
            //differ between ids set in the IAP Settings editor
            if (debug)
            {
                Debug.Log("HandleSuccessfulPurchase: " + id);
            }
            //get instantiated shop item based on the IAP id
            IAPItem item = null;

            if (ShopManager.GetInstance())
            {
                item = ShopManager.GetIAPItem(id);
            }

            //if the purchased item was non-consumable,
            //additionally block further purchase of the shop item
            if (item != null &&
                (item.type == IAPType.nonConsumable ||
                 item.type == IAPType.nonConsumableVirtual ||
                 item.type == IAPType.subscription))
            {
                item.Purchased(true);
            }

            switch (id)
            {
            //section for in app purchases

            case "bann_coins":
                gameParameters.currentCharacter = "Bann";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Bann!");
                break;

            case "bella_coins":
                gameParameters.currentCharacter = "Bella";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Bella!");
                break;

            case "blane_coins":
                gameParameters.currentCharacter = "Blane";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Blane!");
                break;

            case "damien_coins":
                gameParameters.currentCharacter = "Damien";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Damien!");
                break;

            case "finnikin_coins":
                gameParameters.currentCharacter = "Finnikin";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Finnikin!");
                break;

            case "gwyn_coins":
                gameParameters.currentCharacter = "Gwyn";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Gwyn!");
                break;

            case "hector_coins":
                gameParameters.currentCharacter = "Hector";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Hector!");
                break;

            case "katsa_coins":
                gameParameters.currentCharacter = "Katsa";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Katsa!");
                break;

            case "mather_coins":
                gameParameters.currentCharacter = "Mather";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Mather!");
                break;

            case "pifoo_coins":
                gameParameters.currentCharacter = "Pifoo";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Pifoo!");
                break;

            case "rylan_coins":
                gameParameters.currentCharacter = "Rylan";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Rylan!");
                break;

            case "sothe_coins":
                gameParameters.currentCharacter = "Sothe";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Sothe!");
                break;

            case "wesker_coins":
                gameParameters.currentCharacter = "Wesker";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Wesker!");
                break;

            case "yuki_coins":
                gameParameters.currentCharacter = "Yuki";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Yuki!");
                break;
            }
        }
예제 #11
0
        /// <summary>
        /// handle purchases, for real money or ingame currency
        /// </summary>
        public void HandleSuccessfulPurchase(string id)
        {
            //differ between ids set in the IAP Settings editor
            if (IAPManager.isDebug)
            {
                Debug.Log("HandleSuccessfulPurchase: " + id);
            }
            IAPObject obj = IAPManager.GetIAPObject(id);

            //get instantiated shop item based on the IAP id
            IAPItem item = null;

            if (ShopManager.GetInstance())
            {
                item = ShopManager.GetIAPItem(id);
            }

            //if the purchased item was non-consumable,
            //additionally block further purchase of the shop item
            if (item != null && obj != null && obj.type != ProductType.Consumable)
            {
                item.Purchased(true);
            }

            switch (id)
            {
            //section for in app purchases
            case "coins":
                //the user bought the item "coins",
                //increase coins by 1000 and show appropriate feedback
                DBManager.IncreaseFunds("coins", 1000);
                ShowMessage("1000 coins were added to your balance!");
                break;

            case "coin_pack":
                DBManager.IncreaseFunds("coins", 2500);
                ShowMessage("2500 coins were added to your balance!");
                break;

            case "big_coin_pack":
                DBManager.IncreaseFunds("coins", 6000);
                ShowMessage("6000 coins were added to your balance!");
                break;

            case "huge_coin_pack":
                DBManager.IncreaseFunds("coins", 12000);
                ShowMessage("12000 coins were added to your balance!");
                break;

            case "no_ads":
                //no_ads purchased. You can now check DBManager.isPurchased("no_ads")
                //before showing ads and block them
                ShowMessage("Ads disabled!");
                break;

            case "abo_monthly":
                //same here - your code to unlock subscription content
                ShowMessage("Subscribed to monthly abo!");
                break;

            case "restore":
                //nothing else to call here,
                //the actual restore is handled by IAPManager
                ShowMessage("Restored transactions!");
                break;

            //section for in game content
            case "bullets":
                //for virtual items, you could use DBManager's custom data option in order
                //to save amounts of virtual products. E.g. increasing bullets by 100:
                //int bullets = DBManager.GetPlayerData("bullets").AsInt;
                //DBManager.SetPlayerData("bullets", new SimpleJSON.JSONData(bullets + 100));
                ShowMessage("Bullets were added to your inventory!");
                break;

            case "health":
                ShowMessage("Medikits were added to your inventory!");
                break;

            case "energy":
                ShowMessage("Energy was added to your inventory!");
                break;

            case "speed":
                ShowMessage("Speed boost unlocked!");
                break;

            case "speed_1":
            case "speed_2":
            case "speed_3":
                ShowMessage("Speed boost upgraded!");
                break;

            case "bonus":
                ShowMessage("Bonus level unlocked!");
                break;

            case "uzi":
                ShowMessage("Uzi unlocked!");
                break;

            case "ak47":
                ShowMessage("AK47 unlocked!");
                break;

            case "m4":
                ShowMessage("M4 unlocked!");
                break;

            case "hat":
                ShowMessage("Hat unlocked!");
                break;

            case "backpack":
                ShowMessage("Backpack unlocked!");
                break;

            case "belt":
                ShowMessage("Ammo belt unlocked!");
                break;

            case "jetpack":
                ShowMessage("Jetpack unlocked!");
                break;

            case "booster":
                ShowMessage("Double XP unlocked!");
                break;
            }
        }
예제 #12
0
        // handles an online verification request and response from
        // our external server. www.text can returns true or false.
        // true: purchase verified, false: not verified (fake?) purchase
        IEnumerator WaitForRequest(Dictionary <string, string> dic)
        {
            //cache requested product id
            string id = dic["pid"];

            //build POST request with transaction data
            WWWForm form = new WWWForm();

            foreach (string key in dic.Keys)
            {
                form.AddField(key, dic[key]);
            }
            //create URL and execute until we have a respone
            WWW www = new WWW(serverUrl + verificationFileName, form);

            yield return(www);

            //check for URL errors
            if (www.error == null)
            {
                //we have a successful response from our server,
                //but it returned false (fake purchase)
                if (!bool.Parse(www.text))
                {
                    inventory.ErasePurchase(id);
                    if (debug)
                    {
                        Debug.Log("The receipt for '" + id + "' could not be verified: " + www.text);
                    }
                    //PurchaseFailed("The receipt for '" + id + "' could not be verified.");

                    id = GetIAPIdentifier(id);
                    //remove purchase from the database and update item state
                    if (DBManager.isPurchased(id))
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(id);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(id);
                    }
                    yield break;
                }
                else
                {
                    //successful response, verified transaction
                    if (debug)
                    {
                        Debug.Log(dic["pid"] + " verification success.");
                    }
                }
            }
            else
            {
                //we can't reach our external server, do nothing:
                //in this case we handle the purchase as without verification
                if (debug)
                {
                    Debug.Log("Verification URL error: " + www.text);
                }
            }

            id = GetIAPIdentifier(id);
            PurchaseVerified(id);
        }
예제 #13
0
        // check for purchases on online servers at billing initialization.
        // If a purchase is not registered, set local purchase state back to false
        private void VerifyReceipts()
        {
            //get list of old purchases: on iOS the saved and filtered transactions (avoiding duplicates),
            //on Android we use the old purchases list received from Google
            #if UNITY_IPHONE
            List <StoreKitTransaction> prods = FilterTransactions(StoreKitBinding.getAllSavedTransactions());
            #endif
            if (prods == null || prods.Count == 0)
            {
                return;
            }

            //loop over all IAP items to check if a valid receipt exists
            for (int i = 0; i < ids.Length; i++)
            {
                //cache IAP id,
                //only verify purchased items
                string localId  = ids[i];
                string globalId = GetIAPIdentifier(localId);
                if (DBManager.isPurchased(globalId))
                {
                    //initialize item as faked and loop over receipts
                    bool faked = true;
                    for (int j = 0; j < prods.Count; j++)
                    {
                        //find corresponding transaction class
                        string identifier = "";
                        #if UNITY_IPHONE
                        StoreKitTransaction purchase = prods[j];
                        identifier = purchase.productIdentifier;
                        #elif UNITY_ANDROID
                        GooglePurchase purchase = prods[j];
                        identifier = purchase.productId;
                        #endif
                        if (identifier == localId)
                        {
                            //we found a receipt for this product on the device,
                            //unset fake purchase and let our external
                            //server decide what happens with this transaction
                            faked = false;
                            MakeRequest(purchase);
                            break;
                        }
                    }
                    //we haven't found a receipt for this item, yet it is
                    //set to purchased. This can't be, maybe our external server
                    //response or the database has been hacked with fake data
                    if (faked)
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(globalId);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(globalId);
                    }
                }
            }
        }