package psn import ( "github.com/jwetzell/psn-go/internal/chunks" "github.com/jwetzell/psn-go/internal/decoders" ) type Decoder struct { infoPacketFrames map[uint8][]chunks.InfoPacketChunk dataPacketFrames map[uint8][]chunks.DataPacketChunk Trackers map[uint16]*Tracker SystemName string } func NewDecoder() *Decoder { var decoder Decoder decoder.infoPacketFrames = map[uint8][]chunks.InfoPacketChunk{} decoder.dataPacketFrames = map[uint8][]chunks.DataPacketChunk{} decoder.Trackers = map[uint16]*Tracker{} return &decoder } func (d *Decoder) updateInfo(framePackets []chunks.InfoPacketChunk) { for _, framePacket := range framePackets { d.SystemName = framePacket.Data.SystemName.Data.SystemName for _, infoTrackerChunk := range framePacket.Data.TrackerList.Data.Trackers { tracker, ok := d.Trackers[infoTrackerChunk.Chunk.Header.Id] if ok { tracker.UpdateInfo(infoTrackerChunk) } else { d.Trackers[infoTrackerChunk.Chunk.Header.Id] = TrackerFromInfo(infoTrackerChunk) } } } } func (d *Decoder) updateData(framePackets []chunks.DataPacketChunk) { for _, framePacket := range framePackets { for _, dataTrackerChunk := range framePacket.Data.TrackerList.Data.Trackers { tracker, ok := d.Trackers[dataTrackerChunk.Chunk.Header.Id] if ok { tracker.UpdateData(dataTrackerChunk) } else { d.Trackers[dataTrackerChunk.Chunk.Header.Id] = TrackerFromData(dataTrackerChunk) } } } } func (d *Decoder) Decode(bytes []byte) error { chunk, err := decoders.DecodeChunk(bytes) if err != nil { return err } switch chunk.Header.Id { case 0x6756: infoPacket, err := decoders.DecodeInfoPacketChunk(bytes) if err != nil { return err } currentInfoPacketHeader := infoPacket.Data.PacketHeader _, ok := d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId] if !ok { d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId] = []chunks.InfoPacketChunk{} } d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId] = append(d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId], infoPacket) if len(d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId]) == int(currentInfoPacketHeader.Data.FramePacketCount) { d.updateInfo(d.infoPacketFrames[currentInfoPacketHeader.Data.FrameId]) delete(d.infoPacketFrames, currentInfoPacketHeader.Data.FrameId) } case 0x6755: dataPacket, err := decoders.DecodeDataPacketChunk(bytes) if err != nil { return err } currentInfoPacketHeader := dataPacket.Data.PacketHeader _, ok := d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId] if !ok { d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId] = []chunks.DataPacketChunk{} } d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId] = append(d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId], dataPacket) if len(d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId]) == int(currentInfoPacketHeader.Data.FramePacketCount) { d.updateData(d.dataPacketFrames[currentInfoPacketHeader.Data.FrameId]) delete(d.dataPacketFrames, currentInfoPacketHeader.Data.FrameId) } } return nil }