108 lines
2.6 KiB
TypeScript
108 lines
2.6 KiB
TypeScript
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<IConf> {
|
|
|
|
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,
|
|
}
|
|
}
|
|
|
|
}
|