mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 11:35:05 +08:00
Compare commits
70 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98acbbad01 | ||
|
|
eb72b6baee | ||
|
|
422addcbb6 | ||
|
|
4a58be2aa0 | ||
|
|
562b54839c | ||
|
|
639eaa9416 | ||
|
|
6c6cb65b30 | ||
|
|
8ea8437e19 | ||
|
|
2656eb1aeb | ||
|
|
fa1e92b127 | ||
|
|
cff8ee13e6 | ||
|
|
3956e3863e | ||
|
|
9600218757 | ||
|
|
2db7cb0d64 | ||
|
|
267a70d621 | ||
|
|
667bedab82 | ||
|
|
49990a0859 | ||
|
|
f7c4cd9398 | ||
|
|
cd4f4d5ad4 | ||
|
|
fe429fe213 | ||
|
|
0a24ca3fe2 | ||
|
|
8c93a0d247 | ||
|
|
5c75dda864 | ||
|
|
55bdded6a4 | ||
|
|
25b2c0f7e3 | ||
|
|
ed522852cf | ||
|
|
224e42d345 | ||
|
|
128a1f59a9 | ||
|
|
40ffde0439 | ||
|
|
ec5578a437 | ||
|
|
1cf40a2d17 | ||
|
|
958ea0ac1d | ||
|
|
a9fdae28b2 | ||
|
|
3d9eb869b0 | ||
|
|
8162c6d42f | ||
|
|
48a9f17222 | ||
|
|
e381d04094 | ||
|
|
0e79326571 | ||
|
|
f7eb8cd913 | ||
|
|
a15c1f99b2 | ||
|
|
ba2191172d | ||
|
|
6ab2c9dbbf | ||
|
|
7da460d4b1 | ||
|
|
ffe7b1f4a1 | ||
|
|
6a1f502d25 | ||
|
|
434359ea01 | ||
|
|
ae2ad6ddf2 | ||
|
|
ec11683dc5 | ||
|
|
47318b0c14 | ||
|
|
60d6214ad7 | ||
|
|
a3e26a21a7 | ||
|
|
d0f3a6f74b | ||
|
|
fee236a050 | ||
|
|
e3e4bcc015 | ||
|
|
2d546ccbf7 | ||
|
|
b41804bb5b | ||
|
|
47a04df189 | ||
|
|
2efedaf46c | ||
|
|
49e43c830b | ||
|
|
763e101208 | ||
|
|
e39a62b1fd | ||
|
|
da76abda75 | ||
|
|
829d7d0a7e | ||
|
|
9f6372b305 | ||
|
|
12edd782c6 | ||
|
|
0b59fa9416 | ||
|
|
cc0f12ed26 | ||
|
|
f42553d0e1 | ||
|
|
e7564420c9 | ||
|
|
e81a0ded11 |
@@ -5,6 +5,7 @@ packages:
|
||||
- freetype-dev
|
||||
- fontconfig-dev
|
||||
- opus-dev
|
||||
- bzip2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -7,6 +7,7 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,6 +6,7 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,6 +6,7 @@ packages:
|
||||
- print/freetype2
|
||||
- x11-fonts/fontconfig
|
||||
- audio/opus
|
||||
- archivers/bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,6 +6,7 @@ packages:
|
||||
- fontconfig
|
||||
- libopus
|
||||
- pkgconf
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -3,6 +3,7 @@ packages:
|
||||
- python3
|
||||
- sdl2
|
||||
- opus
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -342,3 +342,6 @@ enc_temp_folder/
|
||||
|
||||
# KDevelop4
|
||||
*.kdev4
|
||||
|
||||
# ccls langauge server
|
||||
.ccls-*
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -22,3 +22,6 @@
|
||||
[submodule "3rdparty/bzip2/bzip2"]
|
||||
path = 3rdparty/bzip2/bzip2
|
||||
url = https://gitlab.com/bzip2/bzip2
|
||||
[submodule "3rdparty/MultiEmulator"]
|
||||
path = 3rdparty/MultiEmulator
|
||||
url = https://github.com/FWGS/MultiEmulator
|
||||
|
||||
1
3rdparty/MultiEmulator
vendored
Submodule
1
3rdparty/MultiEmulator
vendored
Submodule
Submodule 3rdparty/MultiEmulator added at 2f3c3a40cd
2
3rdparty/bzip2/wscript
vendored
2
3rdparty/bzip2/wscript
vendored
@@ -14,6 +14,7 @@ def configure(conf):
|
||||
conf.define('BZ_UNIX', 1)
|
||||
|
||||
def build(bld):
|
||||
# doesn't work with CMake generator
|
||||
# bld(
|
||||
# features = 'subst',
|
||||
# source = 'bzip2/bz_version.h.in',
|
||||
@@ -27,7 +28,6 @@ def build(bld):
|
||||
source = bz_sources,
|
||||
target = 'bzip2',
|
||||
# use = 'bz_version.h',
|
||||
features = 'c',
|
||||
includes = ['.', 'bzip2/'],
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
export_includes = ['bzip2/']
|
||||
|
||||
2
3rdparty/extras/xash-extras
vendored
2
3rdparty/extras/xash-extras
vendored
Submodule 3rdparty/extras/xash-extras updated: f4ff263d42...9050d05a7b
2
3rdparty/gl-wes-v2
vendored
2
3rdparty/gl-wes-v2
vendored
Submodule 3rdparty/gl-wes-v2 updated: 2d9b5afe10...d4ed038d13
1
3rdparty/gl4es/wscript
vendored
1
3rdparty/gl4es/wscript
vendored
@@ -16,7 +16,6 @@ def build(bld):
|
||||
|
||||
bld.stlib(source = gl4es_srcdir.ant_glob(['gl/*.c', 'gl/*/*.c', 'glx/hardext.c']),
|
||||
target = 'gl4es',
|
||||
features = 'c',
|
||||
includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'],
|
||||
defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'NO_LOADER', 'STATICLIB'],
|
||||
cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'],
|
||||
|
||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: b7edbaf2de...0bb921ea8d
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: e75792de03...6c0f341b7b
2
3rdparty/opus/opus
vendored
2
3rdparty/opus/opus
vendored
Submodule 3rdparty/opus/opus updated: 8cf872a186...82ac57d9f1
2
3rdparty/opus/wscript
vendored
2
3rdparty/opus/wscript
vendored
@@ -27,7 +27,7 @@ def build(bld):
|
||||
'opus/celt/opus_custom_demo.c'
|
||||
])
|
||||
includes = ['opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/']
|
||||
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.3.1"', 'CUSTOM_MODES']
|
||||
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.4.0"', 'CUSTOM_MODES']
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
|
||||
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 7276993f3f...e0ab95229d
17
README.md
17
README.md
@@ -61,23 +61,24 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
|
||||
#### GNU/Linux
|
||||
##### Debian/Ubuntu
|
||||
* For 32-bit engine on 64-bit x86 operating system:
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
|
||||
* Install development tools: `$ sudo apt install build-essential gcc-multilib g++-multilib python libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype6-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
|
||||
* Install `aptitude` ([why?](https://github.com/FWGS/xash3d-fwgs/issues/1828#issuecomment-2415131759)): `$ sudo apt update && sudo apt upgrade && sudo apt install aptitude`
|
||||
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
|
||||
|
||||
* For non-x86 systems:
|
||||
* Install development tools: `$ sudo apt install build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
##### RedHat/Fedora
|
||||
* For 32-bit engine on 64-bit x86 operating system:
|
||||
* Install development tools: `$ sudo dnf install gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
||||
|
||||
* For non-x86 systems:
|
||||
* Install development tools: `$ sudo dnf install gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void CL_PlayCDTrack_f( void )
|
||||
if( paused ) Con_Printf( "Paused %s track %u\n", looped ? "looping" : "playing", track );
|
||||
else Con_Printf( "Currently %s track %u\n", looped ? "looping" : "playing", track );
|
||||
}
|
||||
Con_Printf( "Volume is %f\n", Cvar_VariableValue( "MP3Volume" ));
|
||||
Con_Printf( "Volume is %f\n", s_musicvolume.value );
|
||||
return;
|
||||
}
|
||||
else Con_Printf( "%s: unknown command %s\n", Cmd_Argv( 0 ), command );
|
||||
|
||||
@@ -50,7 +50,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
Con_Reportf( "Download refused, cl_allow_download is 0\n" );
|
||||
Con_Reportf( "Download refused, cl_allowdownload is 0\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
||||
|
||||
if( cl.http_download )
|
||||
{
|
||||
HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
|
||||
HTTP_AddDownload( filepath, pResource->nDownloadSize, true, pResource );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -285,7 +285,7 @@ void CL_WriteDemoUserCmd( int cmdnumber )
|
||||
|
||||
// write usercmd_t
|
||||
MSG_Init( &buf, "UserCmd", data, sizeof( data ));
|
||||
CL_WriteUsercmd( &buf, -1, cmdnumber ); // always no delta
|
||||
CL_WriteUsercmd( PROTO_CURRENT, &buf, -1, cmdnumber ); // always no delta, always in current protocol
|
||||
|
||||
bytes = MSG_GetNumBytesWritten( &buf );
|
||||
|
||||
@@ -708,7 +708,7 @@ static void CL_DemoStartPlayback( int mode )
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize, 0 );
|
||||
CL_SetupNetchanForProtocol( cls.legacymode );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
@@ -1470,7 +1470,7 @@ static qboolean CL_ParseDemoHeader( const char *callee, const char *filename, fi
|
||||
return false;
|
||||
}
|
||||
|
||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_LEGACY_VERSION )
|
||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_LEGACY_VERSION && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: net protocol outdated (%i should be %i or %i)\n",
|
||||
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_LEGACY_VERSION );
|
||||
|
||||
@@ -3485,7 +3485,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
nr->flags = flags;
|
||||
|
||||
// local servers request
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "netinfo %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, request );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, A2A_NETINFO" %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, request );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1303,6 +1303,16 @@ static gameinfo2_t *pfnGetModInfo( int gi_version, int i )
|
||||
return &gameui.modsInfo[i];
|
||||
}
|
||||
|
||||
static int pfnIsCvarReadOnly( const char *name )
|
||||
{
|
||||
convar_t *cv = Cvar_FindVar( name );
|
||||
|
||||
if( !cv )
|
||||
return -1;
|
||||
|
||||
return FBitSet( cv->flags, FCVAR_READ_ONLY ) ? 1 : 0;
|
||||
}
|
||||
|
||||
static ui_extendedfuncs_t gExtendedfuncs =
|
||||
{
|
||||
pfnEnableTextInput,
|
||||
@@ -1318,6 +1328,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
&gNetApi,
|
||||
pfnGetGameInfo,
|
||||
pfnGetModInfo,
|
||||
pfnIsCvarReadOnly,
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -698,7 +698,7 @@ void CL_ParseCustomization( sizebuf_t *msg )
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
Con_DPrintf( "Refusing new resource, cl_allow_download set to 0\n" );
|
||||
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
||||
Mem_Free( pRes );
|
||||
return;
|
||||
}
|
||||
@@ -925,9 +925,13 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_GOLDSRC_EDICTS );
|
||||
clgame.maxModels = 512; // ???
|
||||
Q_strncpy( clgame.maptitle, clgame.mapname, sizeof( clgame.maptitle ));
|
||||
|
||||
Host_ValidateEngineFeatures( 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
@@ -935,17 +939,19 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_LEGACY_EDICTS );
|
||||
clgame.maxModels = 512; // ???
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
mask = ENGINE_FEATURES_MASK;
|
||||
}
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), sizeof( clgame.mapname ));
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||
background = MSG_ReadOneBit( msg );
|
||||
Q_strncpy( gamefolder, MSG_ReadString( msg ), sizeof( gamefolder ));
|
||||
Host_ValidateEngineFeatures( MSG_ReadDword( msg ));
|
||||
Host_ValidateEngineFeatures( 0, MSG_ReadDword( msg ));
|
||||
|
||||
if( proto != PROTO_LEGACY )
|
||||
{
|
||||
@@ -1043,9 +1049,13 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
COM_ClearCustomizationList( &cl.players[i].customdata, true );
|
||||
CL_CreateCustomizationList();
|
||||
|
||||
if( proto != PROTO_LEGACY )
|
||||
// request resources from server
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
CL_ServerCommand( true, "sendres" );
|
||||
}
|
||||
else if( proto != PROTO_LEGACY )
|
||||
{
|
||||
// request resources from server
|
||||
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
|
||||
}
|
||||
|
||||
@@ -1496,9 +1506,15 @@ void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
if( proto != PROTO_LEGACY )
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
|
||||
if( slot == cl.playernum ) gameui.playerinfo = *player;
|
||||
if( proto == PROTO_GOLDSRC && ( !COM_CheckStringEmpty( player->userinfo ) || !COM_CheckStringEmpty( player->name )))
|
||||
active = false;
|
||||
|
||||
if( active && slot == cl.playernum )
|
||||
gameui.playerinfo = *player;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
if( !active )
|
||||
{
|
||||
COM_ClearCustomizationList( &player->customdata, true );
|
||||
|
||||
@@ -1601,7 +1617,7 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
vec3_t mins, maxs;
|
||||
string filename;
|
||||
CRC32_t crcFile;
|
||||
byte md5[16];
|
||||
byte md5[16] = { 0 };
|
||||
consistency_t *pc;
|
||||
int i, pos;
|
||||
|
||||
@@ -1617,6 +1633,8 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
MSG_StartBitWriting( msg );
|
||||
}
|
||||
|
||||
FS_AllowDirectPaths( true );
|
||||
|
||||
for( i = 0; i < cl.num_consistency; i++ )
|
||||
{
|
||||
qboolean have_file = true;
|
||||
@@ -1645,6 +1663,8 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
switch( pc->check_type )
|
||||
{
|
||||
case force_exactfile:
|
||||
// servers rely on md5 not being initialized after previous file
|
||||
// if current file doesn't exist
|
||||
MD5_HashFile( md5, filename, NULL );
|
||||
memcpy( &pc->value, md5, sizeof( pc->value ));
|
||||
LittleLongSW( pc->value );
|
||||
@@ -1693,6 +1713,8 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
}
|
||||
|
||||
FS_AllowDirectPaths( false );
|
||||
|
||||
MSG_WriteOneBit( msg, 0 );
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
|
||||
@@ -264,7 +264,7 @@ static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
Con_DPrintf( "Refusing new resource, cl_allow_download set to 0\n" );
|
||||
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
||||
reslist.rescount = 0;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
continue; // already exists
|
||||
|
||||
host.downloadcount++;
|
||||
HTTP_AddDownload( path, -1, true );
|
||||
HTTP_AddDownload( path, -1, true, NULL );
|
||||
}
|
||||
|
||||
if( !host.downloadcount )
|
||||
|
||||
@@ -29,7 +29,7 @@ static void CL_ParseExtraInfo( sizebuf_t *msg )
|
||||
|
||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
||||
if( COM_CheckStringEmpty( clientfallback ))
|
||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__ );
|
||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
||||
|
||||
if( MSG_ReadByte( msg ))
|
||||
{
|
||||
|
||||
@@ -853,7 +853,6 @@ void SCR_Shutdown( void )
|
||||
{
|
||||
if( !scr_init ) return;
|
||||
|
||||
Cmd_RemoveCommand( "timerefresh" );
|
||||
Cmd_RemoveCommand( "skyname" );
|
||||
Cmd_RemoveCommand( "viewpos" );
|
||||
UI_SetActiveMenu( false );
|
||||
|
||||
@@ -560,7 +560,6 @@ typedef struct
|
||||
byte datagram_buf[MAX_DATAGRAM];
|
||||
|
||||
netchan_t netchan;
|
||||
int challenge; // from the server to use for connecting
|
||||
|
||||
float packet_loss;
|
||||
double packet_loss_recalc_time;
|
||||
@@ -748,8 +747,8 @@ void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel );
|
||||
void CL_Init( void );
|
||||
void CL_Disconnect_f( void );
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename );
|
||||
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
|
||||
int CL_GetFragmentSize( void *unused , fragsize_t mode );
|
||||
void CL_WriteUsercmd( connprotocol_t proto, sizebuf_t *msg, int from, int to );
|
||||
void CL_SetupNetchanForProtocol( connprotocol_t proto );
|
||||
qboolean CL_PrecacheResources( void );
|
||||
void CL_SetupOverviewParams( void );
|
||||
void CL_UpdateFrameLerp( void );
|
||||
|
||||
@@ -875,7 +875,6 @@ void Con_Print( const char *txt )
|
||||
Con_DeleteLastLine();
|
||||
cr_pending = 0;
|
||||
}
|
||||
|
||||
c = *txt;
|
||||
|
||||
switch( c )
|
||||
@@ -883,10 +882,13 @@ void Con_Print( const char *txt )
|
||||
case '\0':
|
||||
break;
|
||||
case '\r':
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = 1;
|
||||
bufpos = 0;
|
||||
if( txt[1] != '\n' )
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = 1;
|
||||
bufpos = 0;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
@@ -894,6 +896,7 @@ void Con_Print( const char *txt )
|
||||
bufpos = 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
buf[bufpos++] = c | mask;
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
|
||||
{
|
||||
@@ -1941,7 +1944,7 @@ void Con_DrawConsole( void )
|
||||
{
|
||||
if( !cl_allow_levelshots.value && !cls.timedemo )
|
||||
{
|
||||
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
|
||||
if( cls.key_dest != key_console && ( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )))
|
||||
con.vislines = con.showlines = 0;
|
||||
else con.vislines = con.showlines = refState.height;
|
||||
}
|
||||
|
||||
@@ -1214,13 +1214,13 @@ void Cmd_Unlink( int group )
|
||||
cmd_t **prev;
|
||||
int count = 0;
|
||||
|
||||
if( Cvar_VariableInteger( "host_gameloaded" ) && FBitSet( group, CMD_SERVERDLL ))
|
||||
if( FBitSet( group, CMD_SERVERDLL ) && Cvar_VariableInteger( "host_gameloaded" ))
|
||||
return;
|
||||
|
||||
if( Cvar_VariableInteger( "host_clientloaded" ) && FBitSet( group, CMD_CLIENTDLL ))
|
||||
if( FBitSet( group, CMD_CLIENTDLL ) && Cvar_VariableInteger( "host_clientloaded" ))
|
||||
return;
|
||||
|
||||
if( Cvar_VariableInteger( "host_gameuiloaded" ) && FBitSet( group, CMD_GAMEUIDLL ))
|
||||
if( FBitSet( group, CMD_GAMEUIDLL ) && Cvar_VariableInteger( "host_gameuiloaded" ))
|
||||
return;
|
||||
|
||||
prev = &cmd_functions;
|
||||
|
||||
@@ -537,7 +537,7 @@ void Host_WriteVideoConfig( void );
|
||||
void Host_WriteConfig( void );
|
||||
void Host_ShutdownServer( void );
|
||||
void Host_Error( const char *error, ... ) _format( 1 );
|
||||
void Host_ValidateEngineFeatures( uint32_t features );
|
||||
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features );
|
||||
void Host_Frame( double time );
|
||||
void Host_Credits( void );
|
||||
|
||||
|
||||
@@ -16,12 +16,37 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "ref_api.h"
|
||||
#include "server.h"
|
||||
|
||||
ref_globals_t refState;
|
||||
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
const char *CL_MsgInfo( int cmd )
|
||||
{
|
||||
static string sz;
|
||||
|
||||
Q_strncpy( sz, "???", sizeof( sz ));
|
||||
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
const char *svc_string = svc_strings[cmd];
|
||||
|
||||
Q_strncpy( sz, svc_string, sizeof( sz ));
|
||||
}
|
||||
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
{
|
||||
if( svgame.msg[i].number == cmd )
|
||||
{
|
||||
Q_strncpy( sz, svgame.msg[i].name, sizeof( sz ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
int GAME_EXPORT CL_Active( void )
|
||||
|
||||
@@ -228,27 +228,8 @@ Host_ValidateEngineFeatures
|
||||
validate features bits and set host.features
|
||||
==============
|
||||
*/
|
||||
void Host_ValidateEngineFeatures( uint32_t features )
|
||||
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features )
|
||||
{
|
||||
uint32_t mask = ENGINE_FEATURES_MASK;
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
{
|
||||
switch( cls.legacymode )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
break;
|
||||
default:
|
||||
mask = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't allow unsupported bits
|
||||
features &= mask;
|
||||
|
||||
|
||||
@@ -1055,7 +1055,7 @@ static void HPAK_Extract_f( void )
|
||||
FS_Seek( f, entry->filepos, SEEK_SET );
|
||||
FS_Read( f, pData, nDataSize );
|
||||
|
||||
Q_snprintf( szFileOut, sizeof( szFileOut ), "hpklmps\\lmp%04i.bmp", nCurrent );
|
||||
Q_snprintf( szFileOut, sizeof( szFileOut ), "hpklmps/lmp%04i.bmp", nCurrent );
|
||||
FS_WriteFile( szFileOut, pData, nDataSize );
|
||||
if( pData ) Mem_Free( pData );
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ static const byte mungify_table3[] =
|
||||
0x0A, 0x2D, 0x48, 0x0C, 0x4A, 0x12, 0xA9, 0xB5,
|
||||
};
|
||||
|
||||
static int COM_SwapLong( int c )
|
||||
static uint COM_SwapLong( uint c )
|
||||
{
|
||||
return ((( c >> 0 ) & 0xFF) << 24 ) +
|
||||
((( c >> 8 ) & 0xFF) << 16 ) +
|
||||
@@ -48,12 +48,12 @@ static void COM_GenericMunge( byte *data, const size_t len, const int seq, const
|
||||
|
||||
for( i = 0; i < mungelen; i++ )
|
||||
{
|
||||
uint *pc, c;
|
||||
uint32_t c;
|
||||
void *pc = &data[i * 4];
|
||||
byte *p;
|
||||
int j;
|
||||
|
||||
pc = (uint *)&data[i * 4];
|
||||
c = *pc;
|
||||
memcpy( &c, pc, sizeof( c ));
|
||||
c ^= seq;
|
||||
if( !reverse )
|
||||
c = COM_SwapLong( c );
|
||||
@@ -65,7 +65,7 @@ static void COM_GenericMunge( byte *data, const size_t len, const int seq, const
|
||||
if( reverse )
|
||||
c = COM_SwapLong( c );
|
||||
c ^= ~seq;
|
||||
*pc = c;
|
||||
memcpy( pc, &c, sizeof( c ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
|
||||
}
|
||||
else if( type == NS_CLIENT )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg && cmd != clc_nop )
|
||||
{
|
||||
Con_Printf( "^1cl^7 (%d) write: %s\n", sb->iCurBit, clc_strings[cmd] );
|
||||
}
|
||||
@@ -574,7 +574,8 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
|
||||
{
|
||||
if( type == NS_SERVER )
|
||||
{
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
if( cmd != svc_nop )
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
}
|
||||
else if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
|
||||
@@ -324,6 +324,12 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, voi
|
||||
|
||||
memset( chan, 0, sizeof( *chan ));
|
||||
|
||||
if( pfnBlockSize == NULL )
|
||||
{
|
||||
Host_Error( "%s: pfnBlockSize == NULL", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
chan->sock = sock;
|
||||
chan->remote_address = adr;
|
||||
chan->last_received = host.realtime;
|
||||
@@ -514,7 +520,7 @@ Netchan_OutOfBand
|
||||
Sends an out-of-band datagram
|
||||
================
|
||||
*/
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int len, byte *data )
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int len, const byte *data )
|
||||
{
|
||||
byte buf[MAX_PRINT_MSG + 4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
@@ -738,9 +744,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
||||
if( MSG_GetNumBytesWritten( msg ) == 0 )
|
||||
return;
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
|
||||
wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t ));
|
||||
|
||||
@@ -919,9 +923,7 @@ void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filenam
|
||||
|
||||
if( !size ) return;
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
|
||||
if( !LZSS_IsCompressed( pbuf ))
|
||||
{
|
||||
@@ -1024,9 +1026,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
|
||||
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", filename );
|
||||
compressedFileTime = FS_FileTime( compressedfilename, false );
|
||||
@@ -1504,7 +1504,7 @@ transmition / retransmition of the reliable messages.
|
||||
A 0 length will still generate a packet and deal with the reliable messages.
|
||||
================
|
||||
*/
|
||||
void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
{
|
||||
byte send_buf[NET_MAX_MESSAGE];
|
||||
qboolean send_reliable_fragment;
|
||||
@@ -1521,6 +1521,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
return;
|
||||
}
|
||||
|
||||
if( chan->pfnBlockSize == NULL ) // not initialized
|
||||
return;
|
||||
|
||||
// if the remote side dropped the last reliable message, resend it
|
||||
send_reliable = false;
|
||||
|
||||
@@ -1559,12 +1562,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
// stall reliable payloads if sending from frag buffer
|
||||
if( send_from_regular && ( send_from_frag[FRAG_NORMAL_STREAM] ))
|
||||
{
|
||||
int maxsize = MAX_RELIABLE_PAYLOAD;
|
||||
int maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
send_from_regular = false;
|
||||
|
||||
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
if( maxsize == 0 )
|
||||
maxsize = MAX_RELIABLE_PAYLOAD;
|
||||
|
||||
@@ -1746,9 +1746,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
|
||||
if( length )
|
||||
{
|
||||
int maxsize = NET_MAX_MESSAGE;
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_UNRELIABLE );
|
||||
int maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_UNRELIABLE );
|
||||
|
||||
if( (( MSG_GetNumBytesWritten( &send ) + length ) >> 3) <= maxsize )
|
||||
MSG_WriteBits( &send, data, length );
|
||||
@@ -1782,9 +1780,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
// send the datagram
|
||||
if( !CL_IsPlaybackDemo( ))
|
||||
{
|
||||
int splitsize = 0;
|
||||
if( chan->pfnBlockSize )
|
||||
splitsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
int splitsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
|
||||
if( chan->use_munge )
|
||||
COM_Munge2( send.pData + 8, MSG_GetNumBytesWritten( &send ) - 8, (byte)( chan->outgoing_sequence - 1 ));
|
||||
|
||||
1188
engine/common/net_http.c
Normal file
1188
engine/common/net_http.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,17 +18,7 @@ GNU General Public License for more details.
|
||||
#include "netchan.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "ipv6text.h"
|
||||
|
||||
#if XASH_NO_NETWORK
|
||||
#include "platform/stub/net_stub.h"
|
||||
#elif XASH_WIN32
|
||||
#include "platform/win32/net.h"
|
||||
#elif XASH_PSVITA
|
||||
#include "platform/psvita/net_psvita.h"
|
||||
static const struct in6_addr in6addr_any;
|
||||
#else
|
||||
#include "platform/posix/net.h"
|
||||
#endif
|
||||
#include "net_ws_private.h"
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL_thread.h>
|
||||
@@ -141,85 +131,6 @@ static CVAR_DEFINE_AUTO( net6_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "c
|
||||
|
||||
static void NET_ClearLagData( qboolean bClient, qboolean bServer );
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_ErrorString
|
||||
====================
|
||||
*/
|
||||
static const char *NET_ErrorString( void )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
int err = WSANOTINITIALISED;
|
||||
|
||||
if( net.initialized )
|
||||
err = WSAGetLastError();
|
||||
|
||||
switch( err )
|
||||
{
|
||||
case WSAEINTR: return "WSAEINTR";
|
||||
case WSAEBADF: return "WSAEBADF";
|
||||
case WSAEACCES: return "WSAEACCES";
|
||||
case WSAEFAULT: return "WSAEFAULT";
|
||||
case WSAEINVAL: return "WSAEINVAL";
|
||||
case WSAEMFILE: return "WSAEMFILE";
|
||||
case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
|
||||
case WSAEINPROGRESS: return "WSAEINPROGRESS";
|
||||
case WSAEALREADY: return "WSAEALREADY";
|
||||
case WSAENOTSOCK: return "WSAENOTSOCK";
|
||||
case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
|
||||
case WSAEMSGSIZE: return "WSAEMSGSIZE";
|
||||
case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
|
||||
case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
|
||||
case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
|
||||
case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
|
||||
case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
|
||||
case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
|
||||
case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
|
||||
case WSAEADDRINUSE: return "WSAEADDRINUSE";
|
||||
case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
|
||||
case WSAENETDOWN: return "WSAENETDOWN";
|
||||
case WSAENETUNREACH: return "WSAENETUNREACH";
|
||||
case WSAENETRESET: return "WSAENETRESET";
|
||||
case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
|
||||
case WSAECONNRESET: return "WSAECONNRESET";
|
||||
case WSAENOBUFS: return "WSAENOBUFS";
|
||||
case WSAEISCONN: return "WSAEISCONN";
|
||||
case WSAENOTCONN: return "WSAENOTCONN";
|
||||
case WSAESHUTDOWN: return "WSAESHUTDOWN";
|
||||
case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
|
||||
case WSAETIMEDOUT: return "WSAETIMEDOUT";
|
||||
case WSAECONNREFUSED: return "WSAECONNREFUSED";
|
||||
case WSAELOOP: return "WSAELOOP";
|
||||
case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
|
||||
case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
|
||||
case WSAEDISCON: return "WSAEDISCON";
|
||||
case WSASYSNOTREADY: return "WSASYSNOTREADY";
|
||||
case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
|
||||
case WSANOTINITIALISED: return "WSANOTINITIALISED";
|
||||
case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
|
||||
case WSATRY_AGAIN: return "WSATRY_AGAIN";
|
||||
case WSANO_RECOVERY: return "WSANO_RECOVERY";
|
||||
case WSANO_DATA: return "WSANO_DATA";
|
||||
default: return "NO ERROR";
|
||||
}
|
||||
#else
|
||||
return strerror( errno );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline socklen_t NET_SockAddrLen( const struct sockaddr_storage *addr )
|
||||
{
|
||||
switch ( addr->ss_family )
|
||||
{
|
||||
case AF_INET:
|
||||
return sizeof( struct sockaddr_in );
|
||||
case AF_INET6:
|
||||
return sizeof( struct sockaddr_in6 );
|
||||
default:
|
||||
return sizeof( *addr ); // what the fuck is this?
|
||||
}
|
||||
}
|
||||
|
||||
static inline qboolean NET_IsSocketError( int retval )
|
||||
{
|
||||
#if XASH_WIN32 || XASH_DOS4GW
|
||||
@@ -491,7 +402,7 @@ idnewt:28000
|
||||
192.246.40.70:28000
|
||||
=============
|
||||
*/
|
||||
static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_storage *sadr, qboolean nonblocking, int family )
|
||||
net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_storage *sadr, qboolean nonblocking, int family )
|
||||
{
|
||||
int ret = 0, port;
|
||||
char *colon;
|
||||
@@ -1018,16 +929,6 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_IsLocalAddress
|
||||
====================
|
||||
*/
|
||||
qboolean NET_IsLocalAddress( netadr_t adr )
|
||||
{
|
||||
return (adr.type == NA_LOOPBACK) ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
NET_StringToAdr
|
||||
@@ -2220,860 +2121,3 @@ void NET_Shutdown( void )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================================================
|
||||
|
||||
HTTP downloader
|
||||
|
||||
=================================================
|
||||
*/
|
||||
|
||||
#define MAX_HTTP_BUFFER_SIZE (BIT( 13 ))
|
||||
|
||||
typedef struct httpserver_s
|
||||
{
|
||||
char host[256];
|
||||
int port;
|
||||
char path[MAX_SYSPATH];
|
||||
qboolean needfree;
|
||||
struct httpserver_s *next;
|
||||
|
||||
} httpserver_t;
|
||||
|
||||
enum connectionstate
|
||||
{
|
||||
HTTP_QUEUE = 0,
|
||||
HTTP_OPENED,
|
||||
HTTP_SOCKET,
|
||||
HTTP_NS_RESOLVED,
|
||||
HTTP_CONNECTED,
|
||||
HTTP_REQUEST,
|
||||
HTTP_REQUEST_SENT,
|
||||
HTTP_RESPONSE_RECEIVED,
|
||||
HTTP_FREE
|
||||
};
|
||||
|
||||
typedef struct httpfile_s
|
||||
{
|
||||
struct httpfile_s *next;
|
||||
httpserver_t *server;
|
||||
char path[MAX_SYSPATH];
|
||||
file_t *file;
|
||||
int socket;
|
||||
int size;
|
||||
int downloaded;
|
||||
int lastchecksize;
|
||||
float checktime;
|
||||
float blocktime;
|
||||
int id;
|
||||
enum connectionstate state;
|
||||
qboolean process;
|
||||
|
||||
// query or response
|
||||
char buf[MAX_HTTP_BUFFER_SIZE+1];
|
||||
int header_size, query_length, bytes_sent;
|
||||
} httpfile_t;
|
||||
|
||||
static struct http_static_s
|
||||
{
|
||||
// file and server lists
|
||||
httpfile_t *first_file, *last_file;
|
||||
httpserver_t *first_server, *last_server;
|
||||
} http;
|
||||
|
||||
|
||||
static CVAR_DEFINE_AUTO( http_useragent, "", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "User-Agent string" );
|
||||
static CVAR_DEFINE_AUTO( http_autoremove, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "remove broken files" );
|
||||
static CVAR_DEFINE_AUTO( http_timeout, "45", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "timeout for http downloader" );
|
||||
static CVAR_DEFINE_AUTO( http_maxconnections, "4", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "maximum http connection number" );
|
||||
|
||||
/*
|
||||
========================
|
||||
HTTP_ClearCustomServers
|
||||
========================
|
||||
*/
|
||||
void HTTP_ClearCustomServers( void )
|
||||
{
|
||||
if( http.first_file )
|
||||
return; // may be referenced
|
||||
|
||||
while( http.first_server && http.first_server->needfree )
|
||||
{
|
||||
httpserver_t *tmp = http.first_server;
|
||||
|
||||
http.first_server = http.first_server->next;
|
||||
Mem_Free( tmp );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
HTTP_FreeFile
|
||||
|
||||
Skip to next server/file
|
||||
==============
|
||||
*/
|
||||
static void HTTP_FreeFile( httpfile_t *file, qboolean error )
|
||||
{
|
||||
char incname[256];
|
||||
|
||||
// Allways close file and socket
|
||||
if( file->file )
|
||||
FS_Close( file->file );
|
||||
|
||||
file->file = NULL;
|
||||
|
||||
if( file->socket != -1 )
|
||||
closesocket( file->socket );
|
||||
|
||||
file->socket = -1;
|
||||
|
||||
Q_snprintf( incname, sizeof( incname ), DEFAULT_DOWNLOADED_DIRECTORY "%s.incomplete", file->path );
|
||||
if( error )
|
||||
{
|
||||
// Switch to next fastdl server if present
|
||||
if( file->server && ( file->state > HTTP_QUEUE ) && ( file->state != HTTP_FREE ))
|
||||
{
|
||||
file->server = file->server->next;
|
||||
file->state = HTTP_QUEUE; // Reset download state, HTTP_Run() will open file again
|
||||
return;
|
||||
}
|
||||
|
||||
// Called because there was no servers to download, free file now
|
||||
if( http_autoremove.value == 1 ) // remove broken file
|
||||
FS_Delete( incname );
|
||||
else // autoremove disabled, keep file
|
||||
Con_Printf( "cannot download %s from any server. "
|
||||
"You may remove %s now\n", file->path, incname ); // Warn about trash file
|
||||
|
||||
if( file->process )
|
||||
CL_ProcessFile( false, file->path ); // Process file, increase counter
|
||||
}
|
||||
else
|
||||
{
|
||||
// Success, rename and process file
|
||||
char name[256];
|
||||
|
||||
Q_snprintf( name, sizeof( name ), DEFAULT_DOWNLOADED_DIRECTORY "%s", file->path );
|
||||
FS_Rename( incname, name );
|
||||
|
||||
if( file->process )
|
||||
CL_ProcessFile( true, name );
|
||||
else
|
||||
Con_Printf( "successfully downloaded %s, processing disabled!\n", name );
|
||||
}
|
||||
|
||||
file->state = HTTP_FREE;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
HTTP_AutoClean
|
||||
|
||||
remove files with HTTP_FREE state from list
|
||||
===================
|
||||
*/
|
||||
static void HTTP_AutoClean( void )
|
||||
{
|
||||
httpfile_t *curfile, *prevfile = 0;
|
||||
|
||||
// clean all files marked to free
|
||||
for( curfile = http.first_file; curfile; curfile = curfile->next )
|
||||
{
|
||||
if( curfile->state != HTTP_FREE )
|
||||
{
|
||||
prevfile = curfile;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( curfile == http.first_file )
|
||||
{
|
||||
http.first_file = http.first_file->next;
|
||||
Mem_Free( curfile );
|
||||
curfile = http.first_file;
|
||||
if( !curfile )
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( prevfile )
|
||||
prevfile->next = curfile->next;
|
||||
Mem_Free( curfile );
|
||||
curfile = prevfile;
|
||||
if( !curfile )
|
||||
break;
|
||||
}
|
||||
http.last_file = prevfile;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
HTTP_ProcessStream
|
||||
|
||||
process incoming data
|
||||
===================
|
||||
*/
|
||||
static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
||||
{
|
||||
char buf[sizeof( curfile->buf )];
|
||||
char *begin = 0;
|
||||
int res;
|
||||
|
||||
if( curfile->header_size >= sizeof( buf ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Header too big, the size is %d\n", curfile->header_size );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
|
||||
while( ( res = recv( curfile->socket, buf, sizeof( buf ) - curfile->header_size, 0 )) > 0) // if we got there, we are receiving data
|
||||
{
|
||||
curfile->blocktime = 0;
|
||||
|
||||
if( curfile->state < HTTP_RESPONSE_RECEIVED ) // Response still not received
|
||||
{
|
||||
memcpy( curfile->buf + curfile->header_size, buf, res );
|
||||
curfile->buf[curfile->header_size + res] = 0;
|
||||
begin = Q_strstr( curfile->buf, "\r\n\r\n" );
|
||||
|
||||
if( begin ) // Got full header
|
||||
{
|
||||
int cutheadersize = begin - curfile->buf + 4; // after that begin of data
|
||||
char *content_length_line;
|
||||
|
||||
if( !Q_strstr( curfile->buf, "200 OK" ))
|
||||
{
|
||||
*begin = 0; // cut string to print out response
|
||||
begin = Q_strchr( curfile->buf, '\r' );
|
||||
|
||||
if( !begin ) begin = Q_strchr( curfile->buf, '\n' );
|
||||
if( begin )
|
||||
*begin = 0;
|
||||
|
||||
Con_Printf( S_ERROR "%s: bad response: %s\n", curfile->path, curfile->buf );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
|
||||
// print size
|
||||
content_length_line = Q_stristr( curfile->buf, "Content-Length: " );
|
||||
if( content_length_line )
|
||||
{
|
||||
int size;
|
||||
|
||||
content_length_line += sizeof( "Content-Length: " ) - 1;
|
||||
size = Q_atoi( content_length_line );
|
||||
|
||||
Con_Reportf( "HTTP: Got 200 OK! File size is %d\n", size );
|
||||
|
||||
if( ( curfile->size != -1 ) && ( curfile->size != size )) // check size if specified, not used
|
||||
Con_Reportf( S_WARN "Server reports wrong file size for %s!\n", curfile->path );
|
||||
|
||||
curfile->size = size;
|
||||
curfile->header_size = 0;
|
||||
}
|
||||
|
||||
if( curfile->size == -1 )
|
||||
{
|
||||
// Usually fastdl's reports file size if link is correct
|
||||
Con_Printf( S_ERROR "file size is unknown, refusing download!\n" );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
|
||||
curfile->state = HTTP_RESPONSE_RECEIVED; // got response, let's start download
|
||||
begin += 4;
|
||||
|
||||
// Write remaining message part
|
||||
if( res - cutheadersize - curfile->header_size > 0 )
|
||||
{
|
||||
int ret = FS_Write( curfile->file, begin, res - cutheadersize - curfile->header_size );
|
||||
|
||||
if( ret != res - cutheadersize - curfile->header_size ) // could not write file
|
||||
{
|
||||
// close it and go to next
|
||||
Con_Printf( S_ERROR "write failed for %s!\n", curfile->path );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
curfile->downloaded += ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
curfile->header_size += res;
|
||||
}
|
||||
else if( res > 0 )
|
||||
{
|
||||
// data download
|
||||
int ret = FS_Write( curfile->file, buf, res );
|
||||
|
||||
if ( ret != res )
|
||||
{
|
||||
// close it and go to next
|
||||
Con_Printf( S_ERROR "write failed for %s!\n", curfile->path );
|
||||
curfile->state = HTTP_FREE;
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
|
||||
curfile->downloaded += ret;
|
||||
curfile->lastchecksize += ret;
|
||||
|
||||
// as after it will run in same frame
|
||||
if( curfile->checktime > 5 )
|
||||
{
|
||||
float speed = (float)curfile->lastchecksize / ( 5.0f * 1024 );
|
||||
|
||||
curfile->checktime = 0;
|
||||
Con_Reportf( "download speed %f KB/s\n", speed );
|
||||
curfile->lastchecksize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
curfile->checktime += host.frametime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
HTTP_Run
|
||||
|
||||
Download next file block of each active file
|
||||
Call every frame
|
||||
==============
|
||||
*/
|
||||
void HTTP_Run( void )
|
||||
{
|
||||
httpfile_t *curfile;
|
||||
int iActiveCount = 0;
|
||||
int iProgressCount = 0;
|
||||
float flProgress = 0;
|
||||
qboolean fResolving = false;
|
||||
|
||||
for( curfile = http.first_file; curfile; curfile = curfile->next )
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
|
||||
if( curfile->state == HTTP_FREE )
|
||||
continue;
|
||||
|
||||
if( curfile->state == HTTP_QUEUE )
|
||||
{
|
||||
char name[MAX_SYSPATH];
|
||||
|
||||
if( iActiveCount > http_maxconnections.value )
|
||||
continue;
|
||||
|
||||
if( !curfile->server )
|
||||
{
|
||||
Con_Printf( S_ERROR "no servers to download %s!\n", curfile->path );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
break;
|
||||
}
|
||||
|
||||
Con_Reportf( "HTTP: Starting download %s from %s\n", curfile->path, curfile->server->host );
|
||||
Q_snprintf( name, sizeof( name ), DEFAULT_DOWNLOADED_DIRECTORY "%s.incomplete", curfile->path );
|
||||
|
||||
curfile->file = FS_Open( name, "wb", true );
|
||||
|
||||
if( !curfile->file )
|
||||
{
|
||||
Con_Printf( S_ERROR "HTTP: cannot open %s!\n", name );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
break;
|
||||
}
|
||||
|
||||
curfile->state = HTTP_OPENED;
|
||||
curfile->blocktime = 0;
|
||||
curfile->downloaded = 0;
|
||||
curfile->lastchecksize = 0;
|
||||
curfile->checktime = 0;
|
||||
}
|
||||
|
||||
iActiveCount++;
|
||||
|
||||
if( curfile->state < HTTP_SOCKET ) // Socket is not created
|
||||
{
|
||||
dword mode;
|
||||
|
||||
curfile->socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
|
||||
|
||||
// Now set non-blocking mode
|
||||
// You may skip this if not supported by system,
|
||||
// but download will lock engine, maybe you will need to add manual returns
|
||||
mode = 1;
|
||||
ioctlsocket( curfile->socket, FIONBIO, (void*)&mode );
|
||||
#if XASH_LINUX
|
||||
// SOCK_NONBLOCK is not portable, so use fcntl
|
||||
fcntl( curfile->socket, F_SETFL, fcntl( curfile->socket, F_GETFL, 0 ) | O_NONBLOCK );
|
||||
#endif
|
||||
curfile->state = HTTP_SOCKET;
|
||||
}
|
||||
|
||||
if( curfile->state < HTTP_NS_RESOLVED )
|
||||
{
|
||||
net_gai_state_t res;
|
||||
char hostport[MAX_VA_STRING];
|
||||
|
||||
if( fResolving )
|
||||
continue;
|
||||
|
||||
Q_snprintf( hostport, sizeof( hostport ), "%s:%d", curfile->server->host, curfile->server->port );
|
||||
|
||||
res = NET_StringToSockaddr( hostport, &addr, true, AF_INET );
|
||||
|
||||
if( res == NET_EAI_AGAIN )
|
||||
{
|
||||
fResolving = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( res == NET_EAI_NONAME )
|
||||
{
|
||||
Con_Printf( S_ERROR "failed to resolve server address for %s!\n", curfile->server->host );
|
||||
HTTP_FreeFile( curfile, true ); // Cannot connect
|
||||
break;
|
||||
}
|
||||
curfile->state = HTTP_NS_RESOLVED;
|
||||
}
|
||||
|
||||
if( curfile->state < HTTP_CONNECTED ) // Connection not enstabilished
|
||||
{
|
||||
int res = connect( curfile->socket, (struct sockaddr*)&addr, NET_SockAddrLen( &addr ) );
|
||||
|
||||
if( res )
|
||||
{
|
||||
if( WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK ) // Should give EWOOLDBLOCK if try recv too soon
|
||||
curfile->state = HTTP_CONNECTED;
|
||||
else
|
||||
{
|
||||
Con_Printf( S_ERROR "cannot connect to server: %s\n", NET_ErrorString( ));
|
||||
HTTP_FreeFile( curfile, true ); // Cannot connect
|
||||
break;
|
||||
}
|
||||
continue; // skip to next file
|
||||
}
|
||||
curfile->state = HTTP_CONNECTED;
|
||||
}
|
||||
|
||||
if( curfile->state < HTTP_REQUEST ) // Request not formatted
|
||||
{
|
||||
string useragent;
|
||||
|
||||
if( !COM_CheckStringEmpty( http_useragent.string ) || !Q_strcmp( http_useragent.string, "xash3d" ))
|
||||
{
|
||||
Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)",
|
||||
XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), Q_buildcommit( ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( useragent, http_useragent.string, sizeof( useragent ));
|
||||
}
|
||||
|
||||
curfile->query_length = Q_snprintf( curfile->buf, sizeof( curfile->buf ),
|
||||
"GET %s%s HTTP/1.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
"User-Agent: %s\r\n\r\n", curfile->server->path,
|
||||
curfile->path, curfile->server->host, useragent );
|
||||
curfile->header_size = 0;
|
||||
curfile->bytes_sent = 0;
|
||||
curfile->state = HTTP_REQUEST;
|
||||
}
|
||||
|
||||
if( curfile->state < HTTP_REQUEST_SENT ) // Request not sent
|
||||
{
|
||||
qboolean wait = false;
|
||||
|
||||
while( curfile->bytes_sent < curfile->query_length )
|
||||
{
|
||||
int res = send( curfile->socket, curfile->buf + curfile->bytes_sent, curfile->query_length - curfile->bytes_sent, 0 );
|
||||
|
||||
if( res < 0 )
|
||||
{
|
||||
if( WSAGetLastError() != WSAEWOULDBLOCK && WSAGetLastError() != WSAENOTCONN )
|
||||
{
|
||||
Con_Printf( S_ERROR "failed to send request: %s\n", NET_ErrorString( ));
|
||||
HTTP_FreeFile( curfile, true );
|
||||
wait = true;
|
||||
break;
|
||||
}
|
||||
// blocking while waiting connection
|
||||
// increase counter when blocking
|
||||
curfile->blocktime += host.frametime;
|
||||
wait = true;
|
||||
|
||||
if( curfile->blocktime > http_timeout.value )
|
||||
{
|
||||
Con_Printf( S_ERROR "timeout on request send:\n%s\n", curfile->buf );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
curfile->bytes_sent += res;
|
||||
curfile->blocktime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( wait )
|
||||
continue;
|
||||
|
||||
Con_Reportf( "HTTP: Request sent!\n");
|
||||
memset( curfile->buf, 0, sizeof( curfile->buf ));
|
||||
curfile->state = HTTP_REQUEST_SENT;
|
||||
}
|
||||
|
||||
if( !HTTP_ProcessStream( curfile ))
|
||||
break;
|
||||
|
||||
if( curfile->size > 0 )
|
||||
{
|
||||
flProgress += (float)curfile->downloaded / curfile->size;
|
||||
iProgressCount++;
|
||||
}
|
||||
|
||||
if( curfile->size > 0 && curfile->downloaded >= curfile->size )
|
||||
{
|
||||
HTTP_FreeFile( curfile, false ); // success
|
||||
break;
|
||||
}
|
||||
else if(( WSAGetLastError( ) != WSAEWOULDBLOCK ) && ( WSAGetLastError( ) != WSAEINPROGRESS ))
|
||||
Con_Reportf( "problem downloading %s:\n%s\n", curfile->path, NET_ErrorString( ));
|
||||
else
|
||||
curfile->blocktime += host.frametime;
|
||||
|
||||
if( curfile->blocktime > http_timeout.value )
|
||||
{
|
||||
Con_Printf( S_ERROR "timeout on receiving data!\n");
|
||||
HTTP_FreeFile( curfile, true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update progress
|
||||
if( !Host_IsDedicated() && iProgressCount != 0 )
|
||||
Cvar_SetValue( "scr_download", flProgress/iProgressCount * 100 );
|
||||
|
||||
HTTP_AutoClean();
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
HTTP_AddDownload
|
||||
|
||||
Add new download to end of queue
|
||||
===================
|
||||
*/
|
||||
void HTTP_AddDownload( const char *path, int size, qboolean process )
|
||||
{
|
||||
httpfile_t *httpfile = Z_Calloc( sizeof( httpfile_t ));
|
||||
|
||||
Con_Reportf( "File %s queued to download\n", path );
|
||||
|
||||
httpfile->size = size;
|
||||
httpfile->downloaded = 0;
|
||||
httpfile->socket = -1;
|
||||
Q_strncpy ( httpfile->path, path, sizeof( httpfile->path ));
|
||||
|
||||
if( http.last_file )
|
||||
{
|
||||
// Add next to last download
|
||||
httpfile->id = http.last_file->id + 1;
|
||||
http.last_file->next= httpfile;
|
||||
http.last_file = httpfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// It will be the only download
|
||||
httpfile->id = 0;
|
||||
http.last_file = http.first_file = httpfile;
|
||||
}
|
||||
|
||||
httpfile->file = NULL;
|
||||
httpfile->next = NULL;
|
||||
httpfile->state = HTTP_QUEUE;
|
||||
httpfile->server = http.first_server;
|
||||
httpfile->process = process;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
HTTP_Download_f
|
||||
|
||||
Console wrapper
|
||||
===============
|
||||
*/
|
||||
static void HTTP_Download_f( void )
|
||||
{
|
||||
if( Cmd_Argc() < 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "download <gamedir_path>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
HTTP_AddDownload( Cmd_Argv( 1 ), -1, false );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
HTTP_ParseURL
|
||||
==============
|
||||
*/
|
||||
static httpserver_t *HTTP_ParseURL( const char *url )
|
||||
{
|
||||
httpserver_t *server;
|
||||
int i;
|
||||
|
||||
url = Q_strstr( url, "http://" );
|
||||
|
||||
if( !url )
|
||||
return NULL;
|
||||
|
||||
url += 7;
|
||||
server = Z_Calloc( sizeof( httpserver_t ));
|
||||
i = 0;
|
||||
|
||||
while( *url && ( *url != ':' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' ))
|
||||
{
|
||||
if( i > sizeof( server->host ))
|
||||
return NULL;
|
||||
|
||||
server->host[i++] = *url++;
|
||||
}
|
||||
|
||||
server->host[i] = 0;
|
||||
|
||||
if( *url == ':' )
|
||||
{
|
||||
server->port = Q_atoi( ++url );
|
||||
|
||||
while( *url && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' ))
|
||||
url++;
|
||||
}
|
||||
else
|
||||
server->port = 80;
|
||||
|
||||
i = 0;
|
||||
|
||||
while( *url && ( *url != '\r' ) && ( *url != '\n' ))
|
||||
{
|
||||
if( i > sizeof( server->path ))
|
||||
return NULL;
|
||||
|
||||
server->path[i++] = *url++;
|
||||
}
|
||||
|
||||
server->path[i] = 0;
|
||||
server->next = NULL;
|
||||
server->needfree = false;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
HTTP_AddCustomServer
|
||||
=======================
|
||||
*/
|
||||
void HTTP_AddCustomServer( const char *url )
|
||||
{
|
||||
httpserver_t *server = HTTP_ParseURL( url );
|
||||
|
||||
if( !server )
|
||||
{
|
||||
Con_Printf( S_ERROR "\"%s\" is not valid url!\n", url );
|
||||
return;
|
||||
}
|
||||
|
||||
server->needfree = true;
|
||||
server->next = http.first_server;
|
||||
http.first_server = server;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
HTTP_AddCustomServer_f
|
||||
=======================
|
||||
*/
|
||||
static void HTTP_AddCustomServer_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 2 )
|
||||
{
|
||||
HTTP_AddCustomServer( Cmd_Argv( 1 ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_USAGE "http_addcustomserver <url>\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
HTTP_Clear_f
|
||||
|
||||
Clear all queue
|
||||
============
|
||||
*/
|
||||
static void HTTP_Clear_f( void )
|
||||
{
|
||||
http.last_file = NULL;
|
||||
|
||||
while( http.first_file )
|
||||
{
|
||||
httpfile_t *file = http.first_file;
|
||||
|
||||
http.first_file = http.first_file->next;
|
||||
|
||||
if( file->file )
|
||||
FS_Close( file->file );
|
||||
|
||||
if( file->socket != -1 )
|
||||
closesocket( file->socket );
|
||||
|
||||
Mem_Free( file );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
HTTP_Cancel_f
|
||||
|
||||
Stop current download, skip to next file
|
||||
==============
|
||||
*/
|
||||
static void HTTP_Cancel_f( void )
|
||||
{
|
||||
if( !http.first_file )
|
||||
return;
|
||||
|
||||
http.first_file->state = HTTP_FREE;
|
||||
HTTP_FreeFile( http.first_file, true );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
HTTP_Skip_f
|
||||
|
||||
Stop current download, skip to next server
|
||||
=============
|
||||
*/
|
||||
static void HTTP_Skip_f( void )
|
||||
{
|
||||
if( http.first_file )
|
||||
HTTP_FreeFile( http.first_file, true );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
HTTP_List_f
|
||||
|
||||
Print all pending downloads to console
|
||||
=============
|
||||
*/
|
||||
static void HTTP_List_f( void )
|
||||
{
|
||||
httpfile_t *file = http.first_file;
|
||||
|
||||
while( file )
|
||||
{
|
||||
if ( file->server )
|
||||
Con_Printf ( "\t%d %d http://%s:%d/%s%s %d\n", file->id, file->state,
|
||||
file->server->host, file->server->port, file->server->path,
|
||||
file->path, file->downloaded );
|
||||
else
|
||||
Con_Printf ( "\t%d %d (no server) %s\n", file->id, file->state, file->path );
|
||||
|
||||
file = file->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HTTP_ResetProcessState
|
||||
|
||||
When connected to new server, all old files should not increase counter
|
||||
================
|
||||
*/
|
||||
void HTTP_ResetProcessState( void )
|
||||
{
|
||||
httpfile_t *file = http.first_file;
|
||||
|
||||
while( file )
|
||||
{
|
||||
file->process = false;
|
||||
file = file->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
HTTP_Init
|
||||
=============
|
||||
*/
|
||||
void HTTP_Init( void )
|
||||
{
|
||||
char *serverfile, *line, token[1024];
|
||||
|
||||
http.last_server = NULL;
|
||||
|
||||
http.first_file = http.last_file = NULL;
|
||||
|
||||
Cmd_AddRestrictedCommand( "http_download", HTTP_Download_f, "add file to download queue" );
|
||||
Cmd_AddRestrictedCommand( "http_skip", HTTP_Skip_f, "skip current download server" );
|
||||
Cmd_AddRestrictedCommand( "http_cancel", HTTP_Cancel_f, "cancel current download" );
|
||||
Cmd_AddRestrictedCommand( "http_clear", HTTP_Clear_f, "cancel all downloads" );
|
||||
Cmd_AddRestrictedCommand( "http_list", HTTP_List_f, "list all queued downloads" );
|
||||
Cmd_AddCommand( "http_addcustomserver", HTTP_AddCustomServer_f, "add custom fastdl server");
|
||||
|
||||
Cvar_RegisterVariable( &http_useragent );
|
||||
Cvar_RegisterVariable( &http_autoremove );
|
||||
Cvar_RegisterVariable( &http_timeout );
|
||||
Cvar_RegisterVariable( &http_maxconnections );
|
||||
|
||||
// Read servers from fastdl.txt
|
||||
line = serverfile = (char *)FS_LoadFile( "fastdl.txt", 0, false );
|
||||
|
||||
if( serverfile )
|
||||
{
|
||||
while(( line = COM_ParseFile( line, token, sizeof( token ))))
|
||||
{
|
||||
httpserver_t *server = HTTP_ParseURL( token );
|
||||
|
||||
if( !server )
|
||||
continue;
|
||||
|
||||
if( !http.last_server )
|
||||
http.last_server = http.first_server = server;
|
||||
else
|
||||
{
|
||||
http.last_server->next = server;
|
||||
http.last_server = server;
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Free( serverfile );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
HTTP_Shutdown
|
||||
====================
|
||||
*/
|
||||
void HTTP_Shutdown( void )
|
||||
{
|
||||
HTTP_Clear_f();
|
||||
|
||||
while( http.first_server )
|
||||
{
|
||||
httpserver_t *tmp = http.first_server;
|
||||
|
||||
http.first_server = http.first_server->next;
|
||||
Mem_Free( tmp );
|
||||
}
|
||||
|
||||
http.last_server = NULL;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ void NET_Sleep( int msec );
|
||||
qboolean NET_IsActive( void );
|
||||
qboolean NET_IsConfigured( void );
|
||||
void NET_Config( qboolean net_enable, qboolean changeport );
|
||||
qboolean NET_IsLocalAddress( netadr_t adr );
|
||||
const char *NET_AdrToString( const netadr_t a );
|
||||
const char *NET_BaseAdrToString( const netadr_t a );
|
||||
qboolean NET_IsReservedAdr( netadr_t a );
|
||||
@@ -79,12 +78,17 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 );
|
||||
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr );
|
||||
|
||||
static inline qboolean NET_IsLocalAddress( netadr_t adr )
|
||||
{
|
||||
return adr.type == NA_LOOPBACK ? true : false;
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
int CL_GetSplitSize( void );
|
||||
#endif
|
||||
|
||||
void HTTP_AddCustomServer( const char *url );
|
||||
void HTTP_AddDownload( const char *path, int size, qboolean process );
|
||||
void HTTP_AddDownload( const char *path, int size, qboolean process, resource_t *res );
|
||||
void HTTP_ClearCustomServers( void );
|
||||
void HTTP_Shutdown( void );
|
||||
void HTTP_ResetProcessState( void );
|
||||
|
||||
103
engine/common/net_ws_private.h
Normal file
103
engine/common/net_ws_private.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
net_ws_private.h - networking private definitions
|
||||
Copyright (C) 2024 Alibek Omarov
|
||||
|
||||
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 "net_ws.h"
|
||||
#if XASH_NO_NETWORK
|
||||
#include "platform/stub/net_stub.h"
|
||||
#elif XASH_WIN32
|
||||
#include "platform/win32/net.h"
|
||||
#elif XASH_PSVITA
|
||||
#include "platform/psvita/net_psvita.h"
|
||||
static const struct in6_addr in6addr_any;
|
||||
#else
|
||||
#include "platform/posix/net.h"
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// net_ws.c
|
||||
//
|
||||
static inline const char *NET_ErrorString( void )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
int err = WSAGetLastError();
|
||||
switch( err )
|
||||
{
|
||||
case WSAEINTR: return "WSAEINTR";
|
||||
case WSAEBADF: return "WSAEBADF";
|
||||
case WSAEACCES: return "WSAEACCES";
|
||||
case WSAEFAULT: return "WSAEFAULT";
|
||||
case WSAEINVAL: return "WSAEINVAL";
|
||||
case WSAEMFILE: return "WSAEMFILE";
|
||||
case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
|
||||
case WSAEINPROGRESS: return "WSAEINPROGRESS";
|
||||
case WSAEALREADY: return "WSAEALREADY";
|
||||
case WSAENOTSOCK: return "WSAENOTSOCK";
|
||||
case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
|
||||
case WSAEMSGSIZE: return "WSAEMSGSIZE";
|
||||
case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
|
||||
case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
|
||||
case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
|
||||
case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
|
||||
case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
|
||||
case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
|
||||
case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
|
||||
case WSAEADDRINUSE: return "WSAEADDRINUSE";
|
||||
case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
|
||||
case WSAENETDOWN: return "WSAENETDOWN";
|
||||
case WSAENETUNREACH: return "WSAENETUNREACH";
|
||||
case WSAENETRESET: return "WSAENETRESET";
|
||||
case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
|
||||
case WSAECONNRESET: return "WSAECONNRESET";
|
||||
case WSAENOBUFS: return "WSAENOBUFS";
|
||||
case WSAEISCONN: return "WSAEISCONN";
|
||||
case WSAENOTCONN: return "WSAENOTCONN";
|
||||
case WSAESHUTDOWN: return "WSAESHUTDOWN";
|
||||
case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
|
||||
case WSAETIMEDOUT: return "WSAETIMEDOUT";
|
||||
case WSAECONNREFUSED: return "WSAECONNREFUSED";
|
||||
case WSAELOOP: return "WSAELOOP";
|
||||
case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
|
||||
case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
|
||||
case WSAEDISCON: return "WSAEDISCON";
|
||||
case WSASYSNOTREADY: return "WSASYSNOTREADY";
|
||||
case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
|
||||
case WSANOTINITIALISED: return "WSANOTINITIALISED";
|
||||
case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
|
||||
case WSATRY_AGAIN: return "WSATRY_AGAIN";
|
||||
case WSANO_RECOVERY: return "WSANO_RECOVERY";
|
||||
case WSANO_DATA: return "WSANO_DATA";
|
||||
}
|
||||
|
||||
return "NO ERROR";
|
||||
#else
|
||||
return strerror( errno );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline socklen_t NET_SockAddrLen( const struct sockaddr_storage *addr )
|
||||
{
|
||||
switch ( addr->ss_family )
|
||||
{
|
||||
case AF_INET:
|
||||
return sizeof( struct sockaddr_in );
|
||||
case AF_INET6:
|
||||
return sizeof( struct sockaddr_in6 );
|
||||
default:
|
||||
return sizeof( *addr ); // what the fuck is this?
|
||||
}
|
||||
}
|
||||
|
||||
net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_storage *sadr, qboolean nonblocking, int family );
|
||||
@@ -305,8 +305,8 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
|
||||
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg );
|
||||
void Netchan_CreateFragments( netchan_t *chan, sizebuf_t *msg );
|
||||
int Netchan_CreateFileFragments( netchan_t *chan, const char *filename );
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, const byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, const byte *data );
|
||||
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, const char *format, ... ) _format( 3 );
|
||||
qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg );
|
||||
void Netchan_UpdateProgress( netchan_t *chan );
|
||||
|
||||
@@ -343,12 +343,6 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define clc_goldsrc_requestcvarvalue2 11
|
||||
#define clc_goldsrc_lastmsg 11
|
||||
|
||||
#define S2C_REJECT_BADPASSWORD '8'
|
||||
#define S2C_REJECT '9'
|
||||
#define S2C_CHALLENGE "A00000000"
|
||||
#define S2C_CONNECTION "B"
|
||||
#define A2C_PRINT 'l'
|
||||
|
||||
#define MAX_GOLDSRC_BACKUP_CMDS 8
|
||||
#define MAX_GOLDSRC_TOTAL_CMDS 16
|
||||
#define MAX_GOLDSRC_MODEL_BITS 10
|
||||
@@ -358,4 +352,55 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define MAX_GOLDSRC_EDICTS ( BIT( MAX_ENTITY_BITS ) + ( MAX_CLIENTS * 15 ))
|
||||
#define LAST_GOLDSRC_EDICT ( BIT( MAX_ENTITY_BITS ) - 1 )
|
||||
|
||||
|
||||
// from any to any (must be handled on both server and client)
|
||||
|
||||
#define A2A_PING "ping" // reply with A2A_ACK
|
||||
#define A2A_ACK "ack" // no-op
|
||||
#define A2A_INFO "info" // different format for client and server, see code
|
||||
#define A2A_NETINFO "netinfo" // different format for client and server, see code
|
||||
#define A2A_GOLDSRC_PING "i" // reply with A2A_GOLDSRC_ACK
|
||||
#define A2A_GOLDSRC_ACK "j" // no-op
|
||||
|
||||
// from any to server
|
||||
#define A2S_GOLDSRC_INFO "TSource Engine Query"
|
||||
#define A2S_GOLDSRC_RULES 'V'
|
||||
#define A2S_GOLDSRC_PLAYERS 'U'
|
||||
|
||||
// from server to any
|
||||
#define S2A_GOLDSRC_INFO 'I'
|
||||
#define S2A_GOLDSRC_RULES 'E'
|
||||
#define S2A_GOLDSRC_PLAYERS 'D'
|
||||
|
||||
// from master to server
|
||||
#define M2S_CHALLENGE "s"
|
||||
#define M2S_NAT_CONNECT "c"
|
||||
|
||||
// from server to master
|
||||
#define S2M_INFO "0\n"
|
||||
|
||||
// from client to server
|
||||
#define C2S_BANDWIDTHTEST "bandwidth"
|
||||
#define C2S_GETCHALLENGE "getchallenge"
|
||||
#define C2S_CONNECT "connect"
|
||||
#define C2S_RCON "rcon"
|
||||
|
||||
// from server to client
|
||||
#define S2C_BANDWIDTHTEST "testpacket"
|
||||
#define S2C_CHALLENGE "challenge"
|
||||
#define S2C_CONNECTION "client_connect"
|
||||
#define S2C_ERRORMSG "errormsg"
|
||||
#define S2C_REJECT "disconnect"
|
||||
#define S2C_GOLDSRC_REJECT_BADPASSWORD '8'
|
||||
#define S2C_GOLDSRC_REJECT '9'
|
||||
#define S2C_GOLDSRC_CHALLENGE "A00000000"
|
||||
#define S2C_GOLDSRC_CONNECTION "B"
|
||||
|
||||
// from any to client
|
||||
#define A2C_PRINT "print"
|
||||
#define A2C_GOLDSRC_PRINT 'l'
|
||||
|
||||
// from master to client
|
||||
#define M2A_SERVERSLIST "f"
|
||||
|
||||
#endif//NET_PROTOCOL_H
|
||||
|
||||
@@ -222,6 +222,10 @@ typedef struct ui_extendedfuncs_s {
|
||||
// new mods info
|
||||
gameinfo2_t *(*pfnGetGameInfo)( int gi_version ); // might return NULL if gi_version is unsupported
|
||||
gameinfo2_t *(*pfnGetModInfo)( int gi_version, int mod_index ); // continiously call it until it returns null
|
||||
|
||||
// returns 1 if cvar has read-only flag
|
||||
// or -1 if cvar not found
|
||||
int (*pfnIsCvarReadOnly)( const char *name );
|
||||
} ui_extendedfuncs_t;
|
||||
|
||||
// deprecated export from old engine
|
||||
|
||||
@@ -26,47 +26,56 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined __ANDROID__ && !defined XASH_64BIT
|
||||
#include "build.h"
|
||||
#if XASH_ANDROID && !XASH_64BIT
|
||||
#include <string.h>
|
||||
#include <android/log.h>
|
||||
#include "linker.h"
|
||||
|
||||
static Elf_Sym* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) {
|
||||
Elf_Sym* symtab = si->symtab;
|
||||
const char* strtab = si->strtab;
|
||||
static Elf_Sym *soinfo_elf_lookup( const soinfo *si, unsigned hash, const char *name )
|
||||
{
|
||||
const Elf_Sym *symtab = si->symtab;
|
||||
const char *strtab = si->strtab;
|
||||
unsigned n;
|
||||
|
||||
if( si->nbucket == 0 )
|
||||
return NULL;
|
||||
|
||||
for (unsigned n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]) {
|
||||
Elf_Sym* s = symtab + n;
|
||||
if (strcmp(strtab + s->st_name, name)) continue;
|
||||
for( n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n] )
|
||||
{
|
||||
const Elf_Sym *s = symtab + n;
|
||||
|
||||
/* only concern ourselves with global and weak symbol definitions */
|
||||
switch (ELF_ST_BIND(s->st_info)) {
|
||||
case STB_GLOBAL:
|
||||
case STB_WEAK:
|
||||
if (s->st_shndx == SHN_UNDEF) {
|
||||
continue;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
if( strcmp( strtab + s->st_name, name ))
|
||||
continue;
|
||||
|
||||
return NULL;
|
||||
/* only concern ourselves with global and weak symbol definitions */
|
||||
switch( ELF_ST_BIND( s->st_info ))
|
||||
{
|
||||
case STB_GLOBAL:
|
||||
case STB_WEAK:
|
||||
if( s->st_shndx == SHN_UNDEF )
|
||||
continue;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned elfhash(const char* _name) {
|
||||
const unsigned char* name = (const unsigned char*) _name;
|
||||
unsigned h = 0, g;
|
||||
static unsigned elfhash( const unsigned char *name )
|
||||
{
|
||||
unsigned h = 0;
|
||||
|
||||
while(*name) {
|
||||
h = (h << 4) + *name++;
|
||||
g = h & 0xf0000000;
|
||||
h ^= g;
|
||||
h ^= g >> 24;
|
||||
}
|
||||
return h;
|
||||
while( *name )
|
||||
{
|
||||
unsigned g;
|
||||
|
||||
h = ( h << 4 ) + *name++;
|
||||
g = h & 0xf0000000;
|
||||
h ^= g;
|
||||
h ^= g >> 24;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/* This is used by dlsym(3). It performs symbol lookup only within the
|
||||
@@ -78,21 +87,20 @@ static unsigned elfhash(const char* _name) {
|
||||
Binary Interface) where in Chapter 5 it discuss resolving "Shared
|
||||
Object Dependencies" in breadth first search order.
|
||||
*/
|
||||
static Elf_Sym* dlsym_handle_lookup(soinfo* si, const char* name) {
|
||||
return soinfo_elf_lookup(si, elfhash(name), name);
|
||||
static Elf_Sym *dlsym_handle_lookup( const soinfo *si, const char *name )
|
||||
{
|
||||
return soinfo_elf_lookup( si, elfhash((const unsigned char *)name ), name );
|
||||
}
|
||||
|
||||
extern "C" void* dlsym_weak(void* handle, const char* symbol) {
|
||||
extern "C" void *dlsym_weak( void *handle, const char *symbol )
|
||||
{
|
||||
soinfo *found = (soinfo *)handle;
|
||||
Elf_Sym *sym = dlsym_handle_lookup( found, symbol );
|
||||
|
||||
soinfo* found = NULL;
|
||||
Elf_Sym* sym = NULL;
|
||||
found = reinterpret_cast<soinfo*>(handle);
|
||||
sym = dlsym_handle_lookup(found, symbol);
|
||||
if( sym != NULL )
|
||||
return (void *)( sym->st_value + found->base /*load_bias*/ );
|
||||
|
||||
if (sym != NULL) {
|
||||
return reinterpret_cast<void*>(sym->st_value + found->base/*load_bias*/);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_ERROR, "dlsym-weak", "Failed when looking up %s\n", symbol);
|
||||
return NULL;
|
||||
__android_log_print( ANDROID_LOG_ERROR, "dlsym-weak", "Failed when looking up %s\n", symbol );
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#endif // XASH_ANDROID && !XASH_64BIT
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#ifndef _LINKER_H_
|
||||
#define _LINKER_H_
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -39,163 +38,153 @@
|
||||
|
||||
// a1ba: we don't really need custom linker on Android 64, because
|
||||
// it's only intended to workaround bug which persist on Android < 4.4
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_RelA Elf32_Rela
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Half Elf32_Half
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Note Elf32_Note
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_RelA Elf32_Rela
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Half Elf32_Half
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Note Elf32_Note
|
||||
|
||||
// Returns the address of the page containing address 'x'.
|
||||
#define PAGE_START(x) ((x) & PAGE_MASK)
|
||||
#define PAGE_START( x ) (( x )&PAGE_MASK )
|
||||
|
||||
// Returns the offset of address 'x' in its page.
|
||||
#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
|
||||
#define PAGE_OFFSET( x ) (( x ) & ~PAGE_MASK )
|
||||
|
||||
// Returns the address of the next page after address 'x', unless 'x' is
|
||||
// itself at the start of a page.
|
||||
#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
|
||||
#define PAGE_END( x ) PAGE_START(( x ) + ( PAGE_SIZE - 1 ))
|
||||
|
||||
// Magic shared structures that GDB knows about.
|
||||
|
||||
struct link_map_t {
|
||||
uintptr_t l_addr;
|
||||
char* l_name;
|
||||
uintptr_t l_ld;
|
||||
link_map_t* l_next;
|
||||
link_map_t* l_prev;
|
||||
uintptr_t l_addr;
|
||||
char *l_name;
|
||||
uintptr_t l_ld;
|
||||
link_map_t *l_next;
|
||||
link_map_t *l_prev;
|
||||
};
|
||||
|
||||
// Values for r_debug->state
|
||||
enum {
|
||||
RT_CONSISTENT,
|
||||
RT_ADD,
|
||||
RT_DELETE
|
||||
RT_CONSISTENT,
|
||||
RT_ADD,
|
||||
RT_DELETE
|
||||
};
|
||||
#if 0
|
||||
struct r_debug {
|
||||
int32_t r_version;
|
||||
link_map_t* r_map;
|
||||
void (*r_brk)(void);
|
||||
int32_t r_state;
|
||||
uintptr_t r_ldbase;
|
||||
};
|
||||
#endif
|
||||
#define FLAG_LINKED 0x00000001
|
||||
#define FLAG_EXE 0x00000004 // The main executable
|
||||
#define FLAG_LINKER 0x00000010 // The linker itself
|
||||
#define FLAG_LINKED 0x00000001
|
||||
#define FLAG_EXE 0x00000004 // The main executable
|
||||
#define FLAG_LINKER 0x00000010 // The linker itself
|
||||
|
||||
#define SOINFO_NAME_LEN 128
|
||||
|
||||
typedef void (*linker_function_t)();
|
||||
|
||||
// Android uses REL for 32-bit but only uses RELA for 64-bit.
|
||||
#if defined(__LP64__)
|
||||
#if defined( __LP64__ )
|
||||
#define USE_RELA 1
|
||||
#endif
|
||||
|
||||
struct soinfo {
|
||||
public:
|
||||
char name[SOINFO_NAME_LEN];
|
||||
const Elf_Phdr* phdr;
|
||||
size_t phnum;
|
||||
Elf_Addr entry;
|
||||
Elf_Addr base;
|
||||
unsigned size;
|
||||
public:
|
||||
char name[SOINFO_NAME_LEN];
|
||||
const Elf_Phdr *phdr;
|
||||
size_t phnum;
|
||||
Elf_Addr entry;
|
||||
Elf_Addr base;
|
||||
unsigned size;
|
||||
|
||||
#ifndef __LP64__
|
||||
uint32_t unused1; // DO NOT USE, maintained for compatibility.
|
||||
uint32_t unused1; // DO NOT USE, maintained for compatibility.
|
||||
#endif
|
||||
|
||||
Elf_Dyn* dynamic;
|
||||
Elf_Dyn *dynamic;
|
||||
|
||||
#ifndef __LP64__
|
||||
uint32_t unused2; // DO NOT USE, maintained for compatibility
|
||||
uint32_t unused3; // DO NOT USE, maintained for compatibility
|
||||
uint32_t unused2; // DO NOT USE, maintained for compatibility
|
||||
uint32_t unused3; // DO NOT USE, maintained for compatibility
|
||||
#endif
|
||||
|
||||
soinfo* next;
|
||||
unsigned flags;
|
||||
soinfo *next;
|
||||
unsigned flags;
|
||||
|
||||
const char* strtab;
|
||||
Elf_Sym* symtab;
|
||||
const char *strtab;
|
||||
Elf_Sym *symtab;
|
||||
|
||||
size_t nbucket;
|
||||
size_t nchain;
|
||||
unsigned* bucket;
|
||||
unsigned* chain;
|
||||
size_t nbucket;
|
||||
size_t nchain;
|
||||
unsigned *bucket;
|
||||
unsigned *chain;
|
||||
|
||||
#if !defined(__LP64__)
|
||||
// This is only used by 32-bit MIPS, but needs to be here for
|
||||
// all 32-bit architectures to preserve binary compatibility.
|
||||
unsigned* plt_got;
|
||||
#if !defined( __LP64__ )
|
||||
// This is only used by 32-bit MIPS, but needs to be here for
|
||||
// all 32-bit architectures to preserve binary compatibility.
|
||||
unsigned *plt_got;
|
||||
#endif
|
||||
|
||||
#if defined(USE_RELA)
|
||||
Elf_RelA* plt_rela;
|
||||
size_t plt_rela_count;
|
||||
#if defined( USE_RELA )
|
||||
Elf_RelA *plt_rela;
|
||||
size_t plt_rela_count;
|
||||
|
||||
Elf_RelA* rela;
|
||||
size_t rela_count;
|
||||
Elf_RelA *rela;
|
||||
size_t rela_count;
|
||||
#else
|
||||
Elf_Rel* plt_rel;
|
||||
size_t plt_rel_count;
|
||||
Elf_Rel *plt_rel;
|
||||
size_t plt_rel_count;
|
||||
|
||||
Elf_Rel* rel;
|
||||
size_t rel_count;
|
||||
Elf_Rel *rel;
|
||||
size_t rel_count;
|
||||
#endif
|
||||
|
||||
linker_function_t* preinit_array;
|
||||
size_t preinit_array_count;
|
||||
linker_function_t *preinit_array;
|
||||
size_t preinit_array_count;
|
||||
|
||||
linker_function_t* init_array;
|
||||
size_t init_array_count;
|
||||
linker_function_t* fini_array;
|
||||
size_t fini_array_count;
|
||||
linker_function_t *init_array;
|
||||
size_t init_array_count;
|
||||
linker_function_t *fini_array;
|
||||
size_t fini_array_count;
|
||||
|
||||
linker_function_t init_func;
|
||||
linker_function_t fini_func;
|
||||
linker_function_t init_func;
|
||||
linker_function_t fini_func;
|
||||
|
||||
#if defined(__arm__)
|
||||
// ARM EABI section used for stack unwinding.
|
||||
unsigned* ARM_exidx;
|
||||
size_t ARM_exidx_count;
|
||||
#elif defined(__mips__)
|
||||
unsigned mips_symtabno;
|
||||
unsigned mips_local_gotno;
|
||||
unsigned mips_gotsym;
|
||||
#if defined( __arm__ )
|
||||
// ARM EABI section used for stack unwinding.
|
||||
unsigned *ARM_exidx;
|
||||
size_t ARM_exidx_count;
|
||||
#elif defined( __mips__ )
|
||||
unsigned mips_symtabno;
|
||||
unsigned mips_local_gotno;
|
||||
unsigned mips_gotsym;
|
||||
#endif
|
||||
|
||||
size_t ref_count;
|
||||
link_map_t link_map;
|
||||
size_t ref_count;
|
||||
link_map_t link_map;
|
||||
|
||||
bool constructors_called;
|
||||
bool constructors_called;
|
||||
|
||||
// When you read a virtual address from the ELF file, add this
|
||||
// value to get the corresponding address in the process' address space.
|
||||
Elf_Addr load_bias;
|
||||
// When you read a virtual address from the ELF file, add this
|
||||
// value to get the corresponding address in the process' address space.
|
||||
Elf_Addr load_bias;
|
||||
|
||||
#if !defined(__LP64__)
|
||||
bool has_text_relocations;
|
||||
#if !defined( __LP64__ )
|
||||
bool has_text_relocations;
|
||||
#endif
|
||||
bool has_DT_SYMBOLIC;
|
||||
bool has_DT_SYMBOLIC;
|
||||
|
||||
void CallConstructors();
|
||||
void CallDestructors();
|
||||
void CallPreInitConstructors();
|
||||
void CallConstructors();
|
||||
void CallDestructors();
|
||||
void CallPreInitConstructors();
|
||||
|
||||
private:
|
||||
void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
|
||||
void CallFunction(const char* function_name, linker_function_t function);
|
||||
private:
|
||||
void CallArray( const char *array_name, linker_function_t *functions, size_t count, bool reverse );
|
||||
void CallFunction( const char *function_name, linker_function_t function );
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -674,7 +674,7 @@ static void VID_SetWindowIcon( SDL_Window *hWnd )
|
||||
if( ico && WIN_SetWindowIcon( ico ))
|
||||
return;
|
||||
}
|
||||
#endif // _WIN32 && !XASH_64BIT
|
||||
#endif // XASH_WIN32
|
||||
|
||||
Q_strncpy( iconpath, GI->iconpath, sizeof( iconpath ));
|
||||
COM_ReplaceExtension( iconpath, ".tga", sizeof( iconpath ));
|
||||
|
||||
@@ -61,8 +61,6 @@ GNU General Public License for more details.
|
||||
#define FCONTEXT_CORE_PROFILE BIT( 0 )
|
||||
#define FCONTEXT_DEBUG_ARB BIT( 1 )
|
||||
|
||||
#define FCVAR_READ_ONLY (1<<17) // cannot be set by user at all, and can't be requested by CvarGetPointer from game dlls
|
||||
|
||||
// screenshot types
|
||||
#define VID_SCREENSHOT 0
|
||||
#define VID_LEVELSHOT 1
|
||||
|
||||
@@ -683,6 +683,6 @@ int SV_LightForEntity( edict_t *pEdict );
|
||||
//
|
||||
// sv_query.c
|
||||
//
|
||||
qboolean SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from );
|
||||
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from );
|
||||
|
||||
#endif//SERVER_H
|
||||
|
||||
@@ -131,7 +131,7 @@ static void SV_GetChallenge( netadr_t from )
|
||||
}
|
||||
|
||||
// send it back
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, "challenge %i", svs.challenges[i].challenge );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, S2C_CHALLENGE" %i", svs.challenges[i].challenge );
|
||||
}
|
||||
|
||||
static int SV_GetFragmentSize( void *pcl, fragsize_t mode )
|
||||
@@ -194,9 +194,9 @@ void SV_RejectConnection( netadr_t from, const char *fmt, ... )
|
||||
va_end( argptr );
|
||||
|
||||
Con_Reportf( "%s connection refused. Reason: %s\n", NET_AdrToString( from ), text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "errormsg\n^1Server was reject the connection:^7 %s", text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\n^1Server was reject the connection:^7 %s", text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, S2C_ERRORMSG"\n^1Server was reject the connection:^7 %s", text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2C_PRINT"\n^1Server was reject the connection:^7 %s", text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, S2C_REJECT"\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -456,7 +456,7 @@ static void SV_ConnectClient( netadr_t from )
|
||||
Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", newcl->extensions );
|
||||
|
||||
// send the connect packet to the client
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect %s", protinfo );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, S2C_CONNECTION" %s", protinfo );
|
||||
|
||||
newcl->upstate = us_inactive;
|
||||
newcl->connection_started = host.realtime;
|
||||
@@ -604,7 +604,7 @@ void SV_KickPlayer( sv_client_t *cl, const char *fmt, ... )
|
||||
SV_BroadcastPrintf( cl, "%s was kicked with message: \"%s\"\n", cl->name, buf );
|
||||
SV_ClientPrintf( cl, "You were kicked from the game with message: \"%s\"\n", buf );
|
||||
if( cl->useragent[0] )
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, "errormsg\nKicked with message:\n%s\n", buf );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, S2C_ERRORMSG"\nKicked with message:\n%s\n", buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -612,7 +612,7 @@ void SV_KickPlayer( sv_client_t *cl, const char *fmt, ... )
|
||||
SV_BroadcastPrintf( cl, "%s was kicked\n", cl->name );
|
||||
SV_ClientPrintf( cl, "You were kicked from the game\n" );
|
||||
if( cl->useragent[0] )
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, "errormsg\nYou were kicked from the game\n" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, S2C_ERRORMSG"\nYou were kicked from the game\n" );
|
||||
}
|
||||
|
||||
SV_DropClient( cl, false );
|
||||
@@ -714,20 +714,18 @@ static void SV_BeginRedirect( host_redirect_t *rd, netadr_t adr, rdtype_t target
|
||||
|
||||
static void SV_FlushRedirect( netadr_t adr, int dest, char *buf )
|
||||
{
|
||||
if( sv.current_client && FBitSet( sv.current_client->flags, FCL_FAKECLIENT ))
|
||||
return;
|
||||
|
||||
switch( dest )
|
||||
{
|
||||
case RD_PACKET:
|
||||
Netchan_OutOfBandPrint( NS_SERVER, adr, "print\n%s", buf );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, adr, A2C_PRINT"\n%s", buf );
|
||||
break;
|
||||
case RD_CLIENT:
|
||||
if( !sv.current_client ) return; // client not set
|
||||
if( !sv.current_client || !FBitSet( sv.current_client->flags, FCL_FAKECLIENT ))
|
||||
return; // client not set
|
||||
MSG_BeginServerCmd( &sv.current_client->netchan.message, svc_print );
|
||||
MSG_WriteString( &sv.current_client->netchan.message, buf );
|
||||
break;
|
||||
case RD_NONE:
|
||||
default:
|
||||
Con_Printf( S_ERROR "%s: %s: invalid destination\n", __func__, NET_AdrToString( adr ));
|
||||
break;
|
||||
}
|
||||
@@ -953,14 +951,30 @@ static void SV_Info( netadr_t from, int protocolVersion )
|
||||
if( remaining < 0 )
|
||||
{
|
||||
// should never happen?
|
||||
Con_Printf( S_ERROR "SV_Info: infostring overflow!\n" );
|
||||
Con_Printf( S_ERROR "%s: infostring overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
Q_strncpy( temp, hostname.string, remaining );
|
||||
Info_SetValueForKey( s, "host", temp, sizeof( s ));
|
||||
}
|
||||
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "info\n%s", s );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_INFO"\n%s", s );
|
||||
}
|
||||
|
||||
static void SV_ConnectNatClient( netadr_t from )
|
||||
{
|
||||
netadr_t to;
|
||||
|
||||
if( !sv_nat.value || !NET_IsMasterAdr( from ))
|
||||
return;
|
||||
|
||||
if( !NET_StringToAdr( Cmd_Argv( 1 ), &to ))
|
||||
return;
|
||||
|
||||
if( NET_IsReservedAdr( to ))
|
||||
return;
|
||||
|
||||
SV_Info( to, PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -994,7 +1008,7 @@ static void SV_BuildNetAnswer( netadr_t from )
|
||||
{
|
||||
// send error unsupported protocol
|
||||
Info_SetValueForKey( string, "neterror", "protocol", sizeof( string ));
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "netinfo %i %i %s\n", context, type, string );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_NETINFO" %i %i %s\n", context, type, string );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1065,19 +1079,7 @@ static void SV_BuildNetAnswer( netadr_t from )
|
||||
break;
|
||||
}
|
||||
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "netinfo %i %i %s\n", context, type, string );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_Ping
|
||||
|
||||
Just responds with an acknowledgement
|
||||
================
|
||||
*/
|
||||
static void SV_Ping( netadr_t from )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "ack" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_NETINFO" %i %i %s\n", context, type, string );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1105,10 +1107,7 @@ Redirect all printfs
|
||||
*/
|
||||
void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
static char outputbuf[2048];
|
||||
const char *adr;
|
||||
char remaining[1024];
|
||||
char *p = remaining;
|
||||
int i;
|
||||
|
||||
if( !rcon_enable.value || !COM_CheckStringEmpty( rcon_password.string ))
|
||||
@@ -1121,7 +1120,9 @@ void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
||||
|
||||
if( Rcon_Validate( ))
|
||||
{
|
||||
SV_BeginRedirect( &host.rd, from, RD_PACKET, outputbuf, sizeof( outputbuf ) - 16, SV_FlushRedirect );
|
||||
static char outputbuf[2048];
|
||||
char remaining[1024];
|
||||
char *p = remaining;
|
||||
|
||||
remaining[0] = 0;
|
||||
for( i = 2; i < Cmd_Argc(); i++ )
|
||||
@@ -1130,8 +1131,9 @@ void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
||||
p += Q_strncpy( p, Cmd_Argv( i ), sizeof( remaining ) - ( p - remaining ));
|
||||
p += Q_strncpy( p, "\" ", sizeof( remaining ) - ( p - remaining ));
|
||||
}
|
||||
Cmd_ExecuteString( remaining );
|
||||
|
||||
SV_BeginRedirect( &host.rd, from, RD_PACKET, outputbuf, sizeof( outputbuf ) - 16, SV_FlushRedirect );
|
||||
Cmd_ExecuteString( remaining );
|
||||
SV_EndRedirect( &host.rd );
|
||||
}
|
||||
else Con_Printf( S_ERROR "Bad rcon_password.\n" );
|
||||
@@ -1992,7 +1994,7 @@ static qboolean SV_Noclip_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
return true;
|
||||
|
||||
if( pEntity->v.movetype != MOVETYPE_NOCLIP )
|
||||
@@ -2018,7 +2020,7 @@ static qboolean SV_Godmode_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
return true;
|
||||
|
||||
pEntity->v.flags = pEntity->v.flags ^ FL_GODMODE;
|
||||
@@ -2039,7 +2041,7 @@ static qboolean SV_Notarget_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
return true;
|
||||
|
||||
pEntity->v.flags = pEntity->v.flags ^ FL_NOTARGET;
|
||||
@@ -3148,17 +3150,14 @@ connectionless packets.
|
||||
*/
|
||||
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
char *args;
|
||||
const char *pcmd;
|
||||
char buf[MAX_SYSPATH];
|
||||
int len = sizeof( buf );
|
||||
const char *pcmd, *args;
|
||||
|
||||
// prevent flooding from banned address
|
||||
if( SV_CheckIP( &from ) )
|
||||
if( SV_CheckIP( &from ))
|
||||
return;
|
||||
|
||||
MSG_Clear( msg );
|
||||
MSG_ReadLong( msg );// skip the -1 marker
|
||||
MSG_SeekToBit( msg, sizeof( uint32_t ) << 3, SEEK_CUR ); // skip the -1 marker
|
||||
|
||||
args = MSG_ReadStringLine( msg );
|
||||
Cmd_TokenizeString( args );
|
||||
@@ -3168,29 +3167,79 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
if( sv_log_outofband.value )
|
||||
Con_Reportf( "%s: %s : %s\n", __func__, NET_AdrToString( from ), pcmd );
|
||||
|
||||
if( !Q_strcmp( pcmd, "ping" )) SV_Ping( from );
|
||||
else if( !Q_strcmp( pcmd, "ack" )) SV_Ack( from );
|
||||
else if( !Q_strcmp( pcmd, "info" )) SV_Info( from, Q_atoi( Cmd_Argv( 1 )));
|
||||
else if( !Q_strcmp( pcmd, "bandwidth" )) SV_TestBandWidth( from );
|
||||
else if( !Q_strcmp( pcmd, "getchallenge" )) SV_GetChallenge( from );
|
||||
else if( !Q_strcmp( pcmd, "connect" )) SV_ConnectClient( from );
|
||||
else if( !Q_strcmp( pcmd, "rcon" )) SV_RemoteCommand( from, msg );
|
||||
else if( !Q_strcmp( pcmd, "netinfo" )) SV_BuildNetAnswer( from );
|
||||
else if( !Q_strcmp( pcmd, "s" )) SV_AddToMaster( from, msg );
|
||||
else if( !Q_strcmp( pcmd, "i" )) NET_SendPacket( NS_SERVER, 5, "\xFF\xFF\xFF\xFFj", from ); // A2A_PING
|
||||
else if( SV_SourceQuery_HandleConnnectionlessPacket( pcmd, from )) { } // function handles replies
|
||||
else if( !Q_strcmp( pcmd, "c" ) && sv_nat.value && NET_IsMasterAdr( from ))
|
||||
if( !svs.initialized )
|
||||
{
|
||||
netadr_t to;
|
||||
if( NET_StringToAdr( Cmd_Argv( 1 ), &to ) && !NET_IsReservedAdr( to ))
|
||||
SV_Info( to, PROTOCOL_VERSION );
|
||||
// only process rcon if server not initialized
|
||||
if( !Q_strcmp( pcmd, C2S_RCON ))
|
||||
SV_RemoteCommand( net_from, &net_message );
|
||||
|
||||
return;
|
||||
}
|
||||
else if( svgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
|
||||
if( !Q_strcmp( pcmd, A2S_GOLDSRC_INFO ) || pcmd[0] == A2S_GOLDSRC_PLAYERS || pcmd[0] == A2S_GOLDSRC_RULES )
|
||||
{
|
||||
// user out of band message (must be handled in CL_ConnectionlessPacket)
|
||||
if( len > 0 ) Netchan_OutOfBand( NS_SERVER, from, len, (byte*)buf );
|
||||
SV_SourceQuery_HandleConnnectionlessPacket( pcmd, from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_NETINFO ))
|
||||
{
|
||||
SV_BuildNetAnswer( from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_INFO ))
|
||||
{
|
||||
SV_Info( from, Q_atoi( Cmd_Argv( 1 )));
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, M2S_CHALLENGE ))
|
||||
{
|
||||
SV_AddToMaster( from, msg );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, M2S_NAT_CONNECT ))
|
||||
{
|
||||
SV_ConnectNatClient( from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, C2S_BANDWIDTHTEST ))
|
||||
{
|
||||
SV_TestBandWidth( from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, C2S_GETCHALLENGE ))
|
||||
{
|
||||
SV_GetChallenge( from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, C2S_CONNECT ))
|
||||
{
|
||||
SV_ConnectClient( from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_PING ))
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_ACK );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_GOLDSRC_PING ))
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_GOLDSRC_ACK );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, C2S_RCON ))
|
||||
{
|
||||
SV_RemoteCommand( from, msg );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_ACK ) || !Q_strcmp( pcmd, A2A_GOLDSRC_ACK ))
|
||||
{
|
||||
SV_Ack( from );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[MAX_SYSPATH];
|
||||
int len = sizeof( buf );
|
||||
|
||||
if( svgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
{
|
||||
// user out of band message (must be handled in CL_ConnectionlessPacket)
|
||||
if( len > 0 )
|
||||
Netchan_OutOfBand( NS_SERVER, from, len, (byte*)buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf( S_ERROR "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
|
||||
}
|
||||
}
|
||||
else Con_DPrintf( S_ERROR "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2985,24 +2985,22 @@ static void *GAME_EXPORT pfnPvEntPrivateData( edict_t *pEdict )
|
||||
}
|
||||
|
||||
|
||||
#ifdef XASH_64BIT
|
||||
static struct str64_s
|
||||
{
|
||||
size_t maxstringarray;
|
||||
qboolean allowdup;
|
||||
qboolean dynamic;
|
||||
char *staticstringarray;
|
||||
char *pstringarray;
|
||||
char *pstringarraystatic;
|
||||
char *pstringbase;
|
||||
char *poldstringbase;
|
||||
char *plast;
|
||||
qboolean dynamic;
|
||||
size_t maxalloc;
|
||||
size_t numdups;
|
||||
size_t numoverflows;
|
||||
size_t totalalloc;
|
||||
} str64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
@@ -3013,7 +3011,7 @@ Free strings on server stop. Reset string pointer on 64 bits
|
||||
*/
|
||||
void SV_EmptyStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
if( str64.dynamic ) // switch only after array fill (more space for multiplayer games)
|
||||
str64.pstringbase = str64.pstringarray;
|
||||
else
|
||||
@@ -3021,9 +3019,9 @@ void SV_EmptyStringPool( void )
|
||||
str64.pstringbase = str64.poldstringbase = str64.pstringarraystatic;
|
||||
str64.plast = str64.pstringbase + 1;
|
||||
}
|
||||
#else
|
||||
#else // !XASH_64BIT
|
||||
Mem_EmptyPool( svgame.stringspool );
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3037,7 +3035,7 @@ this helps not to lose strings that belongs to static game part
|
||||
*/
|
||||
void SV_SetStringArrayMode( qboolean dynamic )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
Con_Reportf( "%s(%d) %d\n", __func__, dynamic, str64.dynamic );
|
||||
|
||||
if( dynamic == str64.dynamic )
|
||||
@@ -3046,11 +3044,11 @@ void SV_SetStringArrayMode( qboolean dynamic )
|
||||
str64.dynamic = dynamic;
|
||||
|
||||
SV_EmptyStringPool();
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
#if XASH_AMD64 && XASH_LINUX && !XASH_ANDROID
|
||||
#define USE_MMAP
|
||||
#define USE_MMAP 1
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
@@ -3066,7 +3064,7 @@ this case need patched game dll with MAKE_STRING checking ptrdiff size
|
||||
*/
|
||||
static void SV_AllocStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
void *ptr = NULL;
|
||||
string lenstr;
|
||||
|
||||
@@ -3081,7 +3079,7 @@ static void SV_AllocStringPool( void )
|
||||
if( Sys_CheckParm( "-str64dup" ) )
|
||||
str64.allowdup = true;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#if USE_MMAP
|
||||
{
|
||||
uint flags;
|
||||
size_t pagesize = sysconf( _SC_PAGESIZE );
|
||||
@@ -3135,35 +3133,37 @@ static void SV_AllocStringPool( void )
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else // !USE_MMAP
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
#endif
|
||||
#endif // !USE_MMAP
|
||||
|
||||
str64.pstringarray = ptr;
|
||||
str64.pstringarraystatic = (byte*)ptr + str64.maxstringarray;
|
||||
str64.pstringbase = str64.poldstringbase = ptr;
|
||||
str64.plast = (byte*)ptr + 1;
|
||||
svgame.globals->pStringBase = ptr;
|
||||
#else
|
||||
#else // !XASH_64BIT
|
||||
svgame.stringspool = Mem_AllocPool( "Server Strings" );
|
||||
svgame.globals->pStringBase = "";
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
static void SV_FreeStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#if USE_MMAP
|
||||
if( str64.pstringarray != str64.staticstringarray )
|
||||
munmap( str64.pstringarray, (str64.maxstringarray * 2) & ~(sysconf( _SC_PAGESIZE ) - 1) );
|
||||
else
|
||||
#endif
|
||||
#endif // USE_MMAP
|
||||
{
|
||||
Mem_Free( str64.staticstringarray );
|
||||
#else
|
||||
}
|
||||
#else // !XASH_64BIT
|
||||
Mem_FreePool( &svgame.stringspool );
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3234,9 +3234,7 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
{
|
||||
char *newString = NULL;
|
||||
uint len;
|
||||
#ifdef XASH_64BIT
|
||||
int cmp;
|
||||
#endif
|
||||
|
||||
if( svgame.physFuncs.pfnAllocString != NULL )
|
||||
{
|
||||
@@ -3252,7 +3250,7 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
cmp = 1;
|
||||
|
||||
if( !str64.allowdup )
|
||||
@@ -3290,18 +3288,18 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
str64.maxalloc = newString - str64.pstringarray;
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#else
|
||||
#else // !XASH_64BIT
|
||||
len = SV_ProcessString( NULL, szValue );
|
||||
newString = Mem_Malloc( svgame.stringspool, len );
|
||||
SV_ProcessString( newString, szValue );
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
void SV_PrintStr64Stats_f( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
Con_Printf( "====================\n" );
|
||||
Con_Printf( "64 bit string pool statistics\n" );
|
||||
Con_Printf( "====================\n" );
|
||||
@@ -3310,9 +3308,9 @@ void SV_PrintStr64Stats_f( void )
|
||||
Con_Printf( "maximum array usage: %lu\n", str64.maxalloc );
|
||||
Con_Printf( "overflow counter: %lu\n", str64.numoverflows );
|
||||
Con_Printf( "dup string counter: %lu\n", str64.numdups );
|
||||
#else
|
||||
#else // !XASH_64BIT
|
||||
Con_Printf( "Not implemented\n" );
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3326,7 +3324,7 @@ string_t SV_MakeString( const char *szValue )
|
||||
{
|
||||
if( svgame.physFuncs.pfnMakeString != NULL )
|
||||
return svgame.physFuncs.pfnMakeString( szValue );
|
||||
#ifdef XASH_64BIT
|
||||
#if XASH_64BIT
|
||||
{
|
||||
long long ptrdiff = szValue - svgame.globals->pStringBase;
|
||||
if( ptrdiff > INT_MAX || ptrdiff < INT_MIN )
|
||||
@@ -3334,9 +3332,9 @@ string_t SV_MakeString( const char *szValue )
|
||||
else
|
||||
return (int)ptrdiff;
|
||||
}
|
||||
#else
|
||||
#else // !XASH_64BIT
|
||||
return szValue - svgame.globals->pStringBase;
|
||||
#endif
|
||||
#endif // !XASH_64BIT
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -973,7 +973,7 @@ static void SV_GenerateTestPacket( void )
|
||||
// write packet base data
|
||||
MSG_Init( &svs.testpacket, "BandWidthTest", svs.testpacket_buf, maxsize );
|
||||
MSG_WriteLong( &svs.testpacket, -1 );
|
||||
MSG_WriteString( &svs.testpacket, "testpacket" );
|
||||
MSG_WriteString( &svs.testpacket, S2C_BANDWIDTHTEST );
|
||||
svs.testpacket_crcpos = svs.testpacket.pData + MSG_GetNumBytesWritten( &svs.testpacket );
|
||||
MSG_WriteDword( &svs.testpacket, 0 ); // to be changed by crc
|
||||
|
||||
|
||||
@@ -389,23 +389,7 @@ static void SV_ReadPackets( void )
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
if( MSG_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
|
||||
{
|
||||
if( !svs.initialized )
|
||||
{
|
||||
char *args;
|
||||
const char *c;
|
||||
|
||||
MSG_Clear( &net_message );
|
||||
MSG_ReadLong( &net_message );// skip the -1 marker
|
||||
|
||||
args = MSG_ReadStringLine( &net_message );
|
||||
Cmd_TokenizeString( args );
|
||||
c = Cmd_Argv( 0 );
|
||||
|
||||
if( !Q_strcmp( c, "rcon" ))
|
||||
SV_RemoteCommand( net_from, &net_message );
|
||||
}
|
||||
else SV_ConnectionlessPacket( net_from, &net_message );
|
||||
|
||||
SV_ConnectionlessPacket( net_from, &net_message );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -730,7 +714,7 @@ Master will validate challenge and this server to public list
|
||||
void SV_AddToMaster( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
uint challenge, challenge2, heartbeat_challenge;
|
||||
char s[MAX_INFO_STRING] = "0\n"; // skip 2 bytes of header
|
||||
char s[MAX_INFO_STRING] = S2M_INFO; // skip 2 bytes of header
|
||||
int clients, bots;
|
||||
double last_heartbeat;
|
||||
const int len = sizeof( s );
|
||||
|
||||
@@ -2146,18 +2146,18 @@ qboolean SV_InitPhysicsAPI( void )
|
||||
if( svgame.physFuncs.SV_CheckFeatures != NULL )
|
||||
{
|
||||
// grab common engine features (it will be shared across the network)
|
||||
Host_ValidateEngineFeatures( svgame.physFuncs.SV_CheckFeatures( ));
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, svgame.physFuncs.SV_CheckFeatures( ));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// make sure what physic functions is cleared
|
||||
memset( &svgame.physFuncs, 0, sizeof( svgame.physFuncs ));
|
||||
Host_ValidateEngineFeatures( 0 );
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, 0 );
|
||||
return false; // just tell user about problems
|
||||
}
|
||||
|
||||
// physic interface is missed
|
||||
Host_ValidateEngineFeatures( 0 );
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,15 +16,6 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
|
||||
#define SOURCE_QUERY_DETAILS 'T'
|
||||
#define SOURCE_QUERY_DETAILS_RESPONSE 'I'
|
||||
|
||||
#define SOURCE_QUERY_RULES 'V'
|
||||
#define SOURCE_QUERY_RULES_RESPONSE 'E'
|
||||
|
||||
#define SOURCE_QUERY_PLAYERS 'U'
|
||||
#define SOURCE_QUERY_PLAYERS_RESPONSE 'D'
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_SourceQuery_Details
|
||||
@@ -41,7 +32,8 @@ static void SV_SourceQuery_Details( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQuery", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_DETAILS_RESPONSE );
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_INFO );
|
||||
MSG_WriteByte( &buf, PROTOCOL_VERSION );
|
||||
|
||||
MSG_WriteString( &buf, hostname.string );
|
||||
@@ -69,7 +61,7 @@ static void SV_SourceQuery_Details( netadr_t from )
|
||||
MSG_WriteByte( &buf, GI->secure );
|
||||
MSG_WriteString( &buf, XASH_VERSION );
|
||||
|
||||
Netchan_OutOfBand( NS_SERVER, from, MSG_GetNumBytesWritten( &buf ), MSG_GetData( &buf ));
|
||||
NET_SendPacket( NS_SERVER, MSG_GetNumBytesWritten( &buf ), MSG_GetData( &buf ), from );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -87,7 +79,8 @@ static void SV_SourceQuery_Rules( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQueryRules", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_RULES_RESPONSE );
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_RULES );
|
||||
|
||||
pos = MSG_GetNumBitsWritten( &buf );
|
||||
MSG_WriteShort( &buf, 0 );
|
||||
@@ -117,7 +110,7 @@ static void SV_SourceQuery_Rules( netadr_t from )
|
||||
MSG_SeekToBit( &buf, pos, SEEK_SET );
|
||||
MSG_WriteShort( &buf, cvar_count );
|
||||
|
||||
Netchan_OutOfBand( NS_SERVER, from, total, MSG_GetData( &buf ));
|
||||
NET_SendPacket( NS_SERVER, total, MSG_GetData( &buf ), from );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +132,8 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQueryPlayers", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_PLAYERS_RESPONSE );
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_PLAYERS );
|
||||
|
||||
pos = MSG_GetNumBitsWritten( &buf );
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
@@ -168,7 +162,7 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
MSG_SeekToBit( &buf, pos, SEEK_SET );
|
||||
MSG_WriteByte( &buf, count );
|
||||
|
||||
Netchan_OutOfBand( NS_SERVER, from, total, MSG_GetData( &buf ));
|
||||
NET_SendPacket( NS_SERVER, total, MSG_GetData( &buf ), from );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,24 +171,19 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
SV_SourceQuery_HandleConnnectionlessPacket
|
||||
==================
|
||||
*/
|
||||
qboolean SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from )
|
||||
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from )
|
||||
{
|
||||
switch( c[0] )
|
||||
if( !Q_strcmp( c, A2S_GOLDSRC_INFO ))
|
||||
{
|
||||
case SOURCE_QUERY_DETAILS:
|
||||
SV_SourceQuery_Details( from );
|
||||
return true;
|
||||
|
||||
case SOURCE_QUERY_RULES:
|
||||
SV_SourceQuery_Rules( from );
|
||||
return true;
|
||||
|
||||
case SOURCE_QUERY_PLAYERS:
|
||||
SV_SourceQuery_Players( from );
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
else switch( c[0] )
|
||||
{
|
||||
case A2S_GOLDSRC_RULES:
|
||||
SV_SourceQuery_Rules( from );
|
||||
break;
|
||||
case A2S_GOLDSRC_PLAYERS:
|
||||
SV_SourceQuery_Players( from );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,11 @@ def configure(conf):
|
||||
conf.env.LIB_HAIKU = ['network']
|
||||
conf.env.LIBPATH_HAIKU = ['/boot/system/lib']
|
||||
|
||||
if conf.env.DEST_OS == 'wasi':
|
||||
conf.options.NO_ASYNC_RESOLVE = True
|
||||
conf.env.append_unique('CFLAGS', '-mllvm')
|
||||
conf.env.append_unique('CFLAGS', '-wasm-enable-sjlj')
|
||||
|
||||
if conf.options.STATIC:
|
||||
conf.env.STATIC = True
|
||||
conf.define('XASH_NO_LIBDL',1)
|
||||
@@ -123,7 +128,6 @@ def configure(conf):
|
||||
conf.define_cond('XASH_ENABLE_MAIN', conf.env.DISABLE_LAUNCHER)
|
||||
conf.define_cond('XASH_NO_ASYNC_NS_RESOLVE', conf.options.NO_ASYNC_RESOLVE)
|
||||
conf.define_cond('SUPPORT_BSP2_FORMAT', conf.options.SUPPORT_BSP2_FORMAT)
|
||||
conf.define_cond('XASH_64BIT', conf.env.DEST_SIZEOF_VOID_P != 4)
|
||||
conf.define_cond('DBGHELP', conf.env.DEST_OS == 'win32')
|
||||
conf.define_cond('PSAPI_VERSION', conf.env.DEST_OS == 'win32') # will be defined as 1
|
||||
|
||||
@@ -183,7 +187,6 @@ def build(bld):
|
||||
|
||||
if bld.env.MAGX:
|
||||
libs.append('MAGX')
|
||||
source += bld.path.ant_glob(['platform/magx/*.cpp'])
|
||||
is_cxx_link = True
|
||||
|
||||
if bld.env.DEST_OS == 'android':
|
||||
@@ -227,43 +230,44 @@ def build(bld):
|
||||
'client/*.c',
|
||||
'client/vgui/*.c',
|
||||
'client/avi/*.c'])
|
||||
libs += ['opus', 'bzip2']
|
||||
is_cxx_link = True
|
||||
libs += ['opus', 'bzip2', 'MultiEmulator']
|
||||
|
||||
includes = ['server', 'client', 'client/vgui' ]
|
||||
rpath = bld.env.DEFAULT_RPATH
|
||||
|
||||
# Switch and PSVita have custom parameters
|
||||
if bld.env.DEST_OS in ['nswitch', 'psvita']:
|
||||
bld(source = source,
|
||||
target = 'xash',
|
||||
features = 'c cxxprogram',
|
||||
includes = includes,
|
||||
use = libs,
|
||||
install_path = None,
|
||||
nro_install_path = bld.env.BINDIR,
|
||||
nacp = 'platform/nswitch/xash3d-fwgs.nacp',
|
||||
icon = 'platform/nswitch/icon.jpg',
|
||||
sce_sys = 'platform/psvita/sce_sys',
|
||||
title_id = 'XASH10000',
|
||||
app_name = 'xash3d-fwgs'
|
||||
)
|
||||
else:
|
||||
# always build as shared library on Android
|
||||
if bld.env.DISABLE_LAUNCHER and bld.env.DEST_OS != "android":
|
||||
install_path = bld.env.BINDIR
|
||||
program = 'cxxprogram' if is_cxx_link else 'cprogram'
|
||||
if bld.env.STATIC:
|
||||
program += '_static'
|
||||
features = ['c', program]
|
||||
rpath = None
|
||||
install_path = None
|
||||
features = 'cxx c cxxprogram cprogram'
|
||||
# Always build as shared library on Android
|
||||
elif bld.env.DISABLE_LAUNCHER and bld.env.DEST_OS != 'android':
|
||||
install_path = bld.env.BINDIR
|
||||
if bld.env.STATIC:
|
||||
features = 'cxx c cxxprogram_static cprogram_static'
|
||||
elif is_cxx_link:
|
||||
features = 'cxx c cxxprogram cprogram'
|
||||
else:
|
||||
install_path = bld.env.LIBDIR
|
||||
features = ['c', 'cxxshlib' if is_cxx_link else 'cshlib']
|
||||
features = 'c cprogram'
|
||||
else:
|
||||
install_path = bld.env.LIBDIR
|
||||
if is_cxx_link:
|
||||
features = 'cxx c cxxshlib cshlib'
|
||||
else:
|
||||
features = 'c cshlib'
|
||||
|
||||
bld(source = source,
|
||||
target = 'xash',
|
||||
features = features,
|
||||
includes = includes,
|
||||
use = libs,
|
||||
install_path = install_path,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
rpath = bld.env.DEFAULT_RPATH,
|
||||
)
|
||||
bld(source = source,
|
||||
target = 'xash',
|
||||
features = features,
|
||||
includes = 'server client client/vgui',
|
||||
use = libs,
|
||||
install_path = install_path,
|
||||
nro_install_path = bld.env.BINDIR,
|
||||
nacp = 'platform/nswitch/xash3d-fwgs.nacp',
|
||||
icon = 'platform/nswitch/icon.jpg',
|
||||
sce_sys = 'platform/psvita/sce_sys',
|
||||
title_id = 'XASH10000',
|
||||
app_name = 'xash3d-fwgs',
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
rpath = rpath,
|
||||
)
|
||||
|
||||
1
filesystem/exports.txt
Normal file
1
filesystem/exports.txt
Normal file
@@ -0,0 +1 @@
|
||||
GetFSAPI
|
||||
@@ -25,7 +25,7 @@ def build(bld):
|
||||
libs += [ 'public', 'ANDROID' ]
|
||||
|
||||
bld.shlib(target = 'filesystem_stdio',
|
||||
features = 'cxx seq',
|
||||
features = 'seq',
|
||||
source = bld.path.ant_glob(['*.c', '*.cpp']),
|
||||
use = libs,
|
||||
install_path = bld.env.LIBDIR,
|
||||
|
||||
@@ -30,9 +30,8 @@ def build(bld):
|
||||
if bld.env.DEST_OS == 'linux':
|
||||
bld.env.LDFLAGS += ['-Wl,--no-as-needed', '-lm']
|
||||
|
||||
bld(source = source,
|
||||
bld.program(source = source,
|
||||
target = 'xash3d', # hl.exe
|
||||
features = 'c cxx cxxprogram',
|
||||
use = 'sdk_includes DL USER32 SHELL32 werror',
|
||||
rpath = bld.env.DEFAULT_RPATH,
|
||||
install_path = bld.env.BINDIR,
|
||||
|
||||
@@ -216,6 +216,7 @@ typedef struct playermove_s
|
||||
pmtrace_t (*PM_PlayerTraceEx) (float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ));
|
||||
int (*PM_TestPlayerPositionEx) (float *pos, pmtrace_t *ptrace, int (*pfnIgnore)( physent_t *pe ));
|
||||
struct pmtrace_s *(*PM_TraceLineEx)( float *start, float *end, int flags, int usehulll, int (*pfnIgnore)( physent_t *pe ));
|
||||
struct msurface_s *(*PM_TraceSurface)( int ground, float *vstart, float *vend );
|
||||
|
||||
struct msurface_s *(*PM_TraceSurface)( int ground, float *vstart, float *vend ); // Xash3D-specific
|
||||
} playermove_t;
|
||||
#endif//PM_DEFS_H
|
||||
|
||||
@@ -247,6 +247,10 @@ Then you can use another oneliner to query all variables:
|
||||
#error "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug"
|
||||
#endif
|
||||
|
||||
#if !XASH_64BIT && ( defined( __LP64__ ) || defined( _LP64 ))
|
||||
#define XASH_64BIT 1
|
||||
#endif
|
||||
|
||||
#if XASH_ARM == 8
|
||||
#define XASH_ARMv8 1
|
||||
#elif XASH_ARM == 7
|
||||
|
||||
@@ -53,11 +53,13 @@ size_t Q_colorstr( const char *string )
|
||||
return len;
|
||||
}
|
||||
|
||||
static int Q_atoi_hex( int sign, const char *str )
|
||||
int Q_atoi_hex( int sign, const char *str )
|
||||
{
|
||||
int c, val = 0;
|
||||
|
||||
str += 2;
|
||||
if( str[0] == '0' && ( str[1] == 'x' || str[1] == 'X' ))
|
||||
str += 2;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
c = *str++;
|
||||
|
||||
@@ -68,6 +68,7 @@ const char *Q_buildbranch( void );
|
||||
void Q_strnlwr( const char *in, char *out, size_t size_out );
|
||||
#define Q_strlen( str ) (( str ) ? strlen(( str )) : 0 )
|
||||
size_t Q_colorstr( const char *string );
|
||||
int Q_atoi_hex( int sign, const char *str );
|
||||
int Q_atoi( const char *str );
|
||||
float Q_atof( const char *str );
|
||||
void Q_atov( float *vec, const char *str, size_t siz );
|
||||
|
||||
7833
public/miniz.c
Normal file
7833
public/miniz.c
Normal file
File diff suppressed because it is too large
Load Diff
3367
public/miniz.h
3367
public/miniz.h
File diff suppressed because it is too large
Load Diff
@@ -112,7 +112,6 @@ def build(bld):
|
||||
|
||||
bld.stlib(source = bld.path.ant_glob('*.c'),
|
||||
target = 'public',
|
||||
features = 'c',
|
||||
use = 'sdk_includes werror',
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM)
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
GetRefAPI
|
||||
GetRefHumanReadableName
|
||||
@@ -1,25 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
import os
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
conf.define('REF_DLL', 1)
|
||||
|
||||
def build(bld):
|
||||
source = bld.path.ant_glob( [ '*.c' ] )
|
||||
includes = [ '.' ]
|
||||
libs = [ 'engine_includes', 'sdk_includes', 'werror' ]
|
||||
bld.env.LDFLAGS += ['-fPIC']
|
||||
bld.env.CFLAGS += ['-fPIC']
|
||||
bld.stlib(
|
||||
source = source,
|
||||
target = 'gl2_shim',
|
||||
features = 'c',
|
||||
includes = includes,
|
||||
use = libs,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM
|
||||
)
|
||||
@@ -21,8 +21,6 @@ GNU General Public License for more details.
|
||||
#include "pm_local.h"
|
||||
#include "pmtrace.h"
|
||||
|
||||
extern cvar_t r_shadows;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double time;
|
||||
|
||||
@@ -494,22 +494,10 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
|
||||
gEngfuncs.fsapi->AllowDirectPaths( true );
|
||||
break;
|
||||
case VID_LEVELSHOT:
|
||||
flags |= IMAGE_RESAMPLE;
|
||||
if( gpGlobals->wideScreen )
|
||||
{
|
||||
height = 480;
|
||||
width = 800;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = 480;
|
||||
width = 640;
|
||||
}
|
||||
break;
|
||||
case VID_MINISHOT:
|
||||
flags |= IMAGE_RESAMPLE;
|
||||
height = 200;
|
||||
width = 320;
|
||||
height = shot_type == VID_MINISHOT ? 200 : 480;
|
||||
width = Q_rint( height * ((double)r_shot->width / r_shot->height ));
|
||||
break;
|
||||
case VID_MAPSHOT:
|
||||
flags |= IMAGE_RESAMPLE|IMAGE_QUANTIZE; // GoldSrc request overviews in 8-bit format
|
||||
|
||||
@@ -767,6 +767,7 @@ extern convar_t r_vbo_detail;
|
||||
extern convar_t r_vbo_overbrightmode;
|
||||
extern convar_t r_studio_sort_textures;
|
||||
extern convar_t r_studio_drawelements;
|
||||
extern convar_t r_shadows;
|
||||
extern convar_t r_ripple;
|
||||
extern convar_t r_ripple_updatetime;
|
||||
extern convar_t r_ripple_spawntime;
|
||||
|
||||
@@ -22,17 +22,17 @@ CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelfor
|
||||
CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" );
|
||||
CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
|
||||
CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" );
|
||||
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_ARCHIVE, "enable detail textures support" );
|
||||
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_GLCONFIG, "enable detail textures support" );
|
||||
CVAR_DEFINE_AUTO( r_novis, "0", 0, "ignore vis information (perfomance test)" );
|
||||
CVAR_DEFINE_AUTO( r_nocull, "0", 0, "ignore frustrum culling (perfomance test)" );
|
||||
CVAR_DEFINE_AUTO( r_lockpvs, "0", FCVAR_CHEAT, "lockpvs area at current point (pvs test)" );
|
||||
CVAR_DEFINE_AUTO( r_lockfrustum, "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" );
|
||||
CVAR_DEFINE_AUTO( r_traceglow, "0", FCVAR_GLCONFIG, "cull flares behind models" );
|
||||
CVAR_DEFINE_AUTO( gl_round_down, "2", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "round texture sizes to nearest POT value" );
|
||||
CVAR_DEFINE( r_vbo, "gl_vbo", "0", FCVAR_ARCHIVE, "draw world using VBO (known to be glitchy)" );
|
||||
CVAR_DEFINE( r_vbo_detail, "gl_vbo_detail", "0", FCVAR_ARCHIVE, "detail vbo mode (0: disable, 1: multipass, 2: singlepass, broken decal dlights)" );
|
||||
CVAR_DEFINE( r_vbo_dlightmode, "gl_vbo_dlightmode", "1", FCVAR_ARCHIVE, "vbo dlight rendering mode (0-1)" );
|
||||
CVAR_DEFINE( r_vbo_overbrightmode, "gl_vbo_overbrightmode", "0", FCVAR_ARCHIVE, "vbo overbright rendering mode (0-1)" );
|
||||
CVAR_DEFINE( r_vbo, "gl_vbo", "0", FCVAR_GLCONFIG, "draw world using VBO (known to be glitchy)" );
|
||||
CVAR_DEFINE( r_vbo_detail, "gl_vbo_detail", "0", FCVAR_GLCONFIG, "detail vbo mode (0: disable, 1: multipass, 2: singlepass, broken decal dlights)" );
|
||||
CVAR_DEFINE( r_vbo_dlightmode, "gl_vbo_dlightmode", "1", FCVAR_GLCONFIG, "vbo dlight rendering mode (0-1)" );
|
||||
CVAR_DEFINE( r_vbo_overbrightmode, "gl_vbo_overbrightmode", "0", FCVAR_GLCONFIG, "vbo overbright rendering mode (0-1)" );
|
||||
CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water texture ripple simulation" );
|
||||
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
|
||||
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
|
||||
@@ -1146,10 +1146,6 @@ void GL_InitExtensions( void )
|
||||
gEngfuncs.Cvar_SetValue( "gl_finish", 1 );
|
||||
#endif
|
||||
|
||||
// we do not want to write vbo code that does not use multitexture
|
||||
if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 )
|
||||
gEngfuncs.Cvar_FullSet( "gl_vbo", "0", FCVAR_READ_ONLY );
|
||||
|
||||
R_RenderInfo_f();
|
||||
|
||||
tr.framecount = tr.visframecount = 1;
|
||||
@@ -1191,6 +1187,11 @@ static void GL_InitCommands( void )
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple_updatetime );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple_spawntime );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_shadows );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_dlightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
|
||||
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );
|
||||
@@ -1228,6 +1229,7 @@ register VBO cvars and get default value
|
||||
static void R_CheckVBO( void )
|
||||
{
|
||||
qboolean disable = false;
|
||||
int flags = 0;
|
||||
|
||||
// some bad GLES1 implementations breaks dlights completely
|
||||
if( glConfig.max_texture_units < 3 )
|
||||
@@ -1240,17 +1242,18 @@ static void R_CheckVBO( void )
|
||||
disable = true;
|
||||
#endif
|
||||
|
||||
if( disable )
|
||||
// we do not want to write vbo code that does not use multitexture
|
||||
if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 )
|
||||
{
|
||||
r_vbo.flags = r_vbo_dlightmode.flags = 0;
|
||||
r_vbo.string = "0";
|
||||
r_vbo_dlightmode.string = "0";
|
||||
flags = FCVAR_READ_ONLY;
|
||||
disable = true;
|
||||
}
|
||||
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_dlightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
|
||||
if( disable )
|
||||
{
|
||||
gEngfuncs.Cvar_FullSet( r_vbo.name, "0", flags );
|
||||
gEngfuncs.Cvar_FullSet( r_vbo_dlightmode.name, "0", flags );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1261,6 +1264,7 @@ GL_RemoveCommands
|
||||
static void GL_RemoveCommands( void )
|
||||
{
|
||||
gEngfuncs.Cmd_RemoveCommand( "r_info" );
|
||||
gEngfuncs.Cmd_RemoveCommand( "timerefresh" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -154,8 +154,6 @@ void R_StudioInit( void )
|
||||
|
||||
Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
|
||||
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_shadows );
|
||||
|
||||
g_studio.interpolate = true;
|
||||
g_studio.framecount = 0;
|
||||
m_fDoRemap = false;
|
||||
|
||||
@@ -10,16 +10,9 @@ def configure(conf):
|
||||
conf.define('REF_DLL', 1)
|
||||
|
||||
def build(bld):
|
||||
source = bld.path.ant_glob( [ '*.c' ] )
|
||||
includes = [ '.' ]
|
||||
libs = [ 'engine_includes', 'sdk_includes', 'werror' ]
|
||||
bld.env.LDFLAGS += ['-fPIC']
|
||||
bld.env.CFLAGS_cstlib.remove('-fno-PIC')
|
||||
bld.env.CFLAGS += ['-fPIC']
|
||||
bld.stlib(
|
||||
source = source,
|
||||
target = 'vgl_shim',
|
||||
features = 'c',
|
||||
includes = includes,
|
||||
use = libs,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM
|
||||
)
|
||||
bld.stlib(source = bld.path.ant_glob('*.c'),
|
||||
target = 'vgl_shim',
|
||||
use = 'engine_includes sdk_includes werror',
|
||||
includes = '.')
|
||||
|
||||
@@ -17,10 +17,6 @@ def options(opt):
|
||||
return
|
||||
|
||||
def configure(conf):
|
||||
# check for dedicated server build
|
||||
if conf.options.DEDICATED:
|
||||
return
|
||||
|
||||
conf.define_cond('SUPPORT_BSP2_FORMAT', conf.options.SUPPORT_BSP2_FORMAT)
|
||||
|
||||
conf.env.GL_STATIC = conf.options.GL_STATIC
|
||||
@@ -76,7 +72,6 @@ def build(bld):
|
||||
|
||||
bld.shlib(source = source,
|
||||
target = k,
|
||||
features = 'c',
|
||||
includes = includes,
|
||||
use = libs + v['libs'],
|
||||
defines = v['defines'],
|
||||
|
||||
@@ -12,7 +12,6 @@ def build(bld):
|
||||
bld.shlib(
|
||||
source = 'r_context.c',
|
||||
target = 'ref_null',
|
||||
features = 'c',
|
||||
defines = 'REF_DLL',
|
||||
use = 'engine_includes sdk_includes werror',
|
||||
install_path = bld.env.LIBDIR,
|
||||
|
||||
@@ -906,22 +906,10 @@ qboolean GAME_EXPORT VID_ScreenShot( const char *filename, int shot_type )
|
||||
gEngfuncs.fsapi->AllowDirectPaths( true );
|
||||
break;
|
||||
case VID_LEVELSHOT:
|
||||
flags |= IMAGE_RESAMPLE;
|
||||
if( gpGlobals->wideScreen )
|
||||
{
|
||||
height = 480;
|
||||
width = 800;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = 480;
|
||||
width = 640;
|
||||
}
|
||||
break;
|
||||
case VID_MINISHOT:
|
||||
flags |= IMAGE_RESAMPLE;
|
||||
height = 200;
|
||||
width = 320;
|
||||
height = shot_type == VID_MINISHOT ? 200 : 480;
|
||||
width = Q_rint( height * ((double)r_shot->width / r_shot->height ));
|
||||
break;
|
||||
case VID_MAPSHOT:
|
||||
flags |= IMAGE_RESAMPLE|IMAGE_QUANTIZE; // GoldSrc request overviews in 8-bit format
|
||||
|
||||
@@ -12,14 +12,8 @@ def options(opt):
|
||||
return
|
||||
|
||||
def configure(conf):
|
||||
# check for dedicated server build
|
||||
if conf.options.DEDICATED:
|
||||
return
|
||||
|
||||
if conf.options.SUPPORT_BSP2_FORMAT:
|
||||
conf.env.append_unique('DEFINES', 'SUPPORT_BSP2_FORMAT')
|
||||
|
||||
conf.env.append_unique('DEFINES', 'REF_DLL')
|
||||
conf.define_cond('SUPPORT_BSP2_FORMAT', conf.options.SUPPORT_BSP2_FORMAT)
|
||||
conf.define('REF_DLL', 1)
|
||||
|
||||
def build(bld):
|
||||
libs = [ 'engine_includes', 'werror' ]
|
||||
@@ -29,12 +23,8 @@ def build(bld):
|
||||
else:
|
||||
libs += [ 'public', 'M' ]
|
||||
|
||||
if bld.env.DEDICATED:
|
||||
return
|
||||
|
||||
bld.shlib(source = bld.path.ant_glob(['*.c']),
|
||||
bld.shlib(source = bld.path.ant_glob('*.c'),
|
||||
target = 'ref_soft',
|
||||
features = 'c',
|
||||
includes = '.',
|
||||
use = libs,
|
||||
install_path = bld.env.LIBDIR,
|
||||
|
||||
@@ -45,7 +45,7 @@ popd
|
||||
echo "Building engine..."
|
||||
|
||||
./waf configure -T release --psvita || die_configure
|
||||
./waf build install --destdir=pkgtemp/data/xash3d || die
|
||||
./waf build install --destdir=pkgtemp/data/xash3d -v || die
|
||||
cp build/engine/xash.vpk pkgtemp/
|
||||
|
||||
echo "Building HLSDK..."
|
||||
|
||||
@@ -96,7 +96,7 @@ def apply_static(main, *reloc):
|
||||
for k in ('cshlib', 'cxxshlib'):
|
||||
if k in self.features:
|
||||
self.features.remove(k)
|
||||
self.features.append('xshlib')
|
||||
self.features.insert(0, 'xshlib')
|
||||
in_node = self.path.get_src().make_node('exports.txt')
|
||||
bldnode = self.path.get_bld()
|
||||
bldnode.mkdir()
|
||||
|
||||
@@ -16,9 +16,8 @@ def build(bld):
|
||||
if bld.env.DISABLE_UTILS_MDLDEC:
|
||||
return
|
||||
|
||||
bld(source = bld.path.ant_glob('*.c'),
|
||||
bld.program(source = bld.path.ant_glob('*.c'),
|
||||
target = 'mdldec',
|
||||
features = 'c cprogram',
|
||||
includes = '.',
|
||||
use = 'engine_includes public M werror',
|
||||
install_path = bld.env.BINDIR,
|
||||
|
||||
@@ -19,10 +19,9 @@ def add_runner_target(bld, lib, func):
|
||||
source = bld.path.ant_glob('*.c')
|
||||
includes = '.'
|
||||
|
||||
bld(
|
||||
bld.program(
|
||||
source = source,
|
||||
target = 'run-fuzzer-' + func,
|
||||
features = 'c cprogram',
|
||||
includes = includes,
|
||||
use = 'DL werror',
|
||||
defines = ['FUNC="Fuzz_' + func + '"', 'LIB="' + lib + '"'],
|
||||
|
||||
@@ -9,9 +9,8 @@ def configure(conf):
|
||||
pass
|
||||
|
||||
def build(bld):
|
||||
bld(source = bld.path.ant_glob('*.c'),
|
||||
bld.program(source = bld.path.ant_glob('*.c'),
|
||||
target = 'xar',
|
||||
features = 'c cprogram',
|
||||
includes = '.',
|
||||
use = 'public filesystem_includes werror',
|
||||
rpath = bld.env.DEFAULT_RPATH,
|
||||
|
||||
19
wscript
19
wscript
@@ -67,7 +67,6 @@ SUBDIRS = [
|
||||
# always configured and built
|
||||
Subproject('public'),
|
||||
Subproject('filesystem'),
|
||||
Subproject('engine'),
|
||||
Subproject('stub/server'),
|
||||
Subproject('dllemu'),
|
||||
|
||||
@@ -82,9 +81,11 @@ SUBDIRS = [
|
||||
Subproject('3rdparty/bzip2', lambda x: not x.env.DEDICATED and not x.env.HAVE_SYSTEM_BZ2),
|
||||
Subproject('3rdparty/mainui', lambda x: not x.env.DEDICATED),
|
||||
Subproject('3rdparty/vgui_support', lambda x: not x.env.DEDICATED),
|
||||
Subproject('3rdparty/MultiEmulator',lambda x: not x.env.DEDICATED),
|
||||
# Subproject('3rdparty/freevgui', lambda x: not x.env.DEDICATED),
|
||||
Subproject('stub/client', lambda x: not x.env.DEDICATED),
|
||||
Subproject('game_launch', lambda x: not x.env.DISABLE_LAUNCHER),
|
||||
Subproject('engine'), # keep latest for static linking
|
||||
|
||||
# disable only by external dependency presense
|
||||
Subproject('3rdparty/opus', lambda x: not x.env.HAVE_SYSTEM_OPUS and not x.env.DEDICATED),
|
||||
@@ -96,7 +97,6 @@ SUBDIRS = [
|
||||
|
||||
# enabled on PSVita only
|
||||
Subproject('ref/gl/vgl_shim', lambda x: x.env.DEST_OS == 'psvita'),
|
||||
|
||||
]
|
||||
|
||||
REFDLLS = [
|
||||
@@ -197,10 +197,10 @@ def configure(conf):
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.load('msvc_pdb')
|
||||
|
||||
conf.load('msvs msdev subproject clang_compilation_database strip_on_install waf_unit_test enforce_pic cmake')
|
||||
conf.load('msvs msdev subproject clang_compilation_database strip_on_install waf_unit_test enforce_pic cmake force_32bit')
|
||||
|
||||
# Force XP compatibility, all build targets should add subsystem=bld.env.MSVC_SUBSYSTEM
|
||||
if conf.env.MSVC_TARGETS[0] == 'x86':
|
||||
if conf.env.MSVC_TARGETS[0] == 'amd64_x86' or conf.env.MSVC_TARGETS[0] == 'x86':
|
||||
conf.env.MSVC_SUBSYSTEM = 'WINDOWS,5.01'
|
||||
conf.env.CONSOLE_SUBSYSTEM = 'CONSOLE,5.01'
|
||||
else:
|
||||
@@ -249,14 +249,13 @@ def configure(conf):
|
||||
# There is now `-4` (or `--32bits`) configure flag for those
|
||||
# who want to specifically build engine for 32-bit
|
||||
if conf.env.DEST_OS in ['win32', 'linux'] and conf.env.DEST_CPU == 'x86_64':
|
||||
conf.env.BIT32_MANDATORY = not conf.options.ALLOW64
|
||||
force_32bit = not conf.options.ALLOW64
|
||||
else:
|
||||
conf.env.BIT32_MANDATORY = conf.options.FORCE32
|
||||
force_32bit = conf.options.FORCE32
|
||||
|
||||
if conf.env.BIT32_MANDATORY:
|
||||
if force_32bit:
|
||||
Logs.info('WARNING: will build engine for 32-bit target')
|
||||
|
||||
conf.load('force_32bit')
|
||||
conf.force_32bit(True)
|
||||
|
||||
cflags, linkflags = conf.get_optimization_flags()
|
||||
cxxflags = list(cflags) # optimization flags are common between C and C++ but we need a copy
|
||||
@@ -379,7 +378,7 @@ def configure(conf):
|
||||
conf.env.SUPPORT_BSP2_FORMAT = conf.options.SUPPORT_BSP2_FORMAT
|
||||
|
||||
# disable game_launch compiling on platform where it's not needed
|
||||
conf.env.DISABLE_LAUNCHER = conf.env.DEST_OS in ['android', 'nswitch', 'psvita', 'dos'] or conf.env.MAGX or conf.env.DEDICATED
|
||||
conf.env.DISABLE_LAUNCHER = conf.env.DEST_OS in ['android', 'nswitch', 'psvita', 'dos'] or conf.env.MAGX or conf.env.DEDICATED or conf.env.STATIC_LINKING
|
||||
|
||||
if conf.env.SAILFISH == 'aurora':
|
||||
conf.env.DEFAULT_RPATH = '/usr/share/su.xash.Engine/lib'
|
||||
|
||||
Reference in New Issue
Block a user