/************************************************************************/ /* BattlEye Server code */ /************************************************************************/ #include "../server/server.h" #include "winquake.h" extern qboolean Sys_StringToSockaddr(char *s, struct sockaddr *sadr); #ifdef BATTLEYE static SOCKET mastersocket = INVALID_SOCKET; qboolean SV_BE_ConnectToMaster(void) { unsigned long _true = 1; struct sockaddr masteraddress; SV_BE_DisconnectFromMaster(); // create a TCP socket if ((mastersocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { Com_Printf("ERROR: SV_BE_ConnectToMaster: socket: %s\n", NET_ErrorString()); return qfalse; } // make it non-blocking if (ioctlsocket(mastersocket, FIONBIO, &_true) == SOCKET_ERROR) { Com_Printf("ERROR: SV_BE_ConnectToMaster: ioctlsocket FIONBIO: %s\n", NET_ErrorString()); return qfalse; } // resolve BE Master DNS host name if (!Sys_StringToSockaddr(BATTLEYE_MASTERSERVER, &masteraddress)) { Com_Printf("ERROR: SV_BE_ConnectToMaster: Sys_StringToSockaddr: %s\n", NET_ErrorString()); return qfalse; } if (connect(mastersocket, &masteraddress, sizeof(masteraddress)) == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { Com_Printf("ERROR: SV_BE_ConnectToMaster: connect: %s\n", NET_ErrorString()); return qfalse; } return qtrue; } int SV_BE_CheckConnectAttempt(void) { TIMEVAL timeout = { 0, 0 }; fd_set success_set, failure_set; FD_ZERO(&success_set); FD_SET(mastersocket, &success_set); FD_ZERO(&failure_set); FD_SET(mastersocket, &failure_set); if (select(0, NULL, &success_set, &failure_set, &timeout) == SOCKET_ERROR) { Com_Printf("ERROR: SV_BE_CheckConnectAttempt: select: %s\n", NET_ErrorString()); return -1; } if (FD_ISSET(mastersocket, &success_set)) return 1; else if (FD_ISSET(mastersocket, &failure_set)) { int error; int errlen = sizeof(error); getsockopt(mastersocket, SOL_SOCKET, SO_ERROR, (char *)&error, &errlen); WSASetLastError(error); return -1; } else return 0; } void SV_BE_SendToMaster(void* buf, int len) { send(mastersocket, buf, len, 0); } int SV_BE_ReceiveFromMaster(void* buf, int len) { int result = recv(mastersocket, buf, len, 0); if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) return 0; else if (result == SOCKET_ERROR || result == 0 || result != len) return -1; else return 1; } void SV_BE_DisconnectFromMaster(void) { if (mastersocket != INVALID_SOCKET) { closesocket(mastersocket); mastersocket = INVALID_SOCKET; } } #endif // BATTLEYE