Using a Server to keep Game Time in Sync
I haxored your social game loser!A fundamental part of any social game is the use of time as a mechanic to keep the player coming back.
Be it harvesting crops in 1 hour or waiting for your energy to restore, time is important - and more importantly it can be hacked.
Witness the 10 year old girl at Defcon this year who used a simple date time exploits to hack social games on iOS and Android.
So what can we do to make sure this doesn't happen to us?
Here at Doki Doki Games we use the same server that runs our php code and MySQL databases as a time server.
Whenever the game runs we pull the time from the server.
We also update the time every 60 seconds and whenever the player does anything time related in the prototype we pull the time again.
All time calculations are also done on the sever. If the player sets something 'growing', when it comes to harvesting the time is validated with the time in the database and the time on the server.
To get the time manager working in your code you need an empty GameObject running the time manager code in Unity and a server that runs the php code to pull the time.
Here's our Unity time manager code:
using UnityEngine;
using System.Collections;
using System;
public class timeController : MonoBehaviour
{
// Server address where the time php is located
string serverTimeURL = "http://<your server>/getTime.php?";
public Double second = 0;
// Locally stored game time
static DateTime gameTime;
void Start ()
{
// We set two coroutines going. One for the server time
StartCoroutine(getServerTime(true));
// and one to locally increment the time until the server
// pulls the server time
StartCoroutine(maintainGameTime());
}
IEnumerator getServerTime(bool maintain)
{
// call the php on the server and wait for a return
WWW getWWW;
getWWW = new WWW (serverTimeURL);
yield return getWWW;
// We store the server time in a global so it can be
// accessed by any script. You don't have to do this.
globals.instance.serverTime = getWWW.text;
// This pulls the time form the Server every 60 seconds
if(maintain)
{
yield return new WaitForSeconds(60f);
second = 0;
StartCoroutine(getServerTime(true));
}
}
IEnumerator maintainGameTime()
{
while(1==1)
{
// game time is a local copy of the sever time that we
// increment in Unity. Used by the game for countdowns
// on 'grown' items etc.
gameTime = gameTime.AddSeconds(1);
yield return new WaitForSeconds(1f);
}
}
}
Now for getTime.php:
// We use Singapore because there's no daylight
// saving so we never lose or gain an hour
// all calculations based of of this timezone are
// relative meaning that you never see the actual 'time'
$timezone = new DateTimeZone( "Asia/Singapore" );
$date = new DateTime();
$date->setTimezone( $timezone );
$strDate = $date->format('Y-m-d\TH:i:s.uP');
echo $strDate;
And that is pretty much all you need to get a basic server based time manager up and running in Unity.
But back to that 10 year old hacker for a second. Is this code really all that secure? I mean we are asking the server for the time and returning the date/time in a readable text format with no validation.
In theory, since all the code that sets time in the database is run on the server the worst that can happen is the time looking wrong in the game. All the important mechanics of making sure things happen when they should won't be affected by any interception of the data.

However, like John Cusack in Grosse Point Blank we like our code to have its back against the wall and looking out for hitmen, so in the next installment we'll get into encyprting your sever communication (at both ends) so no one, not even Ms. CyFi herself will be able to fool us.

Doki Doki Games
Reader Comments