Search Unity

System.DateTime.now and how to avoid time cheats

Discussion in 'Scripting' started by Jay_Santos, Feb 20, 2012.

  1. Jay_Santos

    Jay_Santos

    Joined:
    May 31, 2011
    Posts:
    42
    Hi,

    I want to reward my player if he comes back to my game every day.

    The obvious solution for this would be something like:

    Code (csharp):
    1.     DateTime currentTime = DateTime.Now;
    2.     TimeSpan ts = currentTime - Convert.ToDateTime (GameParameters.lastPlayDate);
    3.     if (ts.TotalHours > 24)
    4.     {
    5.        Debug.Log ("Welcome back, here's a prize for you!");
    6.     }
    But, this approach can be exploited by changing the time and date on my device. I'd like to avoid that, I've look for an answer here, in Unity forums and in game dev in general and I couldn't find any answer...

    Is there any way to avoid this cheat at all? Either locally or, say, getting time and date from a server via Unity?

    Thanks in advance!
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The only way is to use the time on a server. Anything local can be changed.

    --Eric
     
  3. Jay_Santos

    Jay_Santos

    Joined:
    May 31, 2011
    Posts:
    42
    Thanks, Eric. I thought that would be the answer (unfortunately...)

    Do you have any suggestion of time server that I can use?

    Thanks,

    Jay_Santos
     
  4. CrashKonijn

    CrashKonijn

    Joined:
    Mar 4, 2010
    Posts:
    245
    I just wrote this without testing it but it should work. I don't really know what time format you get from unity so you might need to let something else return from the php script to be able to check it with the time in unity, but this script will get you the unix timestamp from the server :)

    for more info about the time/date outputs you can do with php check these 2 links:
    http://www.php.net/manual/en/function.time.php
    http://www.php.net/manual/en/function.date.php

    CommunicationController.js // This is how I always name this script
    Code (csharp):
    1.  
    2. var phpController = "http://yourwebsite.com/folder/phpcontroller.php";
    3.  
    4. function GetServerTime() {
    5.     var posurl : String = phpController + "?action=getservertime";
    6.     var posgetwww : WWW = WWW(posurl);
    7.     //yield posgetwww;
    8.     if(posgetwww.error) {
    9.         // error... epic FAIL!
    10.         print("There was an error saving the level: " + posgetwww.error);
    11.     } else {
    12.         // no errors... WIN!
    13.         return posgetwww.text;
    14.     }
    15. }
    16.  
    phpcontroller.php
    Code (csharp):
    1.  
    2. <?php
    3.     if(isset($_GET['action']) == "getservertime"){
    4.         echo time(); // Outputs the unix timestamp
    5.     }
    6. ?>
    7.  
     
    jonathanandmilan and vexe like this.
  5. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    Rustam-Ganeyev likes this.
  6. Seven007

    Seven007

    Joined:
    Aug 19, 2013
    Posts:
    5
    How about Windows Platform??? Any plugin for window??
     
  7. razielanarki

    razielanarki

    Joined:
    Jun 1, 2014
    Posts:
    58
    you could also use pool.ntp.org to get the network time like so (obviously you'll need to be online for this, but you won't need your own server script):

    Code (CSharp):
    1.     public static double NtpTime ()
    2.     {
    3.         try
    4.         {
    5.             byte[] ntpData = new byte[48];
    6.      
    7.             //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)
    8.             ntpData[0] = 0x1B;
    9.      
    10.             IPAddress[] addresses = Dns.GetHostEntry ("pool.ntp.org").AddressList;
    11.             Socket socket = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    12.      
    13.             socket.Connect (new IPEndPoint (addresses[0], 123));
    14.             socket.ReceiveTimeout = 1000;
    15.      
    16.             socket.Send (ntpData);
    17.             socket.Receive (ntpData);
    18.             socket.Close ();
    19.      
    20.             ulong intc = (ulong) ntpData[40] << 24 | (ulong) ntpData[41] << 16 | (ulong) ntpData[42] << 8 | (ulong) ntpData[43];
    21.             ulong frac = (ulong) ntpData[44] << 24 | (ulong) ntpData[45] << 16 | (ulong) ntpData[46] << 8 | (ulong) ntpData[47];
    22.      
    23.             return (double) ((intc * 1000) + ((frac * 1000) / 0x100000000L));
    24.         }
    25.         catch (Exception exception)
    26.         {
    27.             Debug.Log ("Could not get NTP time");
    28.             Debug.Log (exception);
    29.             return LocalTime ();
    30.         }
    31.     }
    32.  
    33.     public static double LocalTime ()
    34.     {
    35.         return DateTime.Now.Subtract (new DateTime (1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
    36.     }
     
  8. inxidious

    inxidious

    Joined:
    Nov 8, 2013
    Posts:
    22
    Thanks, helped me a lot.
    I'm just wondering why NtpTime return TotalMilliseconds, but LocalTime return TotalSeconds instead?
     
  9. Quantum_Surt

    Quantum_Surt

    Joined:
    Apr 25, 2015
    Posts:
    39
    Hi, how to you convert it in seconds and minutes ? and how to make a difference ?

    thank you

     
    Last edited: Aug 17, 2017
  10. KingKong320

    KingKong320

    Joined:
    Mar 2, 2018
    Posts:
    21