Beispiel #1
0
void start_server_discovery()
{
	if(server_discovery_started)
		return;
	
	selected_server = -1;
	top_server_visible = 0;
	
	num_servers_unqueried = 0;
	num_servers_queried = 0;
	num_servers_found = 0;
	num_servers_new_proto = 0;
	
	struct server_t *cserver = rumoured_servers;
	
	while(cserver)
	{
		num_servers_unqueried++;
		LL_ADD_TAIL(struct server_t, &unqueried_servers, cserver);
		LL_NEXT(cserver);
	}
	
	pipe(servers_info_pipe);

	output_server_query();
	servers_first_output = get_wall_time();
	servers_next_output = 1.0 / SERVER_QUERY_OUTPUT_RATE + servers_first_output;

	pipe(servers_kill_pipe);
	pthread_create(&servers_thread_id, NULL, servers_thread, NULL);

	server_discovery_started = 1;
}
Beispiel #2
0
void save_rumoured_servers()
{
	struct string_t *filename = new_string_string(emergence_home_dir);

	#ifdef EMCLIENT
	string_cat_text(filename, "/rumoured.client");
	#endif
	
	#ifdef EMSERVER
	string_cat_text(filename, "/rumoured.server.");
	string_cat_int(filename, net_listen_port);
	#endif
	
	FILE *file = fopen(filename->text, "w");
	free_string(filename);
	
	if(!file)
		return;
	
	struct server_t *server = rumoured_servers;
	
	while(server)
	{
		char addr[17];
		if(inet_ntop(AF_INET, &server->ip, addr, 17))
			fprintf(file, "%s:%hu %u\n", addr, ntohs(server->port), (uint32_t)server->time);
		
		LL_NEXT(server);
	}

	fclose(file);
}
Beispiel #3
0
void process_server_info(struct sockaddr_in *sockaddr, struct buffer_t *buffer)
{
	struct queried_server_t *cserver = queried_servers;
	struct found_server_t new_server_info;
	uint16_t servers;
	struct sockaddr_in s;
	time_t t;
	int proto_ver;
		
	while(cserver)
	{
		if(cserver->ip == sockaddr->sin_addr.s_addr && 
			cserver->port == sockaddr->sin_port)
		{
			proto_ver = buffer_read_uint8(buffer);
			if(proto_ver != EM_PROTO_VER)
			{
				if(proto_ver > EM_PROTO_VER)
					num_servers_new_proto++;
				
				break;
			}
			
			new_server_info.ip = sockaddr->sin_addr.s_addr;
			new_server_info.port = sockaddr->sin_port;
			new_server_info.ping = get_wall_time() - cserver->stamp;

			new_server_info.host_name = buffer_read_string(buffer);
			new_server_info.map_name = buffer_read_string(buffer);
			new_server_info.num_players = buffer_read_uint8(buffer);
			new_server_info.max_players = buffer_read_uint8(buffer);
			new_server_info.authenticating = buffer_read_uint8(buffer);
		
			add_new_found_server(&new_server_info);
				
			
			add_new_server(&rumoured_servers, sockaddr, time(NULL));
				
			
			servers = buffer_read_uint16(buffer);
			
			while(servers--)
			{
				s.sin_addr.s_addr = buffer_read_uint32(buffer);
				s.sin_port = buffer_read_uint16(buffer);
				t = buffer_read_uint32(buffer);
				
				if(!find_queried_server(s.sin_addr.s_addr, s.sin_port))
				{
					if(add_new_server(&unqueried_servers, &s, t))
						num_servers_unqueried++;
				}
			}
			
			break;
		}
			
		LL_NEXT(cserver);
	}			
}
Beispiel #4
0
void server_enter(int state)
{
	if(!state)
		return;
	
	pthread_mutex_lock(&servers_mutex);
	
	struct found_server_t *cserver = found_servers;
	int i = 0;
		
	while(cserver)
	{
		if(i == selected_server)
		{
			if(!r_DrawConsole)
				console_toggle();
			
			em_connect(cserver->ip, cserver->port);
			goto end;
		}
		
		LL_NEXT(cserver);
		i++;
	}
		
	end:

	pthread_mutex_unlock(&servers_mutex);
}
Beispiel #5
0
/*
 * sync()
 *	Write dirty buffers to disk
 *
 * If handle is not NULL, sync all buffers dirtied with this handle.
 * Otherwise sync all dirty buffers.
 */
