• Hello
Search Results for

    Show / Hide Table of Contents

    Universal - Device Time - Detector (Pro)

    Using the current date and time is essential for many applications. However, relying on the clock of the user's device creates trust issues, as users can manipulate it for various purposes such as extending trial periods or gaining advantages in games. AntiCheat has introduced a way to counteract such time manipulation.

    Detector

    The 'DeviceTimeCheatingDetector' (class DeviceTimeCheatingDetector, namespace GUPS.AntiCheat.Detector) detects device or system clock manipulation. It subscribes to the 'DeviceTimeMonitor' and reacts to reported time deviations. In addition, it exposes a trustworthy DateTime.UtcNow, calculated from either an internet time source or the device clock, through GUPS.AntiCheat.Protected.Time.ProtectedTime.

    Observed subject

    The detector subscribes in Awake to the DeviceTimeStatus published by the 'DeviceTimeMonitor' that sits on the same GameObject. If no monitor is present on the same GameObject, the detector logs a warning and stays idle.

    Status

    The detector notifies its observers with a CheatingDetectionStatus, which implements IDetectorStatus:

    public struct CheatingDetectionStatus : IDetectorStatus
    {
        // Probability that the detection is a false positive, in the range [0.0, 1.0].
        public float PossibilityOfFalsePositive { get; }
    
        // The threat rating reported with this detection.
        public uint ThreatRating { get; }
    }
    

    Threat rating and false positives

    • PossibilityOfFalsePositive: 0.35 (fixed) reported with each detection.
    • ThreatRating: default 500 (inspector field, recommended 500). It is high because false positives are unlikely and the impact of clock manipulation is significant.

    Lifecycle and timing

    • Subscribes to the monitor in Awake and captures the application start time (from internet time or the device clock).
    • In Start, it performs a startup check: if the device clock differs from the reference time by more than 15 seconds, it reports cheating immediately.
    • It also reports whenever the monitor sends a non-None deviation.
    • In FixedUpdate it recalculates the trustworthy CurrentUtcTime, and it re-fetches the application start time when the application regains focus or is unpaused.

    Configuration

    • Is Active (isActive, bool, default true) - whether the detector is active and watching.
    • Threat Rating (threatRating, uint, default 500) - the threat rating reported on each detection.
    • On Cheating Detection Event (OnCheatingDetectionEvent) - a UnityEvent raised on every detection; wire up reactions in the inspector without writing an observer.
    • Use Internet Time (useInternetTime, bool, default true) - when enabled, the application start time is fetched from an internet endpoint instead of the device clock.
    • Server Address (serverAddress, string, default https://google.com) - the server used to fetch the current UTC time (read from the response Date header).
    • Server Certificate Hash (serverCertificateHash, string, optional) - the X509 certificate hash used to validate the server. When set, a certificate mismatch is treated as possible tampering. Optional, but enhances security.

    Supported platforms

    The detector is available on all platforms.

    Requirements

    There are no requirements. A 'DeviceTimeMonitor' must be present on the same GameObject. Using internet time requires network access to the configured server.

    How To Use

    Attach a 'DeviceTimeMonitor' (if not already done) and the 'DeviceTimeCheatingDetector' to a child GameObject of the 'AntiCheat-Monitor', then define a reaction to detected cheating.

    Add Monitor Component

    To detect device time manipulation, a source of device time deviation data is required. Add the 'DeviceTimeMonitor' to the same GameObject you attach the 'DeviceTimeCheatingDetector' to. The detector subscribes to the 'DeviceTimeStatus' sent by the monitor.

    Add Detector Component

    Manual

    Add the 'DeviceTimeCheatingDetector' MonoBehavior from the 'GUPS.AntiCheat.Detector' namespace to your 'AntiCheat-Monitor' GameObject, or better, to a child GameObject, next to your 'DeviceTimeMonitor' MonoBehavior.

    Add the 'DeviceTimeCheatingDetector' as a Component.

    Prefab

    There is also a prefab, including the detector and the monitor, which you can directly attach as a GameObject to the 'AntiCheat-Monitor'.

    Add the 'Device Time Cheating Detector' prefab to the 'AntiCheat-Monitor'.

    Settings

    After attaching the 'DeviceTimeCheatingDetector' MonoBehavior to a GameObject, you will see the following in the inspector:

    The settings of the 'DeviceTimeCheatingDetector' Component.

    • General Settings: Define here whether the detector should be active.
    • Threat Rating Settings: Define here the severity of the detected cheating.
    • Observable Settings: Add here callbacks invoked when cheating is detected.
    • Device Time Settings: Apply here the settings used to provide a trustworthy DateTime.UtcNow.

    Runtime

    The detector provides a trustworthy DateTime.UtcNow through the ProtectedTime class, calculated from either the internet time or the device time. Replace your usage of DateTime.UtcNow with GUPS.AntiCheat.Protected.Time.ProtectedTime.UtcNow:

    // Instead of using DateTime.UtcNow, use the UtcNow from GUPS.AntiCheat.Protected.Time.ProtectedTime.
    public static class ProtectedTime
    {
        // The protected Coordinated Universal Time (UTC) DateTime (Read Only). The calculated UTC time, which may differ from the original DateTime.UtcNow 
        // because it is calculated to be as secure and trustworthy as possible.
        public static DateTime UtcNow { get; }
    }
    

    Consume the detection in code

    Besides the inspector event, you can subscribe your own observer. Every detector derives from ADetector and exposes Subscribe(IObserver<IDetectorStatus>), which returns an IDisposable you can dispose to unsubscribe. Get the detector via the AntiCheat-Monitor:

    using System;
    using GUPS.AntiCheat;
    using GUPS.AntiCheat.Core.Detector;
    using GUPS.AntiCheat.Detector;
    using UnityEngine;
    
    public class DeviceTimeDetectionLogger : MonoBehaviour, IObserver<IDetectorStatus>
    {
        private void Start()
        {
            var detector = AntiCheatMonitor.Instance.GetDetector<DeviceTimeCheatingDetector>();
            detector.Subscribe(this);
        }
    
        public void OnNext(IDetectorStatus status)
        {
            Debug.LogWarning($"Device time cheating detected (threat={status.ThreatRating}, fp={status.PossibilityOfFalsePositive}).");
        }
    
        public void OnError(Exception error) { }
        public void OnCompleted() { }
    }
    

    React On Cheating

    When the monitor (data provider) and detector (data validator) are set up, you surely want to react to detected cheating.

    Punisher

    In general, any cheat detected is forwarded to the 'AntiCheat-Monitor', which calculates an overall threat level. Based on the threat level, you can apply punishments by using Punisher components added to a child GameObject of the 'AntiCheat-Monitor'. There are some built-in punishers that you can find here as prefabs:

    The location of the built-in Punisher prefabs.

    Inspector

    You can set a callback in the Unity Inspector view of the detector. This callback is invoked as soon as the specific cheating is detected.

    A list of callbacks invoked when cheating is detected by the detector.

    Code

    If you would like to write a custom listener for the detector, you can attach an observer:

    // Get the detector.
    var detector = AntiCheatMonitor.Instance
          .GetDetector<DeviceTimeCheatingDetector>();
    
    // Subscribe as observer and get notified on inconsistency.
    detector.Subscribe(myObserver);
    

    The detector also has an inherited property 'PossibleCheatingDetected' which is set to true once cheating has been detected.

    In This Article
    Back to top GuardingPearSoftware documentation