mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
begun the work for the new server browse backend
This commit is contained in:
parent
d33bdd1dbb
commit
fa05b5e2de
|
@ -15,6 +15,7 @@
|
|||
#include <engine/network.h>
|
||||
#include <engine/config.h>
|
||||
#include <engine/packer.h>
|
||||
#include <engine/memheap.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
|
||||
|
@ -31,8 +32,6 @@ const int prediction_margin = 5;
|
|||
Prediction Latency
|
||||
Upstream latency
|
||||
*/
|
||||
static int info_request_begin;
|
||||
static int info_request_end;
|
||||
static int snapshot_part;
|
||||
static int64 local_start_time;
|
||||
|
||||
|
@ -346,29 +345,119 @@ int *client_get_input(int tick)
|
|||
}
|
||||
|
||||
// ------ server browse ----
|
||||
static struct
|
||||
typedef struct SERVERENTRY_t SERVERENTRY;
|
||||
struct SERVERENTRY_t
|
||||
{
|
||||
SERVER_INFO infos[MAX_SERVERS];
|
||||
int64 request_times[MAX_SERVERS];
|
||||
NETADDR4 addresses[MAX_SERVERS];
|
||||
int num;
|
||||
} servers;
|
||||
NETADDR4 addr;
|
||||
int64 request_time;
|
||||
SERVER_INFO info;
|
||||
|
||||
SERVERENTRY *next_ip; // ip hashed list
|
||||
|
||||
SERVERENTRY *prev_req; // request list
|
||||
SERVERENTRY *next_req;
|
||||
};
|
||||
|
||||
HEAP *serverlist_heap = 0;
|
||||
SERVERENTRY **serverlist = 0;
|
||||
|
||||
SERVERENTRY *serverlist_ip[256] = {0}; // ip hash list
|
||||
|
||||
SERVERENTRY *first_req_server = 0; // request list
|
||||
SERVERENTRY *last_req_server = 0;
|
||||
|
||||
int num_servers = 0;
|
||||
int num_server_capasity = 0;
|
||||
|
||||
static int serverlist_lan = 1;
|
||||
|
||||
int client_serverbrowse_getlist(SERVER_INFO **serverlist)
|
||||
SERVER_INFO *client_serverbrowse_get(int index)
|
||||
{
|
||||
*serverlist = servers.infos;
|
||||
return servers.num;
|
||||
if(index < 0 || index >= num_servers)
|
||||
return 0;
|
||||
return &serverlist[index]->info;
|
||||
}
|
||||
|
||||
int client_serverbrowse_num()
|
||||
{
|
||||
return num_servers;
|
||||
}
|
||||
|
||||
static void client_serverbrowse_init()
|
||||
{
|
||||
servers.num = 0;
|
||||
}
|
||||
|
||||
static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *info)
|
||||
{
|
||||
int hash = addr->ip[0];
|
||||
SERVERENTRY *entry = serverlist_ip[hash];
|
||||
while(entry)
|
||||
{
|
||||
if(net_addr4_cmp(&entry->addr, addr) == 0)
|
||||
{
|
||||
/* update the server that we already have */
|
||||
entry->info = *info;
|
||||
if(!request)
|
||||
entry->info.latency = (time_get()-entry->request_time)*1000/time_freq();
|
||||
return;
|
||||
}
|
||||
entry = entry->next_ip;
|
||||
}
|
||||
|
||||
/* create new entry */
|
||||
entry = (SERVERENTRY *)memheap_allocate(serverlist_heap, sizeof(SERVERENTRY));
|
||||
mem_zero(entry, sizeof(SERVERENTRY));
|
||||
|
||||
/* set the info */
|
||||
entry->addr = *addr;
|
||||
entry->info = *info;
|
||||
|
||||
/* add to the hash list */
|
||||
entry->next_ip = serverlist_ip[hash];
|
||||
serverlist_ip[hash] = entry;
|
||||
|
||||
if(num_servers == num_server_capasity)
|
||||
{
|
||||
num_server_capasity += 100;
|
||||
SERVERENTRY **newlist = mem_alloc(num_server_capasity*sizeof(SERVERENTRY*), 1);
|
||||
memcpy(newlist, serverlist, num_servers*sizeof(SERVERENTRY*));
|
||||
mem_free(serverlist);
|
||||
serverlist = newlist;
|
||||
}
|
||||
|
||||
/* add to list */
|
||||
serverlist[num_servers] = entry;
|
||||
num_servers++;
|
||||
|
||||
/* */
|
||||
entry->prev_req = 0;
|
||||
entry->next_req = 0;
|
||||
|
||||
if(request)
|
||||
{
|
||||
/* add it to the list of servers that we should request info from */
|
||||
entry->prev_req = last_req_server;
|
||||
if(last_req_server)
|
||||
last_req_server->next_req = entry;
|
||||
else
|
||||
first_req_server = entry;
|
||||
last_req_server = entry;
|
||||
}
|
||||
}
|
||||
|
||||
void client_serverbrowse_refresh(int lan)
|
||||
{
|
||||
/* clear out everything */
|
||||
if(serverlist_heap)
|
||||
memheap_destroy(serverlist_heap);
|
||||
serverlist_heap = memheap_create();
|
||||
num_servers = 0;
|
||||
num_server_capasity = 0;
|
||||
mem_zero(serverlist_ip, sizeof(serverlist_ip));
|
||||
first_req_server = 0;
|
||||
last_req_server = 0;
|
||||
|
||||
/* */
|
||||
serverlist_lan = lan;
|
||||
|
||||
if(serverlist_lan)
|
||||
|
@ -389,7 +478,7 @@ void client_serverbrowse_refresh(int lan)
|
|||
netclient_send(net, &packet);
|
||||
|
||||
// reset the list
|
||||
servers.num = 0;
|
||||
//servers.num = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -405,27 +494,28 @@ void client_serverbrowse_refresh(int lan)
|
|||
netclient_send(net, &packet);
|
||||
|
||||
// reset the list
|
||||
servers.num = 0;
|
||||
//servers.num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void client_serverbrowse_request(int id)
|
||||
static void client_serverbrowse_request(SERVERENTRY *entry)
|
||||
{
|
||||
if(config.debug)
|
||||
{
|
||||
dbg_msg("client", "requesting server info from %d.%d.%d.%d:%d",
|
||||
servers.addresses[id].ip[0], servers.addresses[id].ip[1], servers.addresses[id].ip[2],
|
||||
servers.addresses[id].ip[3], servers.addresses[id].port);
|
||||
entry->addr.ip[0], entry->addr.ip[1], entry->addr.ip[2],
|
||||
entry->addr.ip[3], entry->addr.port);
|
||||
}
|
||||
NETPACKET packet;
|
||||
packet.client_id = -1;
|
||||
packet.address = servers.addresses[id];
|
||||
packet.flags = PACKETFLAG_CONNLESS;
|
||||
packet.data_size = sizeof(SERVERBROWSE_GETINFO);
|
||||
packet.data = SERVERBROWSE_GETINFO;
|
||||
netclient_send(net, &packet);
|
||||
servers.request_times[id] = time_get();
|
||||
|
||||
NETPACKET p;
|
||||
p.client_id = -1;
|
||||
p.address = entry->addr;
|
||||
p.flags = PACKETFLAG_CONNLESS;
|
||||
p.data_size = sizeof(SERVERBROWSE_GETINFO);
|
||||
p.data = SERVERBROWSE_GETINFO;
|
||||
netclient_send(net, &p);
|
||||
entry->request_time = time_get();
|
||||
}
|
||||
|
||||
static void client_serverbrowse_update()
|
||||
|
@ -433,7 +523,55 @@ static void client_serverbrowse_update()
|
|||
int64 timeout = time_freq();
|
||||
int64 now = time_get();
|
||||
int max_requests = 10;
|
||||
int count;
|
||||
|
||||
SERVERENTRY *entry, *next;
|
||||
|
||||
/* do timeouts */
|
||||
entry = first_req_server;
|
||||
while(1)
|
||||
{
|
||||
if(!entry) // no more entries
|
||||
break;
|
||||
|
||||
next = entry->next_req;
|
||||
|
||||
if(entry->request_time && entry->request_time+timeout < now)
|
||||
{
|
||||
/* timeout */
|
||||
if(entry->prev_req)
|
||||
entry->prev_req->next_req = entry->next_req;
|
||||
else
|
||||
first_req_server = entry->next_req;
|
||||
|
||||
if(entry->next_req)
|
||||
entry->next_req->prev_req = entry->prev_req;
|
||||
else
|
||||
last_req_server = entry->prev_req;
|
||||
}
|
||||
|
||||
entry = next;
|
||||
}
|
||||
|
||||
/* do timeouts */
|
||||
entry = first_req_server;
|
||||
count = 0;
|
||||
while(1)
|
||||
{
|
||||
if(!entry) // no more entries
|
||||
break;
|
||||
|
||||
if(count == max_requests) // no more then 10 concurrent requests
|
||||
break;
|
||||
|
||||
if(entry->request_time == 0)
|
||||
client_serverbrowse_request(entry);
|
||||
|
||||
count++;
|
||||
entry = entry->next_req;
|
||||
}
|
||||
|
||||
/*
|
||||
// timeout old requests
|
||||
while(info_request_begin < servers.num && info_request_begin < info_request_end)
|
||||
{
|
||||
|
@ -448,7 +586,7 @@ static void client_serverbrowse_update()
|
|||
{
|
||||
client_serverbrowse_request(info_request_end);
|
||||
info_request_end++;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// ------ state handling -----
|
||||
|
@ -597,7 +735,30 @@ static void client_process_packet(NETPACKET *packet)
|
|||
if(packet->data_size >= (int)sizeof(SERVERBROWSE_LIST) &&
|
||||
memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0)
|
||||
{
|
||||
int size = packet->data_size-sizeof(SERVERBROWSE_LIST);
|
||||
//mem_copy(servers.addresses, (char*)packet->data+sizeof(SERVERBROWSE_LIST), size);
|
||||
int num = size/sizeof(NETADDR4);
|
||||
NETADDR4 *addrs = (NETADDR4 *)((char*)packet->data+sizeof(SERVERBROWSE_LIST));
|
||||
|
||||
int i;
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
NETADDR4 addr = addrs[i];
|
||||
SERVER_INFO info = {0};
|
||||
|
||||
info.latency = 999;
|
||||
sprintf(info.address, "%d.%d.%d.%d:%d",
|
||||
addr.ip[0], addr.ip[1], addr.ip[2],
|
||||
addr.ip[3], addr.port);
|
||||
sprintf(info.name, "%d.%d.%d.%d:%d",
|
||||
addr.ip[0], addr.ip[1], addr.ip[2],
|
||||
addr.ip[3], addr.port);
|
||||
|
||||
client_serverbrowse_set(addrs+i, 1, &info);
|
||||
}
|
||||
|
||||
// server listing
|
||||
/*
|
||||
int size = packet->data_size-sizeof(SERVERBROWSE_LIST);
|
||||
mem_copy(servers.addresses, (char*)packet->data+sizeof(SERVERBROWSE_LIST), size);
|
||||
servers.num = size/sizeof(NETADDR4);
|
||||
|
@ -621,7 +782,7 @@ static void client_process_packet(NETPACKET *packet)
|
|||
sprintf(servers.infos[i].name, "%d.%d.%d.%d:%d",
|
||||
servers.addresses[i].ip[0], servers.addresses[i].ip[1], servers.addresses[i].ip[2],
|
||||
servers.addresses[i].ip[3], servers.addresses[i].port);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if(packet->data_size >= (int)sizeof(SERVERBROWSE_INFO) &&
|
||||
|
@ -630,46 +791,27 @@ static void client_process_packet(NETPACKET *packet)
|
|||
// we got ze info
|
||||
UNPACKER up;
|
||||
unpacker_reset(&up, (unsigned char*)packet->data+sizeof(SERVERBROWSE_INFO), packet->data_size-sizeof(SERVERBROWSE_INFO));
|
||||
|
||||
if(serverlist_lan)
|
||||
{
|
||||
if(servers.num != MAX_SERVERS)
|
||||
{
|
||||
int i = servers.num;
|
||||
strncpy(servers.infos[i].name, unpacker_get_string(&up), 128);
|
||||
strncpy(servers.infos[i].map, unpacker_get_string(&up), 128);
|
||||
servers.infos[i].max_players = unpacker_get_int(&up);
|
||||
servers.infos[i].num_players = unpacker_get_int(&up);
|
||||
servers.infos[i].latency = 0;
|
||||
|
||||
sprintf(servers.infos[i].address, "%d.%d.%d.%d:%d",
|
||||
packet->address.ip[0], packet->address.ip[1], packet->address.ip[2],
|
||||
packet->address.ip[3], packet->address.port);
|
||||
SERVER_INFO info = {0};
|
||||
|
||||
if(config.debug)
|
||||
dbg_msg("client", "got server info");
|
||||
servers.num++;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
strncpy(info.version, unpacker_get_string(&up), 32);
|
||||
strncpy(info.name, unpacker_get_string(&up), 64);
|
||||
strncpy(info.map, unpacker_get_string(&up), 32);
|
||||
info.game_type = atol(unpacker_get_string(&up));
|
||||
info.flags = atol(unpacker_get_string(&up));
|
||||
info.progression = atol(unpacker_get_string(&up));
|
||||
info.num_players = atol(unpacker_get_string(&up));
|
||||
info.max_players = atol(unpacker_get_string(&up));
|
||||
|
||||
int i;
|
||||
for(i = 0; i < info.num_players; i++)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < servers.num; i++)
|
||||
{
|
||||
if(net_addr4_cmp(&servers.addresses[i], &packet->address) == 0)
|
||||
{
|
||||
strncpy(servers.infos[i].name, unpacker_get_string(&up), 128);
|
||||
strncpy(servers.infos[i].map, unpacker_get_string(&up), 128);
|
||||
servers.infos[i].max_players = unpacker_get_int(&up);
|
||||
servers.infos[i].num_players = unpacker_get_int(&up);
|
||||
servers.infos[i].latency = ((time_get() - servers.request_times[i])*1000)/time_freq();
|
||||
if(config.debug)
|
||||
dbg_msg("client", "got server info");
|
||||
break;
|
||||
}
|
||||
}
|
||||
strncpy(info.player_names[i], unpacker_get_string(&up), 48);
|
||||
info.player_scores[i] = atol(unpacker_get_string(&up));
|
||||
}
|
||||
|
||||
/* TODO: unpack players aswell */
|
||||
client_serverbrowse_set(&packet->address, 0, &info);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -898,8 +1040,6 @@ static void client_run(const char *direct_connect_server)
|
|||
{
|
||||
local_start_time = time_get();
|
||||
snapshot_part = 0;
|
||||
info_request_begin = 0;
|
||||
info_request_end = 0;
|
||||
|
||||
client_serverbrowse_init();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
|
||||
enum
|
||||
{
|
||||
MAX_CLIENTS=8,
|
||||
MAX_CLIENTS=16,
|
||||
SERVER_TICK_SPEED=50, /* TODO: this should be removed */
|
||||
SNAP_CURRENT=0,
|
||||
SNAP_PREV=1,
|
||||
|
@ -55,12 +55,18 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
int progression;
|
||||
int game_type;
|
||||
int max_players;
|
||||
int num_players;
|
||||
int flags;
|
||||
int latency; /* in ms */
|
||||
char name[128];
|
||||
char map[128];
|
||||
char address[128];
|
||||
char name[64];
|
||||
char map[32];
|
||||
char version[32];
|
||||
char address[24];
|
||||
char player_names[16][48];
|
||||
int player_scores[16];
|
||||
} SERVER_INFO;
|
||||
|
||||
/* image loaders */
|
||||
|
@ -785,7 +791,8 @@ void client_quit();
|
|||
void client_rcon(const char *cmd);
|
||||
|
||||
void client_serverbrowse_refresh(int lan);
|
||||
int client_serverbrowse_getlist(SERVER_INFO **servers);
|
||||
SERVER_INFO *client_serverbrowse_get(int index);
|
||||
int client_serverbrowse_num();
|
||||
|
||||
/* undocumented graphics stuff */
|
||||
void gfx_pretty_text(float x, float y, float size, const char *text, int max_width);
|
||||
|
|
101
src/engine/memheap.c
Normal file
101
src/engine/memheap.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "system.h"
|
||||
|
||||
typedef struct CHUNK_t
|
||||
{
|
||||
char *memory;
|
||||
char *current;
|
||||
char *end;
|
||||
struct CHUNK_t *next;
|
||||
} CHUNK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CHUNK *current;
|
||||
} HEAP;
|
||||
|
||||
/* how large each chunk should be */
|
||||
static const int chunksize = 1024*64;
|
||||
|
||||
/* allocates a new chunk to be used */
|
||||
static CHUNK *memheap_newchunk()
|
||||
{
|
||||
CHUNK *chunk;
|
||||
char *mem;
|
||||
|
||||
/* allocate memory */
|
||||
mem = mem_alloc(sizeof(CHUNK)+chunksize, 1);
|
||||
if(!mem)
|
||||
return 0x0;
|
||||
|
||||
/* the chunk structure is located in the begining of the chunk */
|
||||
/* init it and return the chunk */
|
||||
chunk = (CHUNK*)mem;
|
||||
chunk->memory = (char*)(chunk+1);
|
||||
chunk->current = chunk->memory;
|
||||
chunk->end = chunk->memory + chunksize;
|
||||
chunk->next = (CHUNK *)0x0;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/******************/
|
||||
static void *memheap_allocate_from_chunk(CHUNK *chunk, int size)
|
||||
{
|
||||
char *mem;
|
||||
|
||||
/* check if we need can fit the allocation */
|
||||
if(chunk->current + size >= chunk->end)
|
||||
return (void*)0x0;
|
||||
|
||||
/* get memory and move the pointer forward */
|
||||
mem = chunk->current;
|
||||
chunk->current += size;
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* creates a heap */
|
||||
HEAP *memheap_create()
|
||||
{
|
||||
CHUNK *chunk;
|
||||
HEAP *heap;
|
||||
|
||||
/* allocate a chunk and allocate the heap structure on that chunk */
|
||||
chunk = memheap_newchunk();
|
||||
heap = (HEAP *)memheap_allocate_from_chunk(chunk, sizeof(HEAP));
|
||||
heap->current = chunk;
|
||||
return heap;
|
||||
}
|
||||
|
||||
/* destroys the heap */
|
||||
void memheap_destroy(HEAP *heap)
|
||||
{
|
||||
CHUNK *chunk = heap->current;
|
||||
CHUNK *next;
|
||||
|
||||
while(chunk)
|
||||
{
|
||||
next = chunk->next;
|
||||
mem_free(chunk);
|
||||
chunk = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void *memheap_allocate(HEAP *heap, int size)
|
||||
{
|
||||
char *mem;
|
||||
|
||||
/* try to allocate from current chunk */
|
||||
mem = (char *)memheap_allocate_from_chunk(heap->current, size);
|
||||
if(!mem)
|
||||
{
|
||||
/* allocate new chunk and add it to the heap */
|
||||
CHUNK *chunk = memheap_newchunk();
|
||||
chunk->next = heap->current;
|
||||
heap->current = chunk;
|
||||
|
||||
/* try to allocate again */
|
||||
mem = (char *)memheap_allocate_from_chunk(heap->current, size);
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
5
src/engine/memheap.h
Normal file
5
src/engine/memheap.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
typedef struct HEAP_t HEAP;
|
||||
HEAP *memheap_create();
|
||||
void memheap_destroy(HEAP *heap);
|
||||
void *memheap_allocate(HEAP *heap, int size);
|
|
@ -494,7 +494,7 @@ static void server_send_serverinfo(NETADDR4 *addr)
|
|||
packer_reset(&p);
|
||||
packer_add_raw(&p, SERVERBROWSE_INFO, sizeof(SERVERBROWSE_INFO));
|
||||
packer_add_string(&p, config.sv_name, 128);
|
||||
packer_add_string(&p, config.sv_map, 128);
|
||||
packer_add_string(&p, config.sv_map, 32);
|
||||
packer_add_int(&p, netserver_max_clients(net)); /* max_players */
|
||||
int c = 0;
|
||||
int i;
|
||||
|
|
|
@ -631,8 +631,7 @@ static int do_server_list(float x, float y, int *scroll_index, int *selected_ind
|
|||
const float real_width = item_width + 20;
|
||||
const float real_height = item_height * visible_items + spacing * (visible_items - 1);
|
||||
|
||||
SERVER_INFO *servers;
|
||||
int num_servers = client_serverbrowse_getlist(&servers);
|
||||
int num_servers = client_serverbrowse_num();
|
||||
|
||||
int r = -1;
|
||||
|
||||
|
@ -644,7 +643,7 @@ static int do_server_list(float x, float y, int *scroll_index, int *selected_ind
|
|||
//ui_do_image(empty_item_texture, x, y + i * item_height + i * spacing, item_width, item_height);
|
||||
else
|
||||
{
|
||||
SERVER_INFO *item = &servers[item_index];
|
||||
SERVER_INFO *item = client_serverbrowse_get(item_index);
|
||||
|
||||
bool clicked = false;
|
||||
clicked = ui_do_button(item, item->name, 0, x, y + i * item_height + i * spacing, item_width, item_height,
|
||||
|
@ -718,10 +717,10 @@ static int main_render()
|
|||
|
||||
if (last_selected_index != selected_index && selected_index != -1)
|
||||
{
|
||||
SERVER_INFO *servers;
|
||||
client_serverbrowse_getlist(&servers);
|
||||
SERVER_INFO *server;
|
||||
server = client_serverbrowse_get(selected_index);
|
||||
|
||||
strcpy(address, servers[selected_index].address);
|
||||
strcpy(address, server->address);
|
||||
}
|
||||
|
||||
static int refresh_button, join_button, quit_button;
|
||||
|
|
217
src/tools/fake_server.c
Normal file
217
src/tools/fake_server.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
#include <engine/config.h>
|
||||
#include <engine/system.h>
|
||||
#include <engine/network.h>
|
||||
#include <mastersrv/mastersrv.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
32 version
|
||||
64 servername
|
||||
32 mapname
|
||||
2 gametype
|
||||
2 flags
|
||||
4 progression
|
||||
3 num players
|
||||
3 max players
|
||||
{
|
||||
48 name
|
||||
6 score
|
||||
} * players
|
||||
|
||||
111111111122222222223333333333444444444
|
||||
123456789012345678901234567890123456789012345678
|
||||
0.3 2d82e361de24cb25
|
||||
my own private little server
|
||||
magnus.auvinen@teewars.somehost-strage-host.com
|
||||
*/
|
||||
|
||||
NETSERVER *net;
|
||||
|
||||
int progression = 50;
|
||||
int game_type = 0;
|
||||
int flags = 0;
|
||||
|
||||
const char *version = "0.3.0 2d82e361de24cb25";
|
||||
const char *map = "somemap";
|
||||
const char *server_name = "unnamed server";
|
||||
NETADDR4 master_servers[16] = {{{0},0}};
|
||||
int num_masters = 0;
|
||||
|
||||
const char *player_names[16] = {0};
|
||||
int player_scores[16] = {0};
|
||||
int num_players = 0;
|
||||
int max_players = 0;
|
||||
|
||||
static void send_heartbeats()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
NETPACKET p;
|
||||
p.client_id = -1;
|
||||
p.flags = PACKETFLAG_CONNLESS;
|
||||
p.data_size = sizeof(SERVERBROWSE_HEARTBEAT);
|
||||
p.data = SERVERBROWSE_HEARTBEAT;
|
||||
|
||||
for(i = 0; i < num_masters; i++)
|
||||
{
|
||||
p.address = master_servers[i];
|
||||
netserver_send(net, &p);
|
||||
}
|
||||
}
|
||||
|
||||
char infomsg[1024];
|
||||
int infomsg_size;
|
||||
|
||||
static void writestr(const char *str)
|
||||
{
|
||||
int l = strlen(str)+1;
|
||||
memcpy(&infomsg[infomsg_size], str, l);
|
||||
infomsg_size += l;
|
||||
}
|
||||
|
||||
static void writeint(int i)
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "%d", i);
|
||||
writestr(buf);
|
||||
}
|
||||
|
||||
static void build_infomessage()
|
||||
{
|
||||
int i;
|
||||
infomsg_size = sizeof(SERVERBROWSE_INFO);
|
||||
memcpy(infomsg, SERVERBROWSE_INFO, infomsg_size);
|
||||
|
||||
writestr(version);
|
||||
writestr(server_name);
|
||||
writestr(map);
|
||||
writeint(game_type);
|
||||
writeint(flags);
|
||||
writeint(progression);
|
||||
writeint(num_players);
|
||||
writeint(max_players);
|
||||
for(i = 0; i < num_players; i++)
|
||||
{
|
||||
writestr(player_names[i]);
|
||||
writeint(player_scores[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_serverinfo(NETADDR4 *addr)
|
||||
{
|
||||
NETPACKET p;
|
||||
p.client_id = -1;
|
||||
p.address = *addr;
|
||||
p.flags = PACKETFLAG_CONNLESS;
|
||||
p.data_size = infomsg_size;
|
||||
p.data = infomsg;
|
||||
netserver_send(net, &p);
|
||||
}
|
||||
|
||||
static void send_fwcheckresponse(NETADDR4 *addr)
|
||||
{
|
||||
NETPACKET p;
|
||||
p.client_id = -1;
|
||||
p.address = *addr;
|
||||
p.flags = PACKETFLAG_CONNLESS;
|
||||
p.data_size = sizeof(SERVERBROWSE_FWRESPONSE);
|
||||
p.data = SERVERBROWSE_FWRESPONSE;
|
||||
netserver_send(net, &p);
|
||||
}
|
||||
|
||||
static int run()
|
||||
{
|
||||
int64 next_heartbeat = 0;
|
||||
NETADDR4 bindaddr = {{0},0};
|
||||
net = netserver_open(bindaddr, 0, 0);
|
||||
if(!net)
|
||||
return -1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
NETPACKET p;
|
||||
netserver_update(net);
|
||||
while(netserver_recv(net, &p))
|
||||
{
|
||||
if(p.client_id == -1)
|
||||
{
|
||||
if(p.data_size == sizeof(SERVERBROWSE_GETINFO) &&
|
||||
memcmp(p.data, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0)
|
||||
{
|
||||
send_serverinfo(&p.address);
|
||||
}
|
||||
else if(p.data_size == sizeof(SERVERBROWSE_FWCHECK) &&
|
||||
memcmp(p.data, SERVERBROWSE_FWCHECK, sizeof(SERVERBROWSE_FWCHECK)) == 0)
|
||||
{
|
||||
send_fwcheckresponse(&p.address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* send heartbeats if needed */
|
||||
if(next_heartbeat < time_get())
|
||||
{
|
||||
next_heartbeat = time_get()+time_freq()*30;
|
||||
send_heartbeats();
|
||||
}
|
||||
|
||||
thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
net_init();
|
||||
|
||||
while(argc)
|
||||
{
|
||||
if(strcmp(*argv, "-m") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
net_host_lookup(*argv, 0, &master_servers[num_masters]);
|
||||
argc--; argv++;
|
||||
master_servers[num_masters].port = atoi(*argv);
|
||||
num_masters++;
|
||||
}
|
||||
else if(strcmp(*argv, "-p") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
player_names[num_players++] = *argv;
|
||||
argc--; argv++;
|
||||
player_scores[num_players] = atoi(*argv);
|
||||
}
|
||||
else if(strcmp(*argv, "-x") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
max_players = atoi(*argv);
|
||||
}
|
||||
else if(strcmp(*argv, "-t") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
game_type = atoi(*argv);
|
||||
}
|
||||
else if(strcmp(*argv, "-p") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
progression = atoi(*argv);
|
||||
}
|
||||
else if(strcmp(*argv, "-f") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
flags = atoi(*argv);
|
||||
}
|
||||
else if(strcmp(*argv, "-n") == 0)
|
||||
{
|
||||
argc--; argv++;
|
||||
server_name = *argv;
|
||||
}
|
||||
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
build_infomessage();
|
||||
return run();
|
||||
}
|
||||
|
Loading…
Reference in a new issue