Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Time cheating prevention in offline mode (iOS + Android)

Discussion in 'Assets and Asset Store' started by Vavius, Jul 13, 2014.

  1. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Hello!

    Time cheat prevention package will help you implementing unbiased timers that cannot be modified by date/time change in device settings.

    It is commonly known that the most secure way to prevent cheating is using a server. But what if your game can be played offline? For example Candy Crush Saga uses server to get timestamps and calculates remaining lives based on it. To replenish lives you can just turn off network and change time by several hours. And now even this kind of cheat can be prevented!

    How it works:
    • Native mobile plugin (iOS + Android) that measures time delta between current app launch and last app quit (this delta is unaffected by device date/time settings)
    • C# helper singleton class with one simple method: Now(). Returns DateTime object initialised with estimated real time value (estimated means that it can be different from actual real world time, but is guaranteed to be unaffected by device time changes - so you can calculate time delta from it safely).
    Requirements:
    • Unity3D 4+ free or pro
    • iOS or Android device. Prevents cheating only on real device, desktop and editor will fallback to DateTime.Now() which is unprotected.

    This package can be used in offline only games and with your timestamp server (whenever server isn't available just use estimate time from plugin).

    View in Asset Store:
    Link

    15.07.2014: Android version is ready
    15.07.2014: Update containing optional ntp sever pool sync (requires Unity3D Pro for mobile, but works on desktop with Free)
     
    Last edited: Oct 3, 2014
  2. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,545
    yes interested in android version too
     
  3. rextr09

    rextr09

    Joined:
    Dec 22, 2011
    Posts:
    416
    This works great on iOS. Just needed a little bit adjustment to make it work across multiple scenes. Now I would like to see the Android Version. Thanks.
     
  4. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Thanks for your replies.

    I'll upload Android version next week.

    DontDestroyOnLoad in singleton? Thanks for the info, will add this fix to the update.
     
  5. rextr09

    rextr09

    Joined:
    Dec 22, 2011
    Posts:
    416
    Yes, exactly. I can't wait for the Android version. Thanks.
     
  6. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Android version is ready. Currently pending review.
     
  7. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
  8. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    705
    Any chance you can just combine the 2 assets into one? I am totally happy paying $15 for this! But $30?
     
  9. rextr09

    rextr09

    Joined:
    Dec 22, 2011
    Posts:
    416
    Thanks for the android. Do you have any plan for a WP8 version? :)
     
    Last edited: Aug 5, 2014
  10. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,545
    Yes, rather than 1 version that supports multiple platform
     
  11. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Sorry, no plans for WP8 support, since I don't have a WP8 device.

    The package will updated soon. Features to be released:
    1. Merge both packages into one. The current iOS package will include Android. The Android package will be removed from store.
    2. Option to sync with timestamp server and an example server-side script.
     
    SmashedAvocado and Prodigga like this.
  12. SmashedAvocado

    SmashedAvocado

    Joined:
    Dec 19, 2013
    Posts:
    37
    Hey Vavius. This sounds like just the right plugin!

    I'm interested in getting this for a mobile game I'm developing. I've got a couple of questions:

    How robust is it? I don't suppose you've tested it on the latest iOS 8 and on older devices?

    Does it work on Desktop/in-editor, for testing and debugging, etc.?

    Any timeframe on the Android/iOS merge? I'm interested in getting both, but I'll wait on the package merge if that will be quick.

    Thanks!
     
  13. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    iOS 8 isn't tested yet. Tested hardware: iPhone 4, 5, 5s, iPad 3 retina. Tested software: iOS 6 and 7.

    It half-works in editor. The API returns valid timestamp (the current system timestamp), but it won't prevent time-change. You can run your game in editor just normally, but without time-change preventing features.

    1-2 weeks. You can get iOS version right now and then just update. I'll be merging Android into iOS.
     
    SmashedAvocado likes this.
  14. SmashedAvocado

    SmashedAvocado

    Joined:
    Dec 19, 2013
    Posts:
    37
    Thanks for the responses! I really appreciate it and I'm looking forward to the Android update :)
     
  15. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    I've added ntp (network time protocol) implementation to acquire current timestamp from server pool (pool.ntp.org). However, ntp is a low-level protocol that uses udp sockets. A .NET sockets are Pro-only feature on mobile devices.
    So, server time sync is made optional.

    The new combined version is pending review now.
     
    SmashedAvocado likes this.
  16. F.Salka

    F.Salka

    Joined:
    Dec 13, 2013
    Posts:
    43
    Hi Vavuis,

    Does the iOS plug in uses undocumented/private APIs? also, can you update the plug so it calls _vtcTimestampOffset() on applicationWillResignActive() (or whatever function the plug in uses to save the time) , currently it seems it's only called on applicationDidEnterBackground, this is essential because on iOS there is a chance that this method (DidEnterBackground) would never be called during the app life cycle, to test this, install fresh version of the app, after it launches for the first time double click the home button and swipe up the app, you can repeat the process as many times and applicationDidEnterBackground will never be called (only applicationWillResignActive), if you change the time during these lunches, Now(). will always return the wrong time, not until applicationDidEnterBackground gets called, then it will actually start reporting a correct time.
     
  17. F.Salka

    F.Salka

    Joined:
    Dec 13, 2013
    Posts:
    43
    Also, the plug in seems to start reporting the correct date when applicationDidBecomeActive gets called AFTER the unity3d scene loads (the first applicationDidBecomeActive that is always called on launch exactly after applicationDidFinishLaunching seems to have zero effect on the plug in), again, this could lead to the plug in not reporting the correct time if those two function never get called during the app lifetime cycle (DidEnterBackground & DidBecomeActive AFTER unity scene loads).
     
    Last edited: Sep 24, 2014
  18. SmashedAvocado

    SmashedAvocado

    Joined:
    Dec 19, 2013
    Posts:
    37
    Awesome! Looking forward to trying the Android version out too!
     
  19. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    It uses sysctl.h which is not a private API. It passes App Store validation normally. We have several titles with this method released.

    Session handling is done through Unity3d API - OnApplicationPause(bool). It uses applicationDidEnterBackground, but not applicationWillResignActive. You can add a call to _vtcOnSessionEnd() in applicationWillResignActive in your Xcode project.

    Another way to fix is manually calling SessionEnd() method to save current data (it just writes some numbers to NSUserDefaults, nothing more). I'll rename it to something more obvious like Sync, Flush, Write... This can be called when you schedule a new timer or when your game data is saved.

    SessionStart is called in Awake(), so the proper place to query Now() is Start(). A better way will be calling SessionStart() just when creating singleton instance, I'll fix that.
     
  20. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    373
    Watching, might need this in the future.
     
  21. SmashedAvocado

    SmashedAvocado

    Joined:
    Dec 19, 2013
    Posts:
    37
    I just wanted to jump in and say that Vavius has provided some of the best support from a plugin developer ever!

    I highly recommend this Time cheat prevention package as it works great and easily on iOS and Android.
     
  22. orukinawa

    orukinawa

    Joined:
    Oct 17, 2014
    Posts:
    1
    Hi Vavius,

    Correct me if I'm wrong but since the time delta is unaffected by device time/date settings, I would assume that you are checking the time elapsed since the device was booted. If that assumption is correct, then what would happen if the user turns the device off and back on. Won't it reset the time elapsed and mess up all the calculations? (In a totally offline environment).
     
  23. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Yes, your assumption is correct. By rebooting device you can actually fool the system. If the uptime is less than it was at last app launch then the current device clock is used as TimeStamp. Doing like so ensures that system won't affect users that don't try to cheat (but you still can cheat with changing time and rebooting device).

    There is only one rare situation when everything breaks - if you rebooted the device some time ago and current uptime is larger than the last one seen in game. In this case you'll see that much less time has passed. This affects more long-running timers like several days or weeks.

    To ensure best user experience it is advised to use server-based solution. This package is good fallback mechanism in offline mode or when your server is down.
     
  24. BAnyBudde

    BAnyBudde

    Joined:
    Jun 3, 2014
    Posts:
    49
    Hey Vavius,

    Getting to that point of the game where I need to start adding a timer that cannot be cheated.
    Saw your plugin on the Asset Store, and I want it :)
    The only drawback for me, is that I use PlayMaker and uScript as I cannot code myself.
    So my question is, can I get this working with Playmaker, and if not... What are the variables that are exposed in the inspector panel?

    Feel Free to E-Mail me at

    braydonbudde@gmail.com

    Quite Urgent.
     
  25. xerohuang

    xerohuang

    Joined:
    Mar 31, 2014
    Posts:
    6
    Hey Vavius,

    Could you add an API that returns if the device is rebooted before app launch?
     
  26. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    OK, will be in the next version. Also I try to make plugin friendly to visual scripting tools (PlayMaker).
     
  27. BAnyBudde

    BAnyBudde

    Joined:
    Jun 3, 2014
    Posts:
    49
    Vavius, Thank you so Much!
    Can't wait to see what Actions & Events you put into Playmaker with this Plugin.
    Will Purchase as soon as you add the update with Playmaker.
    You are Awesome!
     
  28. byerdelen

    byerdelen

    Joined:
    Mar 27, 2010
    Posts:
    68
    And also can you give an example of api how to call the current time? Is it just one line easy like TCP.time? There is no documentation online so I can check if it is good to go.
     
    Last edited: Mar 1, 2015
  29. kunst-stoff

    kunst-stoff

    Joined:
    Sep 2, 2014
    Posts:
    9
    Is it 64bit ready for iOS?
     
  30. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Haven't done anything special for it, but just tried with Unity 5.0.1f1 (il2cpp arm64 build) on iPhone 6 - builds and works fine.
     
  31. Dynamikeyz

    Dynamikeyz

    Joined:
    Aug 21, 2015
    Posts:
    29
    Could this, by any chance, be for a game called Crossy Roads? :p I watched your talk and you mentioned a Unity plugin that prevented time cheaters! I needed just that and I'm guessing this is the plugin your team mentioned? :)
    Also, congrats.

    PS I have a question here https://forums.developer.apple.com/message/48165#48165 that I still don't have an answer to. If anyone knows, please do answer! :)
     
  32. Dynamikeyz

    Dynamikeyz

    Joined:
    Aug 21, 2015
    Posts:
    29
    Hi Vavius,

    I bought your product a month ago but require unbiased time to give 7dp. However, I only found that I could put 5dp. Normally, I do time.realtimesincestartup

    Does your software have a solution to this (i.e. give 7dp)?
    Thanks
     
  33. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Yeah, it is used in Crossy Road.

    I don't quite understand you. Is 7dp means 7 days? From the plugin's point of view 5 days is nothing different from 7 days. But that is a long timeframe, a device reboot can happen and screw up time calculation.
     
  34. miran-loncaric

    miran-loncaric

    Joined:
    Nov 24, 2015
    Posts:
    3
    Awesome plugin!
    Changed our code and it worked as expected on first try!

    I've noticed that you have two UnbiasedTime.cs files, one for free and another for pro version.
    There's UNITY_PRO_LICENSE define, which can be used to determine if a script can use pro features or not.
    I just did that and it worked.

    Thanks and take care!
     
  35. graviton

    graviton

    Joined:
    Jan 11, 2013
    Posts:
    75
    @Vavius

    Will this plugin work for Unity5?

    Edit, never mind
     
  36. graviton

    graviton

    Joined:
    Jan 11, 2013
    Posts:
    75
    @Vavius

    When I change the code in "UnbiasedTime.cs" to the code in "UnbiasedTime_UnityPro.txt" I get an error from the "SampleTimer.cs"

    This error

    "UnbiasedTime" does not contain a definition for "IsUsingSystemTime" and no exenstion method "IsUsingSystemTime" could be found (are you missing a using directive or an assembly reference?)

    The "SampleTimer" is trying to access "IsUsingSystemTime" which you left out of "UnbiasedTime_UnityPro"
     
  37. Salazar

    Salazar

    Joined:
    Sep 2, 2013
    Posts:
    236
    Hello,

    Is this time cheat prevention plugin handles Daylight Saving Time changes?
    EDIT: Most tablets doesn't handle DST, you must change time manually. Cell Phones may get time from cell phone network.
    Regards,
     
    Last edited: Jan 24, 2016
  38. FritzPeace

    FritzPeace

    Joined:
    Sep 15, 2014
    Posts:
    29
    Hello, is this still working?
    Do I need to have a website/server to make this work, or it works easily without much work?
    And do you have an email for contact?

    Best!
     
  39. MetaObjectData

    MetaObjectData

    Joined:
    Sep 9, 2015
    Posts:
    4
    @Vavius Thanks for an awesome plugin. We are using it on a idle game called Farm Away!.

    Any chance for a new version of the libUnbiasedTime.a library built with Bitcode enabled so that we could support iOS app thinning?
     
    relayOne likes this.
  40. relayOne

    relayOne

    Joined:
    Sep 28, 2012
    Posts:
    23
    I am also interestet. I got this error using default build settings in Unity 5.3.2. I wasn't aware I could even fix this. After turning off "Enable Bitcode" it worked.

    .../Libraries/Plugins/iOS/libUnbiasedTime.a(libSecureTime.a-armv7-master.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
     
  41. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    @MetaObjectData, @relayOne Guys, sorry for the delay. I've uploaded update to the asset store. It should become available later this week after review.

    @miran.loncaric Thanks for that UNITY_PRO_LICENSE define!

    Anyway, with the new Unity5 licensing it seems that C# sockets are now available on ios/android with free/personal license. If this is actually true, the next version will be completely refactored for better protection and less false-positives.
     
    MetaObjectData likes this.
  42. relayOne

    relayOne

    Joined:
    Sep 28, 2012
    Posts:
    23
    Unbiased time has been working terrifically when I play on one device. However, I just added cloud synchronization to my game, so players can play on more than one device. UnbiasedTime.Now() seems to be about 40 minutes different between my two test devices. Does 40 minutes seem excessive to you? I actually have both devices set to automatically update to current time, so I'm not even trying to test cheating by changing a clock.

    Will the new licensing that you talk about address the problem? Obviously, when I sync with the cloud, I have access to the network, so it could be nice to have a network time sync option.
     
  43. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    @relayOne Yes, plugin will default to network time if it is available.

    40 minutes is OK, plugin was designed to calculate time difference that is stable after changing device time in settings.
    UnbiasedTime.Now() is unaffected by time sync settings on device, so you get full system timer error + sometimes really big offsets can occur after rebooting the device. Comparing UnbiasedTime.Now() to system time is not a good idea, but difference between the two UnbiasedTime's can be used to disable cheating with time without network.

    I'll address this issues in the next release.
     
  44. GDelaney

    GDelaney

    Joined:
    Oct 7, 2015
    Posts:
    1
    Hi,

    The project I've been working on has been using the plugin and its working as advertised. Thanks!

    There is one situation that is giving us some weird results however. It seems that if we check for the current time on the first frame after resuming the application (via OnApplicationFocus callbacks) then it is returning the device system time (affected by messing with the system clock). This behaviour appears consistent across Android and iOS devices too. Luckily we were able to avoid running into problems by waiting a frame after resume before checking the time. I just wanted to post this behaviour in case it is something that can be solved in a future update to the plugin :)

    Otherwise awesome work!
     
  45. juicybeast

    juicybeast

    Joined:
    Nov 12, 2014
    Posts:
    24
    Hello, I can't compile on iOS, xCode prompts me this:

    Undefined symbols for architecture armv7:
    "__vtcOnSessionEnd", referenced from:
    _UnbiasedTime_EndIOS_m3081547205 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcOnSessionEnd_m3789460829 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_EndIOS_m3081547205 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcOnSessionEnd_m3789460829 in Bulk_Assembly-CSharp-firstpass_3.o
    (maybe you meant: _UnbiasedTime__vtcOnSessionEnd_m3789460829)
    "__vtcOnSessionStart", referenced from:
    _UnbiasedTime_StartIOS_m3569078814 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcOnSessionStart_m3545988836 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_StartIOS_m3569078814 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcOnSessionStart_m3545988836 in Bulk_Assembly-CSharp-firstpass_3.o
    (maybe you meant: _UnbiasedTime__vtcOnSessionStart_m3545988836)
    "__vtcUsingSystemTime", referenced from:
    _UnbiasedTime_UsingSystemTimeIOS_m2034289692 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcUsingSystemTime_m60709331 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_UsingSystemTimeIOS_m2034289692 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcUsingSystemTime_m60709331 in Bulk_Assembly-CSharp-firstpass_3.o
    (maybe you meant: _UnbiasedTime__vtcUsingSystemTime_m60709331)
    "__vtcTimestampOffset", referenced from:
    _UnbiasedTime_UpdateTimeOffsetIOS_m2320183571 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_StartIOS_m3569078814 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcTimestampOffset_m1162747804 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_UpdateTimeOffsetIOS_m2320183571 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime_StartIOS_m3569078814 in Bulk_Assembly-CSharp-firstpass_3.o
    _UnbiasedTime__vtcTimestampOffset_m1162747804 in Bulk_Assembly-CSharp-firstpass_3.o
    (maybe you meant: _UnbiasedTime__vtcTimestampOffset_m1162747804)

    Do you have any idea what could do this and how to fix it?
     
  46. juicybeast

    juicybeast

    Joined:
    Nov 12, 2014
    Posts:
    24
    Nevermind, libUnbiasedTime.a got lost when I switched to the mac computer, when I tried to add it back, it prompted me "deleting, the asset does not exist" I re-downloaded from the asset store and it was good.
     
  47. PabloAM

    PabloAM

    Joined:
    Dec 25, 2012
    Posts:
    35
    Hello @Vavius , any new about the next release that u said?

    Is still the error with IsUsingSystemTime and the define and sockets are old.

    Thanks!
     
  48. BillyMFT

    BillyMFT

    Joined:
    Mar 14, 2013
    Posts:
    178
    Does the network time check in this plugin work with the new Apple requirement to support IPv6 only networks?
     
  49. generalhak

    generalhak

    Joined:
    Apr 20, 2014
    Posts:
    25
  50. pfleetwood22

    pfleetwood22

    Joined:
    Jun 6, 2016
    Posts:
    28
    Any chance for ENABLE_BITCODE support on iOS?