📄 mserv.c
字号:
} if (GetServersList()) CONS_Printf("cannot get server list\n"); CloseConnection();}static char *int2str(int n){ int i; static char res[16]; res[15] = '\0'; res[14] = (n%10)+'0'; for (i=13; (n /= 10); i--) res[i] = (n%10)+'0'; return &res[i+1];}int ConnectionFailed(void){ con_state = MSCS_FAILED; CONS_Printf("Connexion to master server failed\n"); CloseConnection(); return MS_CONNECT_ERROR;}static int AddToMasterServer(void){ static int retry = 0; int i, j, res; msg_t msg; msg_server_t *info = (msg_server_t *) msg.buffer; fd_set tset; memcpy(&tset, &wset, sizeof(tset)); res = select(socket_fd, NULL, &tset, NULL, &select_timeout); if (res == 0) { if (retry++ > 30) // an about 30 second timeout { retry = 0; return ConnectionFailed(); } return MS_CONNECT_ERROR; } retry = 0; if (res < 0) return ConnectionFailed(); // so, the socket is writable, but what does that mean, that the connection is // ok, or bad... let see that! j = 4; getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, (size_t *)&j); if (i != 0) // it was bad return ConnectionFailed(); strcpy(info->header, ""); strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, cv_servername.string); sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); strcpy(registered_server.name, cv_servername.string); msg.type = ADD_SERVER_MSG; msg.length = sizeof(msg_server_t); if (MS_Write(&msg) < 0) return ConnectionFailed(); CONS_Printf("The server has been registered on the master server...\n"); con_state = MSCS_REGISTERED; CloseConnection(); return MS_NO_ERROR;}static int RemoveFromMasterSever(void){ msg_t msg; msg_server_t *info = (msg_server_t *) msg.buffer; strcpy(info->header, ""); strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, registered_server.name); sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); msg.type = REMOVE_SERVER_MSG; msg.length = sizeof(msg_server_t); if (MS_Write(&msg) < 0) return MS_WRITE_ERROR; return MS_NO_ERROR;}char *GetMasterServerPort(void){ char *t = cv_masterserver.string; while ((*t != ':') && (*t != '\0')) t++; if (*t) return ++t; else return DEF_PORT;}char *GetMasterServerIP(void){ static char str_ip[64]; char *t = str_ip; strcpy(t, cv_masterserver.string); while ((*t != ':') && (*t != '\0')) t++; *t = '\0'; return str_ip;}static void openUdpSocket(){#ifdef NEWCODE if( I_NetMakeNode ) { char hostname[24]; sprintf(hostname, "%s:%d", inet_ntoa(addr.sin_addr), atoi(GetMasterServerPort())+1); msnode = I_NetMakeNode(hostname); } else msnode = -1;#else memset(&udp_addr, 0, sizeof(udp_addr)); udp_addr.sin_family = AF_INET; udp_addr.sin_port = htons(atoi(GetMasterServerPort())+1); udp_addr.sin_addr.s_addr = addr.sin_addr.s_addr; // same IP as for TCP#endif}void RegisterServer(int s, int port){ CONS_Printf("Registering this server to the master server...\n"); strcpy(registered_server.ip, GetMasterServerIP()); strcpy(registered_server.port, GetMasterServerPort()); //current_port = port; //mysocket = s; if (MS_Connect(registered_server.ip, registered_server.port, 1)) { CONS_Printf("cannot connect to the master server\n"); return; } openUdpSocket(); // keep the TCP connection open until AddToMasterServer() is completed;}void SendPingToMasterServer(void){ static tic_t next_time = 0; tic_t cur_time; cur_time = I_GetTime(); if (cur_time > next_time) // ping every 2 second if possible { next_time = cur_time+2*TICRATE; if (con_state == MSCS_WAITING) AddToMasterServer(); if (con_state != MSCS_REGISTERED) return; // cur_time is just a dummy data to send#ifdef NEWCODE *((tic_t *)netbuffer) = cur_time; doomcom->datalength = sizeof(cur_time); doomcom->remotenode = msnode; I_NetSend();#else sendto(mysocket, (char*)&cur_time, sizeof(cur_time), 0, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr));#endif }}void UnregisterServer(){ if (con_state != MSCS_REGISTERED) { con_state = MSCS_NONE; CloseConnection(); return; } con_state = MSCS_NONE; CONS_Printf("Unregistering this server to the master server...\n"); if (MS_Connect(registered_server.ip, registered_server.port, 0)) { CONS_Printf("cannot connect to the master server\n"); return; } if (RemoveFromMasterSever() < 0) CONS_Printf("cannot remove this server from the master server\n"); CloseConnection();#ifdef NEWCODE I_NetFreeNodenum( msnode );#endif}/*** MS_GetIP()*/static int MS_GetIP(char *hostname){ struct hostent *host_ent; if (!inet_aton(hostname, &addr.sin_addr)) { //TODO: only when we are connected to Internet, or use a non bloking call host_ent = gethostbyname(hostname); if (host_ent==NULL) return MS_GETHOSTBYNAME_ERROR; memcpy(&addr.sin_addr, host_ent->h_addr_list[0], sizeof(struct in_addr)); } return 0;}/*** MS_Connect()*/static int MS_Connect(char *ip_addr, char *str_port, int async){ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; I_InitTcpDriver(); // this is done only if not already done if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return MS_SOCKET_ERROR; if (MS_GetIP(ip_addr)==MS_GETHOSTBYNAME_ERROR) return MS_GETHOSTBYNAME_ERROR; addr.sin_port = htons(atoi(str_port)); if (async) // do asynchronous connection { int res = 1; ioctl(socket_fd, FIONBIO, &res); res = connect(socket_fd, (struct sockaddr *) &addr, sizeof(addr)); if (res < 0) {#ifdef WIN32 // humm, on win32 it doesn't work with EINPROGRESS (stupid windows) if (WSAGetLastError() != WSAEWOULDBLOCK)#else if (errno != EINPROGRESS)#endif { con_state = MSCS_FAILED; CloseConnection(); return MS_CONNECT_ERROR; } } con_state = MSCS_WAITING; FD_ZERO(&wset); FD_SET(socket_fd, &wset); select_timeout.tv_sec = 0, select_timeout.tv_usec = 0; } else { if (connect(socket_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) return MS_CONNECT_ERROR; } return 0;}/* * MS_Write(): */static int MS_Write(msg_t *msg){ int len; if (msg->length < 0) msg->length = strlen(msg->buffer); len = msg->length+HEADER_SIZE; //msg->id = htonl(msg->id); msg->type = htonl(msg->type); msg->length = htonl(msg->length); if (send(socket_fd, (char*)msg, len, 0) != len) return MS_WRITE_ERROR; return 0;}/* * MS_Read(): */static int MS_Read(msg_t *msg){ if (recv(socket_fd, (char*)msg, HEADER_SIZE, 0) != HEADER_SIZE) return MS_READ_ERROR; //msg->id = ntohl(msg->id); msg->type = ntohl(msg->type); msg->length = ntohl(msg->length); if (!msg->length) //Hurdler: fix a bug in Windows 2000 return 0; if (recv(socket_fd, (char*)msg->buffer, msg->length, 0) != msg->length) return MS_READ_ERROR; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -