0
votes

Code Below: is currently part of an void awake() where the if statement sets up all playerPrefs values for first time playing. The below else statement is trying to implement how many coins will be earned when the player re-opens the app.

How to Fix: How do I make it so it only runs this code when the application is re-Opened? Not every time the scene is reloaded.

Possible Improvements: If you see a easier way to do the below code to prevent time cheating, I am open to suggestions. I want only a max of 24Hr bonus coins or if open in less than that give equal value coins.

 else
 { 
    // Player Restart Game
    // Check Time for coin bonus

    ButtonCanvas.gameObject.SetActive(false);
    OfflineCanvas.gameObject.SetActive(true);

    // Same Year
    if (PlayerPrefs.GetInt("year").Equals(System.DateTime.Now.Year))
    {
        // Same Month
        if (PlayerPrefs.GetInt("month").Equals(System.DateTime.Now.Month))
        {
            // Same Day
            if(PlayerPrefs.GetInt("day").Equals(System.DateTime.Now.Day))
            { 
                // Add Coin Bouns for hours/min passed
                offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (((System.DateTime.Now.Hour - PlayerPrefs.GetInt("timeHour")) * 60) + (System.DateTime.Now.Minute - PlayerPrefs.GetInt("timeMin")));

            } 
            else // Different Day
            { 
                // Update if new day is higher than old
                if (PlayerPrefs.GetInt("day") < System.DateTime.Now.Month)
                {
                    PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
                    PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
                    PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);

                    // Add Coin Bonus For Time 24 hrs
                    offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
                }
            }
        } 
        else // Different Month
        { 
            // Update if new month is higher than old
            if (PlayerPrefs.GetInt("month") < System.DateTime.Now.Month)
            {
                PlayerPrefs.SetInt("month", System.DateTime.Now.Year);
                PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
                PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
                PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);

                // Add Coin Bonus For Time 24 hrs
                offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
            }
        }
    } 
    else // Different Year
    { 
        // Update if new year is higher than old
        if (PlayerPrefs.GetInt("year") < System.DateTime.Now.Year){
            PlayerPrefs.SetInt("year", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("month", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
            PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);

            // Add Coin Bonus For Time 24 hrs
            offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
        }
    }
}
2
You would need to call this code, not from the Awake() or Start() of a scene script, but from something that persists between scenes. - Draco18s no longer trusts SE
There isn't alot you can do to prevent time cheating unless you setup a server somewhere and get the time from that(afaik). but you can store the most furthest time in the future and do a check to see if the new time is later then that before giving them coins... User's can still time cheat, but if they ever fix the time on their phones it will always be less then that time and they will not get coins. - AresCaelum
I had noticed that Candy Crush had an interesting deterrent to avoid time cheating for lives. I had set my clock ahead on my phone to get lives right away, but when my phone clock went back to normal, the timer for how long until the next life was several days in the future. - Timothy Winters
To expand on that, I think what was done is the time that was on the device at the moment was stored for the time of the life given, so that the next life wouldn't be given until that time again + 30 minutes. So what you could do is when the coin is given, store the time, and then do a time check for the next coin. If someone cheats by advancing their clock forward, when the clock sets back on the network time, they will have to wait for the time to catch up. - Timothy Winters

2 Answers

0
votes

Try:

static bool IsCalled;
else{ //Player Restart Game
    //////
    /// Check Time for coin bonus
    //////
    if (!IsCalled)
    {
    ButtonCanvas.gameObject.SetActive(false);
    OfflineCanvas.gameObject.SetActive(true);

    if(PlayerPrefs.GetInt("year").Equals(System.DateTime.Now.Year)){ // Same Year
        if(PlayerPrefs.GetInt("month").Equals(System.DateTime.Now.Month)){ // Same Month
            if(PlayerPrefs.GetInt("day").Equals(System.DateTime.Now.Day)){ // Same Day
                // Add Coin Bouns for hours/min passed

                offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (((System.DateTime.Now.Hour - PlayerPrefs.GetInt("timeHour")) * 60) + (System.DateTime.Now.Minute - PlayerPrefs.GetInt("timeMin")));

            } else { // Different Day
                // Update if new day is higher than old
                if (PlayerPrefs.GetInt("day") < System.DateTime.Now.Month)
                {
                    PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
                    PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
                    PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);
                    // Add Coin Bonus For Time 24 hrs
                    offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
                }
            }
        } else { // Different Month

            // Update if new month is higher than old
            if (PlayerPrefs.GetInt("month") < System.DateTime.Now.Month)
            {
                PlayerPrefs.SetInt("month", System.DateTime.Now.Year);
                PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
                PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
                PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);
                // Add Coin Bonus For Time 24 hrs
                offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
            }

        }
    } else { // Different Year
        // Update if new year is higher than old
        if(PlayerPrefs.GetInt("year") < System.DateTime.Now.Year){
            PlayerPrefs.SetInt("year", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("month", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("day", System.DateTime.Now.Year);
            PlayerPrefs.SetInt("timeHour", System.DateTime.Now.Hour);
            PlayerPrefs.SetInt("timeMin", System.DateTime.Now.Minute);
            // Add Coin Bonus For Time 24 hrs
            offlineCoinCount = PlayerPrefs.GetInt("OfflineCoinsVal") * (24 * 60);
        }
    }
    IsCalled = true;
}
}

The boolean will remain unchanged til game is reset.

0
votes

The way to do this is to use OnApplicationfoucs() OnApplicationPause() OnApplicationClose()