fix: resolve nethernet connection, ban deadlock, and nil RemoteAddr crashes
This commit is contained in:
+47
-8
@@ -349,33 +349,64 @@ func (srv *Server) listen(l Listener) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
srv.conf.Log.Error(fmt.Sprintf("panic handling connection: %v", r))
|
||||
_ = c.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
name := c.IdentityData().DisplayName
|
||||
xuid := c.IdentityData().XUID
|
||||
uuidStr := c.IdentityData().Identity
|
||||
|
||||
// Safely extract IP - nethernet/local connections may
|
||||
// return nil RemoteAddr or non-standard address formats.
|
||||
ip := ""
|
||||
if addr := c.RemoteAddr(); addr != nil {
|
||||
if host, _, err := net.SplitHostPort(addr.String()); err == nil {
|
||||
ip = host
|
||||
} else {
|
||||
ip = addr.String()
|
||||
addrStr := addr.String()
|
||||
if addrStr != "" {
|
||||
if host, _, err := net.SplitHostPort(addrStr); err == nil {
|
||||
ip = host
|
||||
} else {
|
||||
ip = addrStr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srv.conf.Log.Debug("Player connecting...", "name", name, "xuid", xuid, "ip", ip)
|
||||
|
||||
// Check if player is banned (by name, XUID, or UUID only - not IP).
|
||||
if entry, banned := player.Bans.IsBanned(name, xuid, uuidStr, ip); banned {
|
||||
msg := "You are banned from this server."
|
||||
if entry.Reason != "" {
|
||||
msg += " Reason: " + entry.Reason
|
||||
}
|
||||
if !entry.ExpiresAt.IsZero() {
|
||||
timeLeft := time.Until(entry.ExpiresAt).Round(time.Second)
|
||||
msg = fmt.Sprintf("You are banned from this server. Remaining time: %v", timeLeft)
|
||||
if timeLeft > 0 {
|
||||
msg += fmt.Sprintf(" Remaining: %v", timeLeft)
|
||||
}
|
||||
}
|
||||
srv.conf.Log.Debug("Player banned, rejecting.", "name", name)
|
||||
_ = c.WritePacket(&packet.Disconnect{Message: msg})
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
if srv.PlayerCount() >= 14 && !strings.EqualFold(name, "XTarnaWijaya") && !strings.EqualFold(name, "TarnaWijaya") {
|
||||
|
||||
// Use the configured MaxPlayerCount instead of a hardcoded value.
|
||||
// Admins bypass the player limit.
|
||||
if srv.PlayerCount() >= srv.MaxPlayerCount() &&
|
||||
!strings.EqualFold(name, "XTarnaWijaya") &&
|
||||
!strings.EqualFold(name, "TarnaWijaya") {
|
||||
srv.conf.Log.Debug("Server full, rejecting.", "name", name)
|
||||
_ = c.WritePacket(&packet.Disconnect{Message: "Server is full."})
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
|
||||
if msg, ok := srv.conf.Allower.Allow(c.RemoteAddr(), c.IdentityData(), c.ClientData()); !ok {
|
||||
srv.conf.Log.Debug("Player not allowed.", "name", name, "msg", msg)
|
||||
_ = c.WritePacket(&packet.Disconnect{HideDisconnectionScreen: msg == "", Message: msg})
|
||||
_ = c.Close()
|
||||
return
|
||||
@@ -469,12 +500,20 @@ func (srv *Server) finaliseConn(ctx context.Context, conn session.Conn, l Listen
|
||||
if err := conn.StartGameContext(ctx, data); err != nil {
|
||||
_ = l.Disconnect(conn, "Connection timeout.")
|
||||
|
||||
srv.conf.Log.Debug("spawn failed: "+err.Error(), "raddr", conn.RemoteAddr())
|
||||
raddr := "nethernet"
|
||||
if addr := conn.RemoteAddr(); addr != nil {
|
||||
raddr = addr.String()
|
||||
}
|
||||
srv.conf.Log.Debug("spawn failed: "+err.Error(), "raddr", raddr)
|
||||
return
|
||||
}
|
||||
if _, ok := srv.Player(id); ok {
|
||||
_ = l.Disconnect(conn, "Already logged in.")
|
||||
srv.conf.Log.Debug("spawn failed: already logged in", "raddr", conn.RemoteAddr())
|
||||
raddr := "nethernet"
|
||||
if addr := conn.RemoteAddr(); addr != nil {
|
||||
raddr = addr.String()
|
||||
}
|
||||
srv.conf.Log.Debug("spawn failed: already logged in", "raddr", raddr)
|
||||
return
|
||||
}
|
||||
_ = conn.WritePacket(&packet.ItemRegistry{Items: srv.customItems})
|
||||
|
||||
Reference in New Issue
Block a user