github.com/df-mc/dragonfly@v0.9.13/server/session/handler_client_cache_blob_status.go (about) 1 package session 2 3 import ( 4 "github.com/sandertv/gophertunnel/minecraft/protocol" 5 "github.com/sandertv/gophertunnel/minecraft/protocol/packet" 6 ) 7 8 // ClientCacheBlobStatusHandler handles the ClientCacheBlobStatus packet. 9 type ClientCacheBlobStatusHandler struct { 10 } 11 12 // Handle ... 13 func (c *ClientCacheBlobStatusHandler) Handle(p packet.Packet, s *Session) error { 14 pk := p.(*packet.ClientCacheBlobStatus) 15 16 resp := &packet.ClientCacheMissResponse{Blobs: make([]protocol.CacheBlob, 0, len(pk.MissHashes))} 17 18 s.blobMu.Lock() 19 for _, hit := range pk.HitHashes { 20 delete(s.blobs, hit) 21 c.resolveBlob(hit, s) 22 } 23 for _, miss := range pk.MissHashes { 24 blob, ok := s.blobs[miss] 25 if !ok { 26 // This is expected to happen sometimes, for example when we send the same block storage or biomes a lot of 27 // times in a short timeframe. There is no need to log this, it'll just cause unnecessary noise that doesn't 28 // actually aid in terms of information. 29 continue 30 } 31 resp.Blobs = append(resp.Blobs, protocol.CacheBlob{Hash: miss, Payload: blob}) 32 c.resolveBlob(miss, s) 33 } 34 s.blobMu.Unlock() 35 36 if len(resp.Blobs) > 0 { 37 s.writePacket(resp) 38 } 39 return nil 40 } 41 42 // resolveBlob resolves a blob hash in the session passed. It assumes s.blobMu is locked upon calling. 43 func (c *ClientCacheBlobStatusHandler) resolveBlob(hash uint64, s *Session) { 44 leftover := make([]map[uint64]struct{}, 0, len(s.openChunkTransactions)) 45 for _, m := range s.openChunkTransactions { 46 delete(m, hash) 47 if len(m) != 0 { 48 leftover = append(leftover, m) 49 } 50 } 51 s.openChunkTransactions = leftover 52 delete(s.blobs, hash) 53 }