[Unity]正しい現在時刻を取得して不正を防ぎたい

放置ゲーム(に限らないですけど)で、現在時刻から経過時間を〜〜とか、
デイリーボーナスで〜〜とかそんな時間を絡めた何かをする場合、
デバイス時刻だとちょっぴり不安になりますよね?
ってことで

デバイス時刻に頼らずに現在時刻を取得したい!

です(ちなみに僕が今現在必要としているわけではありません。何故書いたし...(笑))

Unity v2017.2

なぜデバイス時刻だと心配なのか?

いうまでもなく、ちゃちゃっと変えられるからですね...。
6時間後に何かストーリーとかが進むぞ!って言う仕様なんかのときに、まちきれない場合はデバイス時刻を設定などからちゃちゃっとすすめちゃって、
6時間待たずともじゃんじゃか進められる!みたいなことができちゃうわけですね...。

まぁ、ゲーム仕様根幹にかかわらない...とか、他ユーザに何か影響があるわけではない...とかの場合なら、
見て見ぬふりしちゃって、そこまで頑張るならもうやっちゃっていいよ?と構えるのも、個人開発なら悪くないチョイスだと思いますが...
そうじゃない場合は、やっぱりなんとか制御したい!となるわけです

デバイス時刻に依存しないで取得する

自前で何かサーバを持っている場合は、ちゃちゃっとapiのエンドポイントを1つ追加して、サーバから現在時刻を返すようにしたらokでしょう。

自前サーバなんてもってないし、もちたくないし...サーバってなにおいしいの水煮系?味噌系?って言う人にはちょっと...という感じですよね。
ってことで、公開されているNTPサーバを利用してデバイス時刻に依存せずに現在時刻を取得しちゃおう!ということです。

NTPサーバから取得するぞ

NICT様が2008年からNTPサーバを公開していて、json形式で時刻の配信をしています!
(ありがたや🙏)

ってことで、これを利用して現在時刻を取得しちゃいます!💪
jsonで配信してくれてるのは話は早くて...やることはすごく単純。

  • UnityWebRequestをつかって該当URLにアクセス
  • 取ってきたjsonをJsonUtility.FromJson()を使ってマッピング
  • あとは、それをお好きにつかっちゃう!

という感じ。

ってことで、そこらをよしなにするコンポーネントをつくってみました

使う場合は..

public class NTPChecker: MonoBehaviour
{
    [SerializeField] private NTP ntp;
    
    void Start()
    {
        this.ntp.GetTimestamp((timestamp) => {
            Debug.Log(timestamp);
        });
    }
}

みたいな感じでいけるはずです〜〜
Timestamp()は拡張メソッドなのであしからず。。😇

いやまぁ、自分で使う予定がないので...なにかおかしなとこアレばフィードバック下さい(笑)

参考

anzfactory/Unity-Utils
自分用に便利系を集めている(笑)

gist-it
GitHubのファイルを埋め込めちゃうサービスみたい
gistで書いてなかったんでどうしようかとおもったらみつけました