Fix Windows socket WSAENOTCONN disconnect; add boss encounter frames

Socket fixes (fixes Windows-only connection failure):
- WorldSocket::connect() now waits for non-blocking connect to complete with
  select() before returning, preventing WSAENOTCONN on the first recv() call
  on Windows (Linux handles this implicitly but Windows requires writability
  poll after non-blocking connect)
- Add net::isConnectionClosed() helper: treats WSAENOTCONN/WSAECONNRESET/
  WSAESHUTDOWN/WSAECONNABORTED as graceful peer-close rather than recv errors
- Apply isConnectionClosed() in both WorldSocket and TCPSocket recv loops

UI:
- Add renderBossFrames(): displays boss unit health bars in top-right corner
  when SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT has active slots; supports
  click-to-target and color-coded health bars (red→orange→yellow as HP drops)
This commit is contained in:
Kelsi 2026-03-09 20:05:09 -07:00
parent b6dfa8b747
commit 1c1cdf0f23
6 changed files with 135 additions and 1 deletions

View file

@ -91,6 +91,20 @@ inline bool isWouldBlock(int err) {
#endif
}
// Returns true for errors that mean the peer closed the connection cleanly.
// On Windows, WSAENOTCONN / WSAECONNRESET / WSAESHUTDOWN can be returned by
// recv() when the server closes the connection, rather than returning 0.
inline bool isConnectionClosed(int err) {
#ifdef _WIN32
return err == WSAENOTCONN || // socket not connected (server closed)
err == WSAECONNRESET || // connection reset by peer
err == WSAESHUTDOWN || // socket shut down
err == WSAECONNABORTED; // connection aborted
#else
return err == ENOTCONN || err == ECONNRESET;
#endif
}
inline bool isInProgress(int err) {
#ifdef _WIN32
return err == WSAEWOULDBLOCK || err == WSAEALREADY;