Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions minecraft/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,12 @@ func oidcVerifier(ctx context.Context) (*oidc.IDTokenVerifier, error) {
// use the Conn.ReadPacket() and Conn.WritePacket() methods.
// Accept returns an error if the listener is closed.
func (listener *Listener) Accept() (net.Conn, error) {
conn, ok := <-listener.incoming
if !ok {
select {
case conn := <-listener.incoming:
return conn, nil
case <-listener.close:
return nil, &net.OpError{Op: "accept", Net: "minecraft", Addr: listener.Addr(), Err: net.ErrClosed}
}
return conn, nil
}

// Disconnect disconnects a Minecraft Conn passed by first sending a disconnect with the message passed, and
Expand Down Expand Up @@ -434,8 +435,10 @@ func (listener *Listener) listen() {
}
}()
defer func() {
// listener.incoming is never closed: a connection that finishes logging in at this point may still be
// selecting on it in handleConn, and a send on a closed channel would panic. Accept watches
// listener.close instead.
close(listener.close)
close(listener.incoming)
_ = listener.Close()
}()
for {
Expand Down Expand Up @@ -536,8 +539,8 @@ func (listener *Listener) handleConn(conn *Conn) {
if !loggedInBefore && conn.loggedIn {
select {
case <-listener.close:
// The listener was closed while this one was logged in, so the incoming channel will be
// closed. Just return so the connection is closed and cleaned up.
// The listener was closed while this one was logged in. Just return so the connection is
// closed and cleaned up.
return errListenerClosed
case listener.incoming <- conn:
// The connection was previously not logged in, but was after receiving this packet,
Expand Down