void
sync_bufs(void *handle)
{
	struct llist *l;
	uint x;

	for (l = LL_NEXT(&allbufs); l != &allbufs; l = LL_NEXT(l)) {
		struct buf *b = l->l_data;

		/*
		 * Not dirty--easy
		 */
		if (!(b->b_flags & B_DIRTY)) {
			continue;
		}

		/*
		 * Interlock
		 */
		get(b);

		/*
		 * Not dirty after interlock--still easy
		 */
		if (!(b->b_flags & B_DIRTY)) {
			continue;
		}

		/* 
		 * No handle, just sync dirty buffers
		 */
		if (!handle) {
			qio(b, Q_FLUSHBUF);
			continue;
		}

		/*
		 * Check for match.
		 */
		for (x = 0; x < b->b_nhandle; ++x) {
			if (b->b_handles[x] == handle) {
				qio(b, Q_FLUSHBUF);
				break;
			}
		}
	}
}
Beispiel #6
0
int count_servers()
{
	int c = 0;
	
	struct server_t *cserver = rumoured_servers;
		
	while(cserver)
	{
		c++;
		
		LL_NEXT(cserver);
	}
	
	return c;
}
Beispiel #7
0
struct queried_server_t *find_queried_server(uint32_t ip, uint16_t port)
{
	struct queried_server_t *cserver = queried_servers;
		
	while(cserver)
	{
		if(cserver->ip == ip &&
			cserver->port == port)
			return cserver;
		
		LL_NEXT(cserver);
	}
	
	return NULL;
}
//
// get a new event structure from the freelist,
// initialize it, and insert it into the timeoutq
// 
void
create_timeoutq_event(int timeout, int repeat, pfv_t function, unsigned int data)
{
	struct event *x;
	struct event *tempptr;
	
	x = (struct event*)LL_POP(freelist);
	x->timeout         = timeout;	
	x->repeat_interval = repeat;
	x->go		   = function;
	x->data		   = data;	 

	if(LL_IS_EMPTY(timeoutq))
		LL_PUSH(timeoutq, x); //x=timeoutq=head of list
	//insert it correct place and update timout 
	else
	LL_EACH(timeoutq,tempptr,struct event)
	{
		if(x->timeout <= tempptr->timeout)
		{
			tempptr->timeout -= x->timeout;  
			LL_L_INSERT(tempptr,x);
			break;
		}
		else
		{	
			if(LL_NEXT(timeoutq,tempptr) == NULL)
			{
				x->timeout -= tempptr->timeout;			
				LL_R_INSERT(tempptr,x);
				break;
			}
			else
			{
				x->timeout -= tempptr->timeout;			
				continue; //go to the next node 	
			}
		}
	}
	//update then_usec
//	then_usec = now_usec() - then_usec; 
}
Beispiel #9
0
void emit_servers(uint32_t conn)
{
	net_emit_uint8(conn, EMMSG_SERVERS);
	
	int servers = min(45, count_servers());
	
	net_emit_uint32(conn, servers);
	
	struct server_t *cserver = rumoured_servers;

	while(servers--)
	{
		net_emit_uint32(conn, cserver->ip);
		net_emit_uint16(conn, cserver->port);
		net_emit_uint32(conn, cserver->time);
		
		LL_NEXT(cserver);
	}
	
	net_emit_end_of_stream(conn);
}
Beispiel #10
0
int add_new_server(struct server_t **server0, struct sockaddr_in *sockaddr, time_t t)
{
	int found = 0;
	
	// see if this server is already in the list
	
	struct server_t *cserver = *server0, *temp, *next;
		
	while(cserver)
	{
		if(cserver->ip == sockaddr->sin_addr.s_addr &&
			cserver->port == sockaddr->sin_port)
		{
			next = cserver->next;
			LL_REMOVE(struct server_t, server0, cserver);
			cserver = next;
			found = 1;
			continue;
		}
		
		LL_NEXT(cserver);
	}
	
	struct server_t server = {
		sockaddr->sin_addr.s_addr, 
		sockaddr->sin_port, 
		t
	};
	


	// if rumoured_servers is NULL, then create new server here

	if(!*server0)
	{
		*server0 = malloc(sizeof(struct server_t));
		memcpy(*server0, &server, sizeof(struct server_t));
		(*server0)->next = NULL;
		goto end;
	}
	
	if((*server0)->time < t)
	{
		temp = *server0;
		*server0 = malloc(sizeof(struct server_t));
		memcpy(*server0, &server, sizeof(struct server_t));
		(*server0)->next = temp;
		goto end;
	}
	
	
	cserver = *server0;
	
	while(cserver->next)
	{
		if(cserver->next->time < t)
		{
			temp = cserver->next;
			cserver->next = malloc(sizeof(struct server_t));
			cserver = cserver->next;
			memcpy(cserver, &server, sizeof(struct server_t));
			cserver->next = temp;
			goto end;
		}

		LL_NEXT(cserver);
	}


	cserver->next = malloc(sizeof(struct server_t));
	cserver = cserver->next;
	memcpy(cserver, &server, sizeof(struct server_t));
	cserver->next = NULL;

	
	end:
	;
	
	return !found;
}
Beispiel #11
0
/*
 * tmpfs_readdir()
 *	Do reads on directory entries
 */
