LasTres/js-src/input-packets.ts

212 lines
8.5 KiB
TypeScript

import type { PJ } from '@lastres/pj'
import type { Location } from '@lastres/location'
import type InputPacket from '@lastres/input-packet'
import type { LogLine } from '@lastres/log-line'
import type { ActionHash } from '@lastres/action'
import type { TalkNPCs } from '@lastres/talk-npc'
import type { Words } from '@lastres/word'
import InputPacketInfo from '@lastres/input-packet/info'
import InputPacketPong from '@lastres/input-packet/pong'
type SetTeamPJs = (set: PJ[] | null) => void
type SetIsBattling = (set: boolean | null) => void
type SetEnemyTeamPJs = (set: PJ[] | null) => void
type SetCurrentLocation = (set: Location | null) => void
type SetConnectedLocations = (set: Location[] | null) => void
type DispatchHash = Record<string, any>
type SetLogLinesCallback = (set: LogLine[] | null) => LogLine[]
type SetLogLines = (set: LogLine[] | SetLogLinesCallback | null) => void
type SetError = (set: string | null) => void
type SetScrollLogCallback = (set: number | null) => number | null
type SetScrollLog = (set: number | null | SetScrollLogCallback) => void
type LogPresentationRef = React.RefObject<HTMLDivElement>
type SetMovingTo = (set: Location | null) => void
type SetRemainingFrames = (set: number | null) => void
type SetActionHash = (set: ActionHash | null) => void
type SetTalkNPCs = (set: TalkNPCs | null) => void
type SetWords = (set: Words | null) => void
interface Packet {
command: string
data: any
}
type LogHash = Record<string, LogLine>
export default class InputPackets {
setTeamPJs: SetTeamPJs
setEnemyTeamPJs: SetEnemyTeamPJs
setIsBattling: SetIsBattling
setCurrentLocation: SetCurrentLocation
setConnectedLocations: SetConnectedLocations
setLogLines: SetLogLines
logLines: LogLine[] | null
cachedHash: DispatchHash | null = null
cachedArray: InputPacket[] | null = null
setError: SetError
setScrollLog: SetScrollLog
logPresentationRef: LogPresentationRef
setMovingTo: SetMovingTo
setRemainingFrames: SetRemainingFrames
setActionHash: SetActionHash
setTalkNPCs: SetTalkNPCs
setWords: SetWords
constructor (setTeamPJs: SetTeamPJs,
setEnemyTeamPJs: SetEnemyTeamPJs,
setIsBattling: SetIsBattling,
setCurrentLocation: SetCurrentLocation,
setConnectedLocations: SetConnectedLocations,
logLines: LogLine[] | null,
setLogLines: SetLogLines,
setError: SetError,
setScrollLog: SetScrollLog,
logPresentationRef: LogPresentationRef,
setMovingTo: SetMovingTo,
setRemainingFrames: SetRemainingFrames,
setActionHash: SetActionHash,
setTalkNPCs: SetTalkNPCs,
setWords: SetWords) {
this.setTeamPJs = setTeamPJs
this.setEnemyTeamPJs = setEnemyTeamPJs
this.setCurrentLocation = setCurrentLocation
this.setConnectedLocations = setConnectedLocations
this.logLines = logLines
this.setLogLines = setLogLines
this.setError = setError
this.setScrollLog = setScrollLog
this.logPresentationRef = logPresentationRef
this.setMovingTo = setMovingTo
this.setRemainingFrames = setRemainingFrames
this.setIsBattling = setIsBattling
this.setActionHash = setActionHash
this.setTalkNPCs = setTalkNPCs
this.setWords = setWords
}
handle (packet: Packet): void {
const hash = this.hashAvailablePackets()
const identifier = packet.command
const inputPacket = hash[identifier]
inputPacket.recv(packet)
}
listAvailablePackets (): InputPacket[] {
let firstTime = true
if (this.cachedArray === null) {
const infoPacket = new InputPacketInfo()
const pongPacket = new InputPacketPong()
infoPacket.onReceive((data) => {
const logPresentationRef = this.logPresentationRef
let scrollData: number[] = []
function saveScroll (): void {
if (logPresentationRef.current === null) {
return
}
scrollData = [
logPresentationRef.current.scrollHeight,
logPresentationRef.current.scrollTop,
logPresentationRef.current.offsetHeight
]
}
function applyScroll (): void {
if (scrollData.length < 3) {
return
}
if (logPresentationRef.current === null) {
console.log('Not defined')
return
}
const logPresentation = logPresentationRef.current
const [scrollHeight, scrollTop, offsetHeight] = scrollData
if (firstTime) {
firstTime = false
logPresentation.scrollTo(0, logPresentation.scrollHeight)
return
}
if (scrollHeight <= scrollTop + offsetHeight * (3 / 2)) {
logPresentation.scrollTo(0, logPresentation.scrollHeight)
}
}
if (data.error !== undefined) {
this.setError(data.error)
return
}
if (data.team_pjs !== undefined) {
this.setTeamPJs(data.team_pjs)
}
if (data.enemy_team_pjs !== undefined) {
this.setEnemyTeamPJs(data.enemy_team_pjs)
}
if (data.is_battling !== undefined) {
this.setIsBattling(data.is_battling)
}
if (data.location_data !== undefined) {
console.log(data.location_data)
if (data.location_data.connected_places !== undefined) {
this.setConnectedLocations(data.location_data.connected_places)
}
if (data.location_data.current !== undefined) {
this.setCurrentLocation(data.location_data.current)
}
if (data.location_data.moving_to !== undefined) {
this.setMovingTo(data.location_data.moving_to)
} else {
this.setMovingTo(null)
}
}
if (data.npcs !== undefined) {
this.setTalkNPCs(data.npcs)
}
if (data.remaining_frames !== undefined) {
this.setRemainingFrames(data.remaining_frames)
}
if (data.set_log !== undefined) {
saveScroll()
this.setLogLines(data.set_log)
window.setTimeout(() => {
applyScroll()
}, 10)
}
if (data.known_words !== undefined) {
this.setWords(data.known_words)
}
if (data.append_log !== undefined) {
const logHash: LogHash = {}
saveScroll()
this.setLogLines((logLines: LogLine[] | null): LogLine[] => {
if (logLines !== null) {
for (const item of logLines) {
logHash[item.uuid] = item
}
logHash[data.append_log.uuid] = data.append_log
const outputLog: LogLine[] = Object.keys(logHash).map((item, i): LogLine => {
return logHash[item]
})
return outputLog
}
return []
})
window.setTimeout(() => {
applyScroll()
}, 10)
}
if (data.available_actions !== undefined) {
this.setActionHash(data.available_actions)
}
})
this.cachedArray = [infoPacket, pongPacket]
}
return this.cachedArray
}
hashAvailablePackets (): DispatchHash {
if (this.cachedHash === null) {
this.cachedHash = {}
for (const inputPacket of this.listAvailablePackets()) {
this.cachedHash[inputPacket.identifier()] = inputPacket
}
}
return this.cachedHash
}
}