diff --git a/minecraft/conn.go b/minecraft/conn.go index 39ab0740..392d8207 100644 --- a/minecraft/conn.go +++ b/minecraft/conn.go @@ -120,6 +120,12 @@ type Conn struct { // be able to join the server. If they don't accept, they can only leave the server. texturePacksRequired bool packQueue *resourcePackQueue + // downloadResourcePack is an optional function passed to a Dial() call. If set, each resource pack received + // from the server will call this function to see if it should be downloaded or not. + downloadResourcePack func(id uuid.UUID, version string) bool + // ignoredResourcePacks is a slice of resource packs that are not being downloaded due to the downloadResourcePack + // func returning false for the specific pack. + ignoredResourcePacks []exemptedResourcePack cacheEnabled bool @@ -825,6 +831,14 @@ func (conn *Conn) handleResourcePacksInfo(pk *packet.ResourcePacksInfo) error { conn.packQueue.packAmount-- continue } + if conn.downloadResourcePack != nil && !conn.downloadResourcePack(uuid.MustParse(pack.UUID), pack.Version) { + conn.ignoredResourcePacks = append(conn.ignoredResourcePacks, exemptedResourcePack{ + uuid: pack.UUID, + version: pack.Version, + }) + conn.packQueue.packAmount-- + continue + } // This UUID_Version is a hack Mojang put in place. packsToDownload = append(packsToDownload, pack.UUID+"_"+pack.Version) conn.packQueue.downloadingPacks[pack.UUID] = downloadingPack{ @@ -840,6 +854,14 @@ func (conn *Conn) handleResourcePacksInfo(pk *packet.ResourcePacksInfo) error { conn.packQueue.packAmount-- continue } + if conn.downloadResourcePack != nil && !conn.downloadResourcePack(uuid.MustParse(pack.UUID), pack.Version) { + conn.ignoredResourcePacks = append(conn.ignoredResourcePacks, exemptedResourcePack{ + uuid: pack.UUID, + version: pack.Version, + }) + conn.packQueue.packAmount-- + continue + } // This UUID_Version is a hack Mojang put in place. packsToDownload = append(packsToDownload, pack.UUID+"_"+pack.Version) conn.packQueue.downloadingPacks[pack.UUID] = downloadingPack{ @@ -905,6 +927,11 @@ func (conn *Conn) hasPack(uuid string, version string, hasBehaviours bool) bool conn.packMu.Lock() defer conn.packMu.Unlock() + for _, ignored := range conn.ignoredResourcePacks { + if ignored.uuid == uuid && ignored.version == version { + return true + } + } for _, pack := range conn.resourcePacks { if pack.UUID() == uuid && pack.Version() == version && pack.HasBehaviours() == hasBehaviours { return true diff --git a/minecraft/dial.go b/minecraft/dial.go index 7af393f2..25119225 100644 --- a/minecraft/dial.go +++ b/minecraft/dial.go @@ -54,6 +54,11 @@ type Dialer struct { // from which the packet originated, and the destination address. PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr) + // DownloadResourcePack is called individually for every texture and behaviour pack sent by the connection when + // using Dialer.Dial(), and can be used to stop the pack from being downloaded. The function is called with the UUID + // and version of the resource pack, and the boolean returned determines if the pack will be downloaded or not. + DownloadResourcePack func(id uuid.UUID, version string) bool + // Protocol is the Protocol version used to communicate with the target server. By default, this field is // set to the current protocol as implemented in the minecraft/protocol package. Note that packets written // to and read from the Conn are always any of those found in the protocol/packet package, as packets @@ -169,6 +174,7 @@ func (d Dialer) DialContext(ctx context.Context, network, address string) (conn conn.identityData = d.IdentityData conn.clientData = d.ClientData conn.packetFunc = d.PacketFunc + conn.downloadResourcePack = d.DownloadResourcePack conn.cacheEnabled = d.EnableClientCache // Disable the batch packet limit so that the server can send packets as often as it wants to.