static void
tmpfs_readdir(struct msg *m, struct file *f)
{
	char *buf;
	uint len, pos, bufcnt;
	struct llist *l;
	struct openfile *o;
	extern struct llist files;

	/*
	 * Get a buffer of the requested size, but put a sanity
	 * cap on it.
	 */
	len = m->m_arg;
	if (len > 256) {
		len = 256;
	}
	if ((buf = malloc(len+1)) == 0) {
		msg_err(m->m_sender, strerror());
		return;
	}
	buf[0] = '\0';

	/*
	 * Assemble as many names as will fit, starting at
	 * given byte offset.  We assume the caller's position
	 * always advances in units of a whole directory entry.
	 */
	bufcnt = pos = 0;
	for (l = LL_NEXT(&files); l != &files; l = LL_NEXT(l)) {
		uint slen;

		/*
		 * Point to next file.  Get its length.
		 */
		o = l->l_data;
		slen = strlen(o->o_name)+1;

		/*
		 * If we've reached an offset the caller hasn't seen
		 * yet, assemble the entry into the buffer.
		 */
		if (pos >= f->f_pos) {
			/*
			 * No more room in buffer--return results
			 */
			if (slen >= len) {
				break;
			}

			/*
			 * Put string with newline at end of buffer
			 */
			sprintf(buf + bufcnt, "%s\n", o->o_name);

			/*
			 * Update counters
			 */
			len -= slen;
			bufcnt += slen;
		}

		/*
		 * Update position
		 */
		pos += slen;
	}

	/*
	 * Send back results
	 */
	m->m_buf = buf;
	m->m_arg = m->m_buflen = bufcnt;
	m->m_nseg = ((bufcnt > 0) ? 1 : 0);
	m->m_arg1 = 0;
	msg_reply(m->m_sender, m);
	free(buf);
	f->f_pos = pos;
}
Beispiel #12
0
void render_servers()
{
	if(r_DrawConsole)
		return;
	
	if(server_discovery_started)
	{
		pthread_mutex_lock(&servers_mutex);
		
		blit_text(0, vid_height * 5 / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "Servers unqueried:");
	
		blit_text(150, vid_height * 5 / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "%u", num_servers_unqueried);

		blit_text(0, vid_height * 5 / 6 + 14, 0xff, 0xff, 0xff, 
			s_backbuffer, "Servers queried:");
		
		blit_text(150, vid_height * 5 / 6 + 14, 0xff, 0xff, 0xff, 
			s_backbuffer, "%u", num_servers_queried);
		
		blit_text(0, vid_height * 5 / 6 + 28, 0xff, 0xff, 0xff, 
			s_backbuffer, "Servers found:");
		
		blit_text(150, vid_height * 5 / 6 + 28, 0xff, 0xff, 0xff, 
			s_backbuffer, "%u", num_servers_found);

		if(num_servers_new_proto)
		{
			blit_text(0, vid_height * 5 / 6 + 42, 0xff, 0xff, 0xff, 
				s_backbuffer, "Servers found requiring new version:");
		
			blit_text(275, vid_height * 5 / 6 + 42, 0xff, 0xff, 0xff, 
				s_backbuffer, "%u", num_servers_new_proto);
		}

		
		blit_text(50, vid_height / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "Server");

		blit_text(50 + 264, vid_height / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "Port");

		blit_text(50 + 264 + 64, vid_height / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "Ping");

		blit_text(50 + 264 + 64 + 64, vid_height / 6, 0xff, 0xff, 0xff, 
			s_backbuffer, "Key");
			
		blit_text(50 + 264 + 64 + 64, vid_height / 6 + 16, 0xff, 0xff, 0xff, 
			s_backbuffer, "Required?");
			

		blit_text(50 + 32, vid_height / 6 + 14, 0xff, 0xff, 0xff, 
			s_backbuffer, "Map");
		
		blit_text(50 + 32 + 264, vid_height / 6 + 14, 0xff, 0xff, 0xff, 
			s_backbuffer, "Players");

		struct found_server_t *cserver = found_servers;
		int i = 1;
		int server = 0;
			
		while(cserver && i <= 8)
		{
			if(server >= top_server_visible)
			{
				blit_text(50, vid_height / 6 + i * 32, 0xef, 0x6f, 0xff, 
					s_backbuffer, "%s", cserver->host_name->text);
	
				blit_text(50 + 264, vid_height / 6 + i * 32, 0xef, 0x6f, 0xff, 
					s_backbuffer, "%u", ntohs(cserver->port));
	
				blit_text(50 + 264 + 64, vid_height / 6 + i * 32, 0xef, 0x6f, 0xff, 
					s_backbuffer, "%.2fms", cserver->ping * 1000.0);
	
				if(cserver->authenticating)
				{
					blit_text_centered(50 + 264 + 64 + 64 + 12, vid_height / 6 + i * 32 + 6, 
						0xef, 0x6f, 0xff, s_backbuffer, "Y");
				}
	
				blit_text(50 + 32, vid_height / 6 + i * 32 + 14, 0xef, 0x6f, 0xff, 
					s_backbuffer, "%s", cserver->map_name->text);
				
				blit_text(50 + 32 + 264, vid_height / 6 + i * 32 + 14, 0xef, 0x6f, 0xff, 
					s_backbuffer, "%u/%u", cserver->num_players, cserver->max_players);
				
				if(server == selected_server)
				{
					struct blit_params_t params;
						
					params.red = 0x54;
					params.green = 0xa6;
					params.blue = 0xf9;
					params.alpha = 0x7f;
					
					params.dest = s_backbuffer;
					params.dest_x = 48;
					params.dest_y = vid_height / 6 + i * 32 - 2;
					params.width = 475;
					params.height = 32;
				
					alpha_draw_rect(&params);
				}
				
				i++;
			}
			
			LL_NEXT(cserver);
			server++;
		}
		
		pthread_mutex_unlock(&servers_mutex);
	}
}
Beispiel #13
0
void add_new_found_server(struct found_server_t *found_server)
{
	// see if this server is already in the list
	
	struct found_server_t *cserver = found_servers, *next;
	int i;
	
	while(cserver)
	{
		if(cserver->ip == found_server->ip &&
			cserver->port == found_server->port)
			return;
		
		LL_NEXT(cserver);
	}
	
	
	num_servers_found++;

	// if rumoured_servers is NULL, then create new server here

	if(!found_servers)
	{
		found_servers = malloc(sizeof(struct found_server_t));
		memcpy(found_servers, found_server, sizeof(struct found_server_t));
		(found_servers)->next = NULL;
		return;
	}
	
	if((found_servers)->ping > found_server->ping)
	{
		next = found_servers;
		found_servers = malloc(sizeof(struct found_server_t));
		memcpy(found_servers, found_server, sizeof(struct found_server_t));
		(found_servers)->next = next;
		
		if(selected_server != -1)
			server_down_in_lock();
		
		return;
	}
	
	
	cserver = found_servers;
	i = 1;
	
	while(cserver->next)
	{
		if(cserver->next->ping > found_server->ping)
		{
			next = cserver->next;
			cserver->next = malloc(sizeof(struct found_server_t));
			cserver = cserver->next;
			memcpy(cserver, found_server, sizeof(struct found_server_t));
			cserver->next = next;
			
			if(selected_server != -1 && i <= selected_server)
				server_down_in_lock();
			
			return;
		}

		LL_NEXT(cserver);
		i++;
	}


	cserver->next = malloc(sizeof(struct found_server_t));
	cserver = cserver->next;
	memcpy(cserver, found_server, sizeof(struct found_server_t));
	cserver->next = NULL;
}