mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-15 05:29:51 +01:00
Add masterlist from engine. Use non-blocking network name resolution
This commit is contained in:
parent
5a449a56ea
commit
ae5257c654
@ -146,6 +146,7 @@ engine/common/library.h
|
||||
engine/common/mathlib.c
|
||||
engine/common/mathlib.h
|
||||
engine/common/matrixlib.c
|
||||
engine/common/masterlist.c
|
||||
engine/common/mod_bmodel.c
|
||||
engine/common/mod_local.h
|
||||
engine/common/mod_studio.c
|
||||
|
@ -1020,6 +1020,10 @@ Resend a connect message if the last one has timed out
|
||||
void CL_CheckForResend( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
int res;
|
||||
|
||||
if( cls.internetservers_wait )
|
||||
CL_InternetServers_f();
|
||||
|
||||
// if the local server is running and we aren't then connect
|
||||
if( cls.state == ca_disconnected && SV_Active( ))
|
||||
@ -1044,13 +1048,21 @@ void CL_CheckForResend( void )
|
||||
if(( host.realtime - cls.connect_time ) < cl_resend.value )
|
||||
return;
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &adr ))
|
||||
res = NET_StringToAdrNB( cls.servername, &adr );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_CheckForResend: bad server address\n" );
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if( res == 2 )
|
||||
{
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
return;
|
||||
}
|
||||
|
||||
// only retry so many times before failure.
|
||||
if( cls.connect_retry >= CL_CONNECTION_RETRIES )
|
||||
{
|
||||
@ -1424,6 +1436,8 @@ void CL_LocalServers_f( void )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "info %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_InternetServers_f
|
||||
@ -1431,23 +1445,28 @@ CL_InternetServers_f
|
||||
*/
|
||||
void CL_InternetServers_f( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
char fullquery[512] = "1\xFF" "0.0.0.0:0\0" "\\gamedir\\";
|
||||
char fullquery[512] = MS_SCAN_REQUEST;
|
||||
char *info = fullquery + sizeof( MS_SCAN_REQUEST ) - 1;
|
||||
const size_t remaining = sizeof( fullquery ) - sizeof( MS_SCAN_REQUEST );
|
||||
|
||||
// Info_SetValueForKey( info, "nat", cl_nat->string, remaining );
|
||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||
|
||||
// let master know about client version
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining );
|
||||
|
||||
Con_Printf( "Scanning for servers on the internet area...\n" );
|
||||
NET_Config( true ); // allow remote
|
||||
|
||||
if( !NET_StringToAdr( MASTERSERVER_ADR, &adr ) )
|
||||
MsgDev( D_ERROR, "Can't resolve adr: %s\n", MASTERSERVER_ADR );
|
||||
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ), fullquery );
|
||||
cls.internetservers_pending = true;
|
||||
|
||||
Q_strcpy( &fullquery[22], GI->gamefolder );
|
||||
|
||||
NET_SendPacket( NS_CLIENT, Q_strlen( GI->gamefolder ) + 23, fullquery, adr );
|
||||
|
||||
// now we clearing the vgui request
|
||||
if( clgame.master_request != NULL )
|
||||
memset( clgame.master_request, 0, sizeof( net_request_t ));
|
||||
clgame.request_type = NET_REQUEST_GAMEUI;
|
||||
if( !cls.internetservers_wait )
|
||||
{
|
||||
// now we clearing the vgui request
|
||||
if( clgame.master_request != NULL )
|
||||
memset( clgame.master_request, 0, sizeof( net_request_t ));
|
||||
clgame.request_type = NET_REQUEST_GAMEUI;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1907,6 +1926,12 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, servadr, "info %i", PROTOCOL_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
if( cls.internetservers_pending )
|
||||
{
|
||||
Cbuf_AddText( "menu_resetping\n" ); // TODO: New Menu API
|
||||
cls.internetservers_pending = false;
|
||||
}
|
||||
}
|
||||
else if( clgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ static void Vibrate_f()
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: vibrate <time>\n" );
|
||||
Msg( S_USAGE "vibrate <time>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -648,6 +648,8 @@ typedef struct
|
||||
|
||||
file_t *demofile;
|
||||
file_t *demoheader; // contain demo startup info in case we record a demo on this level
|
||||
qboolean internetservers_wait; // internetservers is waiting for dns request
|
||||
qboolean internetservers_pending; // internetservers is waiting for dns request
|
||||
} client_static_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -183,7 +183,7 @@ void Evdev_OpenDevice ( const char *path )
|
||||
void Evdev_OpenDevice_f( void )
|
||||
{
|
||||
if( Cmd_Argc() < 2 )
|
||||
Msg( "Usage: evdev_opendevice <path>\n" );
|
||||
Msg( S_USAGE "evdev_opendevice <path>\n" );
|
||||
|
||||
Evdev_OpenDevice( Cmd_Argv( 1 ) );
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ void IN_TouchExportConfig_f( void )
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: touch_exportconfig <name>\n" );
|
||||
Msg( S_USAGE "touch_exportconfig <name>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ void IN_TouchGenetateCode_f( void )
|
||||
|
||||
if( Cmd_Argc() != 1 )
|
||||
{
|
||||
Msg( "Usage: touch_generate_code\n" );
|
||||
Msg( S_USAGE "touch_generate_code\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -584,7 +584,7 @@ void IN_TouchSetColor_f( void )
|
||||
IN_TouchSetColor( &touch.list_user, Cmd_Argv(1), color );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_setcolor <pattern> <r> <g> <b> <a>\n" );
|
||||
Msg( S_USAGE "touch_setcolor <pattern> <r> <g> <b> <a>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetTexture_f( void )
|
||||
@ -594,7 +594,7 @@ void IN_TouchSetTexture_f( void )
|
||||
IN_TouchSetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_settexture <name> <file>\n" );
|
||||
Msg( S_USAGE "touch_settexture <name> <file>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetFlags_f( void )
|
||||
@ -606,7 +606,7 @@ void IN_TouchSetFlags_f( void )
|
||||
button->flags = Q_atoi( Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_setflags <name> <file>\n" );
|
||||
Msg( S_USAGE "touch_setflags <name> <file>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetCommand_f( void )
|
||||
@ -616,7 +616,7 @@ void IN_TouchSetCommand_f( void )
|
||||
IN_TouchSetCommand( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_command <name> <command>\n" );
|
||||
Msg( S_USAGE "touch_command <name> <command>\n" );
|
||||
}
|
||||
void IN_TouchReloadConfig_f( void )
|
||||
{
|
||||
@ -779,7 +779,7 @@ void IN_TouchAddButton_f( void )
|
||||
IN_TouchAddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), 0.4, 0.4, 0.6, 0.6, color );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
Msg( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
}
|
||||
|
||||
void IN_TouchEnableEdit_f( void )
|
||||
@ -806,7 +806,7 @@ void IN_TouchDeleteProfile_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: touch_deleteprofile <name>\n" );
|
||||
Msg( S_USAGE "touch_deleteprofile <name>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ static void VID_Mode_f( void )
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Msg( "Usage: vid_mode <modenum>|<width height>\n" );
|
||||
Msg( S_USAGE "vid_mode <modenum>|<width height>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1096,6 +1096,13 @@ typedef struct sentenceEntry_ sentenceEntry_s;
|
||||
sequenceEntry_s *Sequence_Get( const char *fileName, const char *entryName );
|
||||
sentenceEntry_s *Sequence_PickSentence( const char *groupName, int pickMethod, int *picked );
|
||||
|
||||
//
|
||||
// masterlist.c
|
||||
//
|
||||
void NET_InitMasters( void );
|
||||
void NET_SaveMasters( void );
|
||||
qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -951,6 +951,8 @@ void Host_WriteConfig( void )
|
||||
FS_Close( f );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Couldn't write config.cfg.\n" );
|
||||
|
||||
NET_SaveMasters();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -906,6 +906,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
|
||||
Mod_Init();
|
||||
NET_Init();
|
||||
NET_InitMasters();
|
||||
Netchan_Init();
|
||||
|
||||
// allow to change game from the console
|
||||
|
256
engine/common/masterlist.c
Normal file
256
engine/common/masterlist.c
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
masterlist.c - multi-master list
|
||||
Copyright (C) 2018 mittorn
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "netchan.h"
|
||||
|
||||
typedef struct master_s
|
||||
{
|
||||
struct master_s *next;
|
||||
qboolean sent;
|
||||
qboolean save;
|
||||
string address;
|
||||
} master_t;
|
||||
|
||||
struct masterlist_s
|
||||
{
|
||||
master_t *list;
|
||||
qboolean modified;
|
||||
} ml;
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_SendToMasters
|
||||
|
||||
Send request to all masterservers list
|
||||
return true if would block
|
||||
========================
|
||||
*/
|
||||
qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data )
|
||||
{
|
||||
master_t *list;
|
||||
qboolean wait = false;
|
||||
|
||||
for( list = ml.list; list; list = list->next )
|
||||
{
|
||||
netadr_t adr;
|
||||
int res;
|
||||
|
||||
if( list->sent )
|
||||
continue;
|
||||
|
||||
res = NET_StringToAdrNB( list->address, &adr );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
MsgDev( D_INFO, "Can't resolve adr: %s\n", list->address );
|
||||
list->sent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( res == 2 )
|
||||
{
|
||||
list->sent = false;
|
||||
wait = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
list->sent = true;
|
||||
|
||||
NET_SendPacket( sock, len, data, adr );
|
||||
}
|
||||
|
||||
if( !wait )
|
||||
{
|
||||
list = ml.list;
|
||||
|
||||
while( list )
|
||||
{
|
||||
list->sent = false;
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
return wait;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_AddMaster
|
||||
|
||||
Add master to the list
|
||||
========================
|
||||
*/
|
||||
static void NET_AddMaster( char *addr, qboolean save )
|
||||
{
|
||||
master_t *master, *last;
|
||||
|
||||
for( last = ml.list; last && last->next; last = last->next )
|
||||
{
|
||||
if( !Q_strcmp( last->address, addr ) ) // already exists
|
||||
return;
|
||||
}
|
||||
|
||||
master = Mem_Alloc( host.mempool, sizeof( master_t ) );
|
||||
Q_strncpy( master->address, addr, MAX_STRING );
|
||||
master->sent = false;
|
||||
master->save = save;
|
||||
master->next = NULL;
|
||||
|
||||
// link in
|
||||
if( last )
|
||||
last->next = master;
|
||||
else
|
||||
ml.list = master;
|
||||
}
|
||||
|
||||
static void NET_AddMaster_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( S_USAGE "addmaster <address>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
NET_AddMaster( Cmd_Argv( 1 ), true ); // save them into config
|
||||
ml.modified = true; // save config
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_ClearMasters
|
||||
|
||||
Clear master list
|
||||
========================
|
||||
*/
|
||||
static void NET_ClearMasters_f( void )
|
||||
{
|
||||
while( ml.list )
|
||||
{
|
||||
master_t *prev = ml.list;
|
||||
ml.list = ml.list->next;
|
||||
Mem_Free( prev );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_ListMasters_f
|
||||
|
||||
Display current master linked list
|
||||
========================
|
||||
*/
|
||||
static void NET_ListMasters_f( void )
|
||||
{
|
||||
master_t *list;
|
||||
int i;
|
||||
|
||||
Msg( "Master servers\n=============\n" );
|
||||
|
||||
|
||||
for( i = 1, list = ml.list; list; i++, list = list->next )
|
||||
{
|
||||
Msg( "%d\t%s\n", i, list->address );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_LoadMasters
|
||||
|
||||
Load master server list from xashcomm.lst
|
||||
========================
|
||||
*/
|
||||
static void NET_LoadMasters( void )
|
||||
{
|
||||
byte *afile, *pfile;
|
||||
char token[MAX_TOKEN];
|
||||
|
||||
pfile = afile = FS_LoadFile( "xashcomm.lst", NULL, true );
|
||||
|
||||
if( !afile ) // file doesn't exist yet
|
||||
{
|
||||
MsgDev( D_INFO, "Cannot load xashcomm.lst\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// format: master <addr>\n
|
||||
while( ( pfile = COM_ParseFile( pfile, token ) ) )
|
||||
{
|
||||
if( !Q_strcmp( token, "master" ) ) // load addr
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
|
||||
NET_AddMaster( token, true );
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Free( afile );
|
||||
|
||||
ml.modified = false;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_SaveMasters
|
||||
|
||||
Save master server list to xashcomm.lst, except for default
|
||||
========================
|
||||
*/
|
||||
void NET_SaveMasters( void )
|
||||
{
|
||||
file_t *f;
|
||||
master_t *m;
|
||||
|
||||
if( !ml.modified )
|
||||
{
|
||||
MsgDev( D_NOTE, "Master server list not changed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
f = FS_Open( "xashcomm.lst", "w", true );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
MsgDev( D_ERROR, "Couldn't write xashcomm.lst\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
for( m = ml.list; m; m = m->next )
|
||||
{
|
||||
if( m->save )
|
||||
FS_Printf( f, "master %s\n", m->address );
|
||||
}
|
||||
|
||||
FS_Close( f );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
NET_InitMasters
|
||||
|
||||
Initialize master server list
|
||||
========================
|
||||
*/
|
||||
void NET_InitMasters( void )
|
||||
{
|
||||
Cmd_AddRestrictedCommand( "addmaster", NET_AddMaster_f, "add address to masterserver list" );
|
||||
Cmd_AddRestrictedCommand( "clearmasters", NET_ClearMasters_f, "clear masterserver list" );
|
||||
Cmd_AddCommand( "listmasters", NET_ListMasters_f, "list masterservers" );
|
||||
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false );
|
||||
NET_AddMaster( MASTERSERVER_ADR2, false );
|
||||
NET_LoadMasters( );
|
||||
}
|
@ -54,6 +54,7 @@ char *NET_BaseAdrToString( const netadr_t a );
|
||||
qboolean NET_IsReservedAdr( netadr_t a );
|
||||
qboolean NET_CompareClassBAdr( netadr_t a, netadr_t b );
|
||||
qboolean NET_StringToAdr( const char *string, netadr_t *adr );
|
||||
int NET_StringToAdrNB( const char *string, netadr_t *adr );
|
||||
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b );
|
||||
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b );
|
||||
qboolean NET_GetPacket( netsrc_t sock, netadr_t *from, byte *data, size_t *length );
|
||||
@ -62,4 +63,4 @@ qboolean NET_BufferToBufferDecompress( char *dest, uint *destLen, char *source,
|
||||
void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to );
|
||||
void NET_ClearLagData( qboolean bClient, qboolean bServer );
|
||||
|
||||
#endif//NET_WS_H
|
||||
#endif//NET_WS_H
|
||||
|
@ -70,6 +70,7 @@ GNU General Public License for more details.
|
||||
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
|
||||
|
||||
#define MASTERSERVER_ADR "ms.xash.su:27010"
|
||||
#define MASTERSERVER_ADR2 "ms2.xash.su:27010"
|
||||
#define PORT_MASTER 27010
|
||||
#define PORT_CLIENT 27005
|
||||
#define PORT_SERVER 27015
|
||||
|
Loading…
Reference in New Issue
Block a user