import { EventEmitter } from 'events' import { SERVER_TICK_RATE, SERVER_TPS } from '../utils/constants' import { longToNumber } from '../utils/func' import Module from '../utils/Module' interface IUpdateTime { age: number[] time: number[] } interface IConf { /** Log if server lost ticks */ minTps: number, /** Log if server lost tps */ maxSpt: number, /** Log if client is not in sync */ maxOffset: number } interface IEmitter { on(event: 'tick', listener: (age: number) => void): this } /** Monitor time and ticks */ export default class Time extends Module { private _events = new EventEmitter() public get events(): IEmitter { return this._events } private _age!: number /** Ticks since world creation */ public get age() { return this._age } private _distAge!: number private _time!: number /** Ticks of the day */ public get time() { return this._time } private _tps!: number /** Processed Tick per seconds */ public get tps() { return this._tps } private _spt!: number /** Processed Tick per seconds */ public get spt() { return this._spt } private _at: number = Date.now() private _clock?: NodeJS.Timeout public umount() { if (this._clock) { clearInterval(this._clock) this._clock = undefined } } protected mount() { this.client.on('update_time', (data: IUpdateTime) => { const now = Date.now() const age = longToNumber(data.age) if (this._distAge) { this._tps = age - this._distAge if (this.tps <= this.conf.minTps) { this.logger.debug('Server Lag: %s / 20 tps', this.tps, SERVER_TPS) } this._spt = (now - this._at) / this.tps if (this.spt >= this.conf.maxSpt) { this.logger.debug('Network Lag: %s / %s spt', this.spt, SERVER_TICK_RATE) } const offset = age - this._age if (Math.abs(offset) > this.conf.maxOffset) { this.logger.debug('Client Off-sync %s ticks', offset) } } this._distAge = this._age = age this._at = now this._time = Math.abs(data.time[1]) % 24000 }) this._clock = setInterval(() => this._events.emit('tick', ++this._age), SERVER_TICK_RATE) } protected getConf(): IConf { return { minTps: SERVER_TPS - 1, maxSpt: SERVER_TICK_RATE + 10, maxOffset: 1, } } }