• Hello
Search Results for

    Show / Hide Table of Contents

    Universal - Device Time - Detector (Pro)

    Many games use the device clock for trials, daily rewards, or timers. The player can change that clock. This detector notices the change and gives you a safer UTC time.

    Walkthrough: Protecting against device clock cheating.

    Detector

    DeviceTimeCheatingDetector (namespace GUPS.AntiCheat.Detector) watches for a moved device clock. It listens to DeviceTimeMonitor. It also exposes a safer DateTime.UtcNow through GUPS.AntiCheat.Protected.Time.ProtectedTime. That time can come from the internet or from the device clock.

    Observed subject

    In Awake, the detector subscribes to DeviceTimeStatus from the DeviceTimeMonitor on the same object. If that monitor is missing, the detector logs a warning and does nothing.

    Status

    The detector sends a CheatingDetectionStatus:

    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) on each report.
    • ThreatRating: default 500 (recommended 500). False alarms are unlikely, and a moved clock matters a lot.

    Lifecycle and timing

    • In Awake it subscribes to the monitor. It also stores the app start time, from the internet or from the device clock.
    • In Start it checks once. If the device clock is more than 15 seconds away from the reference, it reports cheating right away.
    • It also reports when the monitor sends a deviation that is not None.
    • In FixedUpdate it updates CurrentUtcTime. When the app gets focus or leaves pause, it fetches the start time again.

    Configuration

    • Is Active (isActive, bool, default true): Turns the detector on or off.
    • Threat Rating (threatRating, uint, default 500): How much one find adds to the threat score.
    • On Cheating Detection Event (OnCheatingDetectionEvent): Functions to call when a cheat is found.
    • Use Internet Time (useInternetTime, bool, default true): When on, the start time comes from a web server instead of the device clock.
    • Server Address (serverAddress, string, default https://google.com): The server used to read the current UTC time. The time comes from the response Date header.
    • Server Certificate Hash (serverCertificateHash, string, optional): A certificate hash used to check the server. If it does not match, that is treated as possible tampering. Optional, but safer.

    Supported platforms

    Every platform.

    Requirements

    None, except a DeviceTimeMonitor on the same object. Internet time needs a network connection to the server you set.

    How to use

    Add DeviceTimeMonitor if it is not there yet, and add DeviceTimeCheatingDetector as a child of the AntiCheat-Monitor. Then choose how you want to react.

    Add the monitor

    The detector needs the monitor's reports. Put DeviceTimeMonitor on the same object. The detector subscribes to DeviceTimeStatus.

    Add the detector

    Manual

    Add DeviceTimeCheatingDetector from GUPS.AntiCheat.Detector, next to the monitor. A child of the AntiCheat-Monitor is the best place.

    Add the DeviceTimeCheatingDetector component.

    Prefab

    The prefab includes the detector and the monitor.

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

    Settings

    The DeviceTimeCheatingDetector settings.

    • General Settings: Turn the detector on or off.
    • Threat Rating Settings: How serious one find is.
    • Observable Settings: Functions to call when cheating is found.
    • Device Time Settings: How the safer UTC time is built.

    Runtime

    Use ProtectedTime.UtcNow instead of DateTime.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; }
    }
    

    Read the detection in code

    You can also listen yourself. Subscribe returns an IDisposable. Dispose it when you want to stop.

    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 when a cheat is found

    The detector tells the AntiCheat-Monitor. The monitor adds the report to the threat score.

    Punisher. Add a punisher prefab as a child of the monitor. It runs when the score reaches its limit.

    Built-in punisher prefabs.

    Inspector. Add a function to On Cheating Detection Event. It runs when this detector finds a cheat.

    Inspector callbacks on a detector.

    Code.

    var detector = AntiCheatMonitor.Instance
          .GetDetector<DeviceTimeCheatingDetector>();
    
    detector.Subscribe(myObserver);
    

    PossibleCheatingDetected stays true after the first find.

    In This Article
    Back to top GuardingPearSoftware documentation