1

I am developing an app that has refills lives every 5 minutes. What is the best way to check the time since the last refill so that the user cannot trick the system by changing the time on their device?

For an example, look at Candy Crush. Changing the system time on there gives you extra lives, and this is what I need preventing.

EdG
  • 190
  • 8
Mike Deluca
  • 1,295
  • 2
  • 18
  • 41

3 Answers3

0

How about running an [NSTimer scheduledTimerWithTimeInterval:300.0 target:self selector:@selector(giveLife:) userInfo:nil repeats:YES];

That should execute giveLife every 5 minutes and there you can give the extra life. As far as I can tell, NSTimer will not be affected by changing the clock time once it has started.

snowdragon
  • 753
  • 7
  • 18
0

I would suggest You do something similar as it is in Clumsy ninja.

SHORT

  • Every time application becomes active [applicationDidBecomeActive:] - You try to get internet time.
  • If device time timestamp is smaller than stored timestamp - don't allow to continue. (Ask to connect to internet).
  • Implement a feature to save timestamp of the last regeneration cycle. Thus - even if user succeeds getting faster live refills, Once he reverts back to original time and continues game - it will show that next live refill will be way in the future at the time user was last using application, not 5 minutes. (To punish cheaters) (But maybe set a max limit, if last regenerate time is bigger than 5 minutes from current time, then set it to 1 hour? still a punish, but not so big to lose a player.

LONG

(Based on what I could distinguish)

Every time application becomes active - You try to get internet time. At that point - You don't need to check the time anymore while the app is opened, until the next time application becomes active again.

In clumsy ninja, they allow to use app even if internet is not available. So - if I activate airplane mode (for example), adjust time to be few hours forward, and open application - it sees that internet is not available, and thus cannot compare time. And - the things (punch bag, balls, etc) I had to wait to be repaired - are now repaired. Yay.

But If I do the same thing again many many times and finally I want to set back to original date and time - and open application, it will know that there is something not right. It probably stores some last opened timestamps, and if that time is bigger than actual device time - then user probably is doing something bad. And - alert appears - App must connect to server in order to continue.

Another downfall of moving time forward (for user, but great for developer) is - that there are some things, which will auto-regenerate after a while, but needs to be "picked" in order to initiate regenerating again. In clumsy ninja, chicken generates an egg once in a while. If Egg is not picked up, it still holds a timestamp, when it should be / was generated. So - imagine, user successfully forwards time many times (until it is already 1 day ahead of original time) - and now he wants to set the time back to original time, so that clock would actually show correct time. After user does that - when app is opened, time is synced but the generating egg will now show, that it will be ready after 1 day - last saved timestamp. But this could also be used for all items, which require time to be available. Why the clumsy ninja has not used this thing to all items? Maybe they are afraid, that if user sees, that nothing is available for a long time - user will stop playing. Thus - better have a cheater user, than no user at all.

Guntis Treulands
  • 4,764
  • 2
  • 50
  • 72
0
NSURL *url = [NSURL URLWithString:@"http://www.timeapi.org/utc/now"];
NSString *str = [[NSString alloc] initWithContentsOfURL:url usedEncoding:Nil error:Nil];

str = [str stringByReplacingOccurrencesOfString:@"T" withString:@" "];
str = [str stringByReplacingOccurrencesOfString:@"+01:00" withString:@""];

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
NSDate *date = [dateFormat dateFromString:str];
Mike Deluca
  • 1,295
  • 2
  • 18
  • 41