mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
Compare commits
2 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68f1a8bdc2 | ||
|
|
da1669ddf7 |
@@ -5,7 +5,6 @@ packages:
|
||||
- freetype-dev
|
||||
- fontconfig-dev
|
||||
- opus-dev
|
||||
- bzip2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -7,7 +7,6 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- print/freetype2
|
||||
- x11-fonts/fontconfig
|
||||
- audio/opus
|
||||
- archivers/bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- fontconfig
|
||||
- libopus
|
||||
- pkgconf
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -3,7 +3,6 @@ packages:
|
||||
- python3
|
||||
- sdl2
|
||||
- opus
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -342,6 +342,3 @@ enc_temp_folder/
|
||||
|
||||
# KDevelop4
|
||||
*.kdev4
|
||||
|
||||
# ccls langauge server
|
||||
.ccls-*
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -19,9 +19,3 @@
|
||||
[submodule "3rdparty/xash-extras"]
|
||||
path = 3rdparty/extras/xash-extras
|
||||
url = https://github.com/FWGS/xash-extras
|
||||
[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
1
3rdparty/MultiEmulator
vendored
Submodule 3rdparty/MultiEmulator deleted from 2f3c3a40cd
1
3rdparty/bzip2/bz_version.h
vendored
1
3rdparty/bzip2/bz_version.h
vendored
@@ -1 +0,0 @@
|
||||
#define BZ_VERSION "1.1.0-fwgs"
|
||||
1
3rdparty/bzip2/bzip2
vendored
1
3rdparty/bzip2/bzip2
vendored
Submodule 3rdparty/bzip2/bzip2 deleted from 66c46b8c94
34
3rdparty/bzip2/wscript
vendored
34
3rdparty/bzip2/wscript
vendored
@@ -1,34 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
conf.define('_GNU_SOURCE', 1)
|
||||
conf.define('BZ_NO_STDIO', 1)
|
||||
|
||||
if conf.env.DEST_OS == 'win32':
|
||||
conf.define('BZ_LCCWIN32', 1)
|
||||
else:
|
||||
conf.define('BZ_UNIX', 1)
|
||||
|
||||
def build(bld):
|
||||
# doesn't work with CMake generator
|
||||
# bld(
|
||||
# features = 'subst',
|
||||
# source = 'bzip2/bz_version.h.in',
|
||||
# target = 'bz_version.h',
|
||||
# BZ_VERSION='1.1.0-fwgs'
|
||||
# )
|
||||
|
||||
bz_sources = ['bzip2/blocksort.c', 'bzip2/huffman.c', 'bzip2/crctable.c', 'bzip2/randtable.c', 'bzip2/compress.c', 'bzip2/decompress.c', 'bzip2/bzlib.c']
|
||||
|
||||
bld.stlib(
|
||||
source = bz_sources,
|
||||
target = 'bzip2',
|
||||
# use = 'bz_version.h',
|
||||
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: 9050d05a7b...f4ff263d42
2
3rdparty/gl-wes-v2
vendored
2
3rdparty/gl-wes-v2
vendored
Submodule 3rdparty/gl-wes-v2 updated: d4ed038d13...2d9b5afe10
1
3rdparty/gl4es/wscript
vendored
1
3rdparty/gl4es/wscript
vendored
@@ -16,6 +16,7 @@ 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: 0bb921ea8d...b7edbaf2de
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: 6c0f341b7b...e75792de03
2
3rdparty/opus/opus
vendored
2
3rdparty/opus/opus
vendored
Submodule 3rdparty/opus/opus updated: 82ac57d9f1...8cf872a186
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.4.0"', 'CUSTOM_MODES']
|
||||
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.3.1"', 'CUSTOM_MODES']
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
|
||||
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: e0ab95229d...7276993f3f
@@ -1,14 +0,0 @@
|
||||
# Support for GoldSrc network protocol
|
||||
This feature is still work-in-progress, but for now it's available for all users, and we appreciate any bug-reports and contributions around it.
|
||||
|
||||
For connecting to GoldSrc-based servers, use this command:
|
||||
```
|
||||
connect ip:port gs
|
||||
```
|
||||
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should accept HLTV connections.
|
||||
Without this requirement, you will just get "Steam validation rejected" error on connecting.
|
||||
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
In case of ReHLDS with Reunion plugin, by default it rejects HLTV clients. But connections from HLTV can be easily enabled in `reunion.cfg` file.
|
||||
62
README.md
62
README.md
@@ -11,12 +11,12 @@ Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://ww
|
||||
If you like Xash3D FWGS, consider supporting individual engine maintainers. By supporting us, you help to continue developing this game engine further. The sponsorship links are available in [documentation](Documentation/donate.md).
|
||||
|
||||
## Fork features
|
||||
* Steam Half-Life (HLSDK 2.5) support.
|
||||
* Steam Half-Life (HLSDK 2.4) support.
|
||||
* Crossplatform and modern compilers support: supports Windows, Linux, BSD & Android on x86 & ARM and [many more](Documentation/ports.md).
|
||||
* Better multiplayer: multiple master servers, headless dedicated server, voice chat, [GoldSrc protocol support](Documentation/goldsrc-protocol-support.md) and IPv6 support.
|
||||
* Better multiplayer support: multiple master servers, headless dedicated server, voice chat and IPv6 support.
|
||||
* Multiple renderers support: OpenGL, GLESv1, GLESv2 and Software.
|
||||
* Advanced virtual filesystem: `.pk3` and `.pk3dir` support, compatibility with GoldSrc FS module, fast case-insensitivity emulation for crossplatform.
|
||||
* Mobility API: better game integration on mobile devices (vibration, touch controls).
|
||||
* Mobility API: better game integration on mobile devices (vibration, touch controls)
|
||||
* Different input methods: touch and gamepad in addition to mouse & keyboard.
|
||||
* TrueType font rendering, as a part of mainui_cpp.
|
||||
* External VGUI support module.
|
||||
@@ -35,16 +35,17 @@ You still needed to copy `valve` directory as all game resources located there.
|
||||
For additional info, run Xash3D with `-help` command line key.
|
||||
|
||||
## Contributing
|
||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html.
|
||||
* Issues are accepted in both English and Russian.
|
||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html
|
||||
* Issues are accepted in both English and Russian
|
||||
* Before sending a PR, check if you followed our contribution guide in CONTRIBUTING.md file.
|
||||
|
||||
## Build instructions
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read https://waf.io/book/
|
||||
|
||||
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If your CPU is x86 compatible and you're on Windows or Linux, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
|
||||
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
|
||||
|
||||
@@ -61,40 +62,31 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
|
||||
#### GNU/Linux
|
||||
##### Debian/Ubuntu
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Enable i386 on your system: `$ sudo dpkg --add-architecture 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`.
|
||||
* Enable i386 on your system, if you're compiling 32-bit engine on amd64. If not, skip this
|
||||
|
||||
* 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
|
||||
* 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 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`.
|
||||
`$ sudo dpkg --add-architecture i386`
|
||||
* Install development tools
|
||||
* For 32-bit engine on amd64: \
|
||||
`$ sudo apt install build-essential gcc-multilib g++-multilib python libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype6-dev:i386`
|
||||
* For everything else: \
|
||||
`$ sudo apt install build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev`
|
||||
* Clone this repostory:
|
||||
`$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`
|
||||
|
||||
### Building
|
||||
#### Windows (Visual Studio)
|
||||
0) Open command line.
|
||||
0) Open command line
|
||||
1) Navigate to `xash3d-fwgs` directory.
|
||||
2) (optional) Examine which build options are available: `waf --help`.
|
||||
3) Configure build: `waf configure --sdl2=c:/path/to/SDL2`.
|
||||
4) Compile: `waf build`.
|
||||
5) Install: `waf install --destdir=c:/path/to/any/output/directory`.
|
||||
2) Carefully examine which build options are available: `waf --help`
|
||||
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2`
|
||||
4) Compile: `waf build`
|
||||
5) Install: `waf install --destdir=c:/path/to/any/output/directory`
|
||||
|
||||
#### Linux
|
||||
If compiling 32-bit on amd64, make sure `PKG_CONFIG_PATH` from the previous step is set correctly, prior to running configure.
|
||||
If compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
|
||||
|
||||
0) (optional) Examine which build options are available: `./waf --help`.
|
||||
1) Configure build: `./waf configure` (you need to pass `-8` to compile 64-bit engine on 64-bit x86 processor).
|
||||
2) Compile: `./waf build`.
|
||||
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
||||
0) Examine which build options are available: `./waf --help`
|
||||
1) Configure build: `./waf configure -T release`
|
||||
(You need to pass `-8` to compile 64-bit engine on 64-bit x86 processor)
|
||||
2) Compile: `./waf build`
|
||||
3) Install(optional): `./waf install --destdir=/path/to/any/output/directory`
|
||||
|
||||
@@ -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", s_musicvolume.value );
|
||||
Con_Printf( "Volume is %f\n", Cvar_VariableValue( "MP3Volume" ));
|
||||
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_allowdownload is 0\n" );
|
||||
Con_Reportf( "Download refused, cl_allow_download 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, pResource );
|
||||
HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -40,8 +40,6 @@ GNU General Public License for more details.
|
||||
#define IDEMOHEADER (('M'<<24)+('E'<<16)+('D'<<8)+'I') // little-endian "IDEM"
|
||||
#define DEMO_PROTOCOL 3
|
||||
|
||||
#define PROTOCOL_GOLDSRC_VERSION_DEMO (PROTOCOL_GOLDSRC_VERSION | (BIT( 7 ))) // should be 48, only to differentiate it from PROTOCOL_LEGACY_VERSION
|
||||
|
||||
const char *demo_cmd[dem_lastcmd+1] =
|
||||
{
|
||||
"dem_unknown",
|
||||
@@ -122,7 +120,7 @@ static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
||||
case PROTO_QUAKE:
|
||||
return PROTOCOL_VERSION_QUAKE;
|
||||
case PROTO_GOLDSRC:
|
||||
return PROTOCOL_GOLDSRC_VERSION_DEMO;
|
||||
return PROTOCOL_GOLDSRC_VERSION;
|
||||
}
|
||||
|
||||
return PROTOCOL_VERSION;
|
||||
@@ -138,7 +136,7 @@ static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
||||
return PROTO_LEGACY;
|
||||
case PROTOCOL_VERSION_QUAKE:
|
||||
return PROTO_QUAKE;
|
||||
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
||||
case PROTOCOL_GOLDSRC_VERSION:
|
||||
return PROTO_GOLDSRC;
|
||||
}
|
||||
|
||||
@@ -285,7 +283,7 @@ void CL_WriteDemoUserCmd( int cmdnumber )
|
||||
|
||||
// write usercmd_t
|
||||
MSG_Init( &buf, "UserCmd", data, sizeof( data ));
|
||||
CL_WriteUsercmd( PROTO_CURRENT, &buf, -1, cmdnumber ); // always no delta, always in current protocol
|
||||
CL_WriteUsercmd( &buf, -1, cmdnumber ); // always no delta
|
||||
|
||||
bytes = MSG_GetNumBytesWritten( &buf );
|
||||
|
||||
@@ -708,7 +706,7 @@ static void CL_DemoStartPlayback( int mode )
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
CL_SetupNetchanForProtocol( cls.legacymode );
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
@@ -1470,7 +1468,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 && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_LEGACY_VERSION )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: net protocol outdated (%i should be %i or %i)\n",
|
||||
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_LEGACY_VERSION );
|
||||
|
||||
@@ -25,16 +25,13 @@ static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
|
||||
static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
|
||||
static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
|
||||
|
||||
static particle_t *cl_active_particles;
|
||||
static particle_t *cl_active_tracers;
|
||||
static particle_t *cl_free_particles;
|
||||
static particle_t *cl_particles = NULL; // particle pool
|
||||
particle_t *cl_active_particles;
|
||||
particle_t *cl_active_tracers;
|
||||
particle_t *cl_free_particles;
|
||||
particle_t *cl_particles = NULL; // particle pool
|
||||
static vec3_t cl_avelocities[NUMVERTEXNORMALS];
|
||||
static float cl_lasttimewarn = 0.0f;
|
||||
|
||||
// expand debugging BBOX particle hulls by this many units.
|
||||
#define BOX_GAP 0.0f
|
||||
|
||||
/*
|
||||
================
|
||||
R_LookupColor
|
||||
@@ -265,9 +262,9 @@ VIEWBEAMS MANAGEMENT
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
static BEAM *cl_active_beams;
|
||||
static BEAM *cl_free_beams;
|
||||
static BEAM *cl_viewbeams = NULL; // beams pool
|
||||
BEAM *cl_active_beams;
|
||||
BEAM *cl_free_beams;
|
||||
BEAM *cl_viewbeams = NULL; // beams pool
|
||||
|
||||
|
||||
/*
|
||||
@@ -1604,73 +1601,6 @@ void GAME_EXPORT R_RocketTrail( vec3_t start, vec3_t end, int type )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_ParticleLine
|
||||
|
||||
draw line from particles
|
||||
================
|
||||
*/
|
||||
static void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel )
|
||||
{
|
||||
float len, curdist;
|
||||
vec3_t diff, pos;
|
||||
|
||||
// determine distance
|
||||
VectorSubtract( end, start, diff );
|
||||
len = VectorNormalizeLength( diff );
|
||||
curdist = 0;
|
||||
|
||||
while( curdist <= len )
|
||||
{
|
||||
VectorMA( start, curdist, diff, pos );
|
||||
CL_Particle( pos, pcolor, life, 0, zvel );
|
||||
curdist += 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawRectangle
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawRectangle( const vec3_t tl, const vec3_t bl, const vec3_t tr, const vec3_t br, int pcolor, float life )
|
||||
{
|
||||
PM_ParticleLine( tl, bl, pcolor, life, 0 );
|
||||
PM_ParticleLine( bl, br, pcolor, life, 0 );
|
||||
PM_ParticleLine( br, tr, pcolor, life, 0 );
|
||||
PM_ParticleLine( tr, tl, pcolor, life, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawBBox
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life )
|
||||
{
|
||||
vec3_t p[8], tmp;
|
||||
float gap = BOX_GAP;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
tmp[0] = (i & 1) ? mins[0] - gap : maxs[0] + gap;
|
||||
tmp[1] = (i & 2) ? mins[1] - gap : maxs[1] + gap ;
|
||||
tmp[2] = (i & 4) ? mins[2] - gap : maxs[2] + gap ;
|
||||
|
||||
VectorAdd( tmp, origin, tmp );
|
||||
VectorCopy( tmp, p[i] );
|
||||
}
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_ParticleLine
|
||||
@@ -1834,6 +1764,25 @@ void GAME_EXPORT R_StreakSplash( const vec3_t pos, const vec3_t dir, int color,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DebugParticle
|
||||
|
||||
just for debug purposes
|
||||
===============
|
||||
*/
|
||||
void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b )
|
||||
{
|
||||
particle_t *p;
|
||||
|
||||
p = R_AllocParticle( NULL );
|
||||
if( !p ) return;
|
||||
|
||||
VectorCopy( pos, p->org );
|
||||
p->color = R_LookupColor( r, g, b );
|
||||
p->die = cl.time + 0.01f;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_Particle
|
||||
|
||||
@@ -380,7 +380,7 @@ CL_ParseReliableEvent
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg )
|
||||
{
|
||||
int event_index;
|
||||
event_args_t nullargs, args;
|
||||
@@ -390,19 +390,11 @@ void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
event_index = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
|
||||
// reliable events not use delta-compression just null-compression
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
Delta_ReadGSFields( msg, DT_EVENT_T, &nullargs, &args, 0.0f );
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
@@ -417,43 +409,34 @@ CL_ParseEvent
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
void CL_ParseEvent( sizebuf_t *msg )
|
||||
{
|
||||
int event_index;
|
||||
int i, num_events;
|
||||
int packet_index;
|
||||
const event_args_t nullargs = { 0 };
|
||||
event_args_t args = { 0 };
|
||||
event_args_t nullargs, args;
|
||||
entity_state_t *state;
|
||||
float delay;
|
||||
int entity_bits;
|
||||
|
||||
memset( &nullargs, 0, sizeof( nullargs ));
|
||||
memset( &args, 0, sizeof( args ));
|
||||
|
||||
num_events = MSG_ReadUBitLong( msg, 5 );
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
||||
else if( proto == PROTO_LEGACY )
|
||||
entity_bits = MAX_LEGACY_ENTITY_BITS;
|
||||
else entity_bits = MAX_ENTITY_BITS;
|
||||
|
||||
// parse events queue
|
||||
for( i = 0 ; i < num_events; i++ )
|
||||
{
|
||||
event_index = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
packet_index = MSG_ReadUBitLong( msg, entity_bits );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Delta_ReadGSFields( msg, DT_EVENT_T, &nullargs, &args, 0.0f );
|
||||
else MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
}
|
||||
packet_index = MSG_ReadUBitLong( msg, cls.legacymode ? MAX_LEGACY_ENTITY_BITS : MAX_ENTITY_BITS );
|
||||
else packet_index = -1;
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
else delay = 0.0f;
|
||||
|
||||
@@ -174,7 +174,7 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
case MOVETYPE_TOSS:
|
||||
if( cls.legacymode == PROTO_LEGACY && e->model && e->model->type == mod_studio )
|
||||
if( cls.legacymode && e->model && e->model->type == mod_studio )
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -669,9 +669,9 @@ FRAME PARSING
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum )
|
||||
{
|
||||
if( proto == PROTO_LEGACY )
|
||||
if( cls.legacymode )
|
||||
{
|
||||
*newnum = MSG_ReadWord( msg );
|
||||
if( *newnum == 0 )
|
||||
@@ -694,7 +694,7 @@ CL_FlushEntityPacket
|
||||
Read and ignore whole entity packet.
|
||||
=================
|
||||
*/
|
||||
static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
static void CL_FlushEntityPacket( sizebuf_t *msg )
|
||||
{
|
||||
int newnum;
|
||||
entity_state_t from, to;
|
||||
@@ -707,7 +707,7 @@ static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
// read it all, but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum, proto ))
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
@@ -717,47 +717,6 @@ static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CL_ValidateDeltaPacket( uint oldpacket, frame_t *oldframe )
|
||||
{
|
||||
int subtracted = ( cls.netchan.incoming_sequence - oldpacket ) & 0xFF;
|
||||
|
||||
if( subtracted == 0 )
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 update too old\n^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( subtracted >= CL_UPDATE_MASK )
|
||||
{
|
||||
// we can't use this, it is too old
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(( cls.next_client_entities - oldframe->first_entity ) > ( cls.num_client_entities - NUM_PACKET_ENTITIES ))
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CL_UpdateOldEntNum( int oldindex, frame_t *oldframe, entity_state_t **oldent )
|
||||
{
|
||||
if( !oldframe )
|
||||
{
|
||||
*oldent = NULL;
|
||||
return MAX_ENTNUMBER;
|
||||
}
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
return MAX_ENTNUMBER;
|
||||
|
||||
*oldent = &cls.packet_entities[(oldframe->first_entity + oldindex) % cls.num_client_entities];
|
||||
return (*oldent)->number;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DeltaEntity
|
||||
@@ -828,7 +787,7 @@ An svc_packetentities has just been parsed, deal with the
|
||||
rest of the data stream.
|
||||
==================
|
||||
*/
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto )
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *newframe, *oldframe;
|
||||
int oldindex, newnum, oldnum;
|
||||
@@ -844,7 +803,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
CL_WriteDemoJumpTime();
|
||||
|
||||
// sentinel count. save it for debug checking
|
||||
if( proto == PROTO_LEGACY )
|
||||
if( cls.legacymode )
|
||||
count = MSG_ReadWord( msg );
|
||||
else count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||
|
||||
@@ -858,12 +817,32 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
|
||||
if( delta )
|
||||
{
|
||||
uint oldpacket = MSG_ReadByte( msg );
|
||||
int subtracted;
|
||||
|
||||
oldpacket = MSG_ReadByte( msg );
|
||||
subtracted = ( cls.netchan.incoming_sequence - oldpacket ) & 0xFF;
|
||||
|
||||
if( subtracted == 0 )
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 update too old\n^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
if( subtracted >= CL_UPDATE_MASK )
|
||||
{
|
||||
// we can't use this, it is too old
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
oldframe = &cl.frames[oldpacket & CL_UPDATE_MASK];
|
||||
|
||||
if( !CL_ValidateDeltaPacket( oldpacket, oldframe ))
|
||||
if(( cls.next_client_entities - oldframe->first_entity ) > ( cls.num_client_entities - NUM_PACKET_ENTITIES ))
|
||||
{
|
||||
CL_FlushEntityPacket( msg, proto );
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
}
|
||||
@@ -881,11 +860,27 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
|
||||
oldent = NULL;
|
||||
oldindex = 0;
|
||||
oldnum = CL_UpdateOldEntNum( oldindex, oldframe, &oldent );
|
||||
|
||||
if( !oldframe )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum, proto ))
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
@@ -897,7 +892,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_DeltaEntity( msg, newframe, oldnum, oldent, false );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
if( oldnum == newnum )
|
||||
@@ -906,7 +911,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
CL_DeltaEntity( msg, newframe, newnum, oldent, true );
|
||||
if( player ) playerbytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -925,7 +940,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_DeltaEntity( msg, newframe, oldnum, oldent, false );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
if( newframe->num_entities != count && newframe->num_entities != 0 )
|
||||
@@ -947,7 +972,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
cls.signon = SIGNONS;
|
||||
|
||||
// Clear loading plaque.
|
||||
CL_SignonReply( proto );
|
||||
CL_SignonReply ();
|
||||
}
|
||||
|
||||
return playerbytes;
|
||||
@@ -1265,7 +1290,7 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
else if( cls.legacymode == PROTO_LEGACY && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
||||
else if( cls.legacymode && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
||||
{
|
||||
if( !CL_InterpolateModel( ent ))
|
||||
continue;
|
||||
|
||||
@@ -34,10 +34,10 @@ GNU General Public License for more details.
|
||||
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
||||
#define TEXT_MSGNAME "TextMessage%i"
|
||||
|
||||
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||
static client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||
char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||
client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||
|
||||
static const dllfunc_t cdll_exports[] =
|
||||
static dllfunc_t cdll_exports[] =
|
||||
{
|
||||
{ "Initialize", (void **)&clgame.dllFuncs.pfnInitialize },
|
||||
{ "HUD_VidInit", (void **)&clgame.dllFuncs.pfnVidInit },
|
||||
@@ -80,7 +80,7 @@ static const dllfunc_t cdll_exports[] =
|
||||
};
|
||||
|
||||
// optional exports
|
||||
static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
|
||||
static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
|
||||
{
|
||||
{ "HUD_GetStudioModelInterface", (void **)&clgame.dllFuncs.pfnGetStudioModelInterface },
|
||||
{ "HUD_DirectorMessage", (void **)&clgame.dllFuncs.pfnDirectorMessage },
|
||||
@@ -140,7 +140,11 @@ returns true if thirdperson is enabled
|
||||
*/
|
||||
qboolean CL_IsThirdPerson( void )
|
||||
{
|
||||
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
|
||||
cl.local.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
|
||||
|
||||
if( cl.local.thirdperson )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,18 +252,18 @@ static int CL_AdjustXPos( float x, int width, int totalWidth )
|
||||
|
||||
if( x == -1 )
|
||||
{
|
||||
xPos = ( clgame.scrInfo.iWidth - width ) * 0.5f;
|
||||
xPos = ( refState.width - width ) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x < 0 )
|
||||
xPos = (1.0f + x) * clgame.scrInfo.iWidth - totalWidth; // Alight right
|
||||
xPos = (1.0f + x) * refState.width - totalWidth; // Alight right
|
||||
else // align left
|
||||
xPos = x * clgame.scrInfo.iWidth;
|
||||
xPos = x * refState.width;
|
||||
}
|
||||
|
||||
if( xPos + width > clgame.scrInfo.iWidth )
|
||||
xPos = clgame.scrInfo.iWidth - width;
|
||||
if( xPos + width > refState.width )
|
||||
xPos = refState.width - width;
|
||||
else if( xPos < 0 )
|
||||
xPos = 0;
|
||||
|
||||
@@ -279,19 +283,19 @@ static int CL_AdjustYPos( float y, int height )
|
||||
|
||||
if( y == -1 ) // centered?
|
||||
{
|
||||
yPos = ( clgame.scrInfo.iHeight - height ) * 0.5f;
|
||||
yPos = ( refState.height - height ) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alight bottom?
|
||||
if( y < 0 )
|
||||
yPos = (1.0f + y) * clgame.scrInfo.iHeight - height; // Alight bottom
|
||||
yPos = (1.0f + y) * refState.height - height; // Alight bottom
|
||||
else // align top
|
||||
yPos = y * clgame.scrInfo.iHeight;
|
||||
yPos = y * refState.height;
|
||||
}
|
||||
|
||||
if( yPos + height > clgame.scrInfo.iHeight )
|
||||
yPos = clgame.scrInfo.iHeight - height;
|
||||
if( yPos + height > refState.height )
|
||||
yPos = refState.height - height;
|
||||
else if( yPos < 0 )
|
||||
yPos = 0;
|
||||
|
||||
@@ -1015,8 +1019,7 @@ void CL_DrawHUD( int state )
|
||||
CL_DrawCrosshair ();
|
||||
CL_DrawCenterPrint ();
|
||||
clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
|
||||
if( showpause.value )
|
||||
CL_DrawLoadingOrPaused( cls.pauseIcon );
|
||||
CL_DrawLoadingOrPaused( cls.pauseIcon );
|
||||
break;
|
||||
case CL_LOADING:
|
||||
CL_DrawLoadingOrPaused( cls.loadingBar );
|
||||
@@ -3485,7 +3488,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, A2A_NETINFO" %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1303,16 +1303,6 @@ 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,
|
||||
@@ -1328,7 +1318,6 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
&gNetApi,
|
||||
pfnGetGameInfo,
|
||||
pfnGetModInfo,
|
||||
pfnIsCvarReadOnly,
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -63,9 +63,9 @@ static byte netcolors[NETGRAPH_NET_COLORS+NETGRAPH_LERP_HEIGHT][4] =
|
||||
// other will be generated through NetGraph_InitColors()
|
||||
};
|
||||
|
||||
static const byte sendcolor[4] = { 88, 29, 130, 255 };
|
||||
static const byte holdcolor[4] = { 255, 0, 0, 200 };
|
||||
static const byte extrap_base_color[4] = { 255, 255, 255, 255 };
|
||||
static byte sendcolor[4] = { 88, 29, 130, 255 };
|
||||
static byte holdcolor[4] = { 255, 0, 0, 200 };
|
||||
static byte extrap_base_color[4] = { 255, 255, 255, 255 };
|
||||
static netbandwidthgraph_t netstat_graph[NET_TIMINGS];
|
||||
static float packet_loss;
|
||||
static float packet_choke;
|
||||
@@ -79,7 +79,7 @@ NetGraph_DrawRect
|
||||
NetGraph_FillRGBA shortcut
|
||||
==========
|
||||
*/
|
||||
static void NetGraph_DrawRect( const wrect_t *rect, const byte colors[4] )
|
||||
static void NetGraph_DrawRect( wrect_t *rect, byte colors[4] )
|
||||
{
|
||||
ref.dllFuncs.Color4ub( colors[0], colors[1], colors[2], colors[3] ); // color for this quad
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,7 +137,12 @@ static void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
|
||||
//if( FBitSet( flags, SND_SEQUENCE ))
|
||||
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
|
||||
//else
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
@@ -264,7 +269,7 @@ static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
||||
Con_DPrintf( "Refusing new resource, cl_allow_download set to 0\n" );
|
||||
reslist.rescount = 0;
|
||||
}
|
||||
|
||||
@@ -295,7 +300,7 @@ static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
continue; // already exists
|
||||
|
||||
host.downloadcount++;
|
||||
HTTP_AddDownload( path, -1, true, NULL );
|
||||
HTTP_AddDownload( path, -1, true );
|
||||
}
|
||||
|
||||
if( !host.downloadcount )
|
||||
@@ -315,7 +320,7 @@ dispatch messages
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd;
|
||||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
const char *s;
|
||||
|
||||
@@ -340,9 +345,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_LEGACY, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
@@ -357,7 +359,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_legacy_event:
|
||||
CL_ParseEvent( msg, PROTO_LEGACY );
|
||||
CL_ParseEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_legacy_changing:
|
||||
@@ -419,7 +421,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_LEGACY );
|
||||
CL_ParseServerTime( msg );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
@@ -444,19 +446,19 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_LEGACY );
|
||||
CL_ParseServerData( msg, true );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_LEGACY );
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_LEGACY );
|
||||
CL_UpdateUserinfo( msg, true );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
CL_ParseClientData( msg, PROTO_LEGACY );
|
||||
CL_ParseClientData( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resource:
|
||||
@@ -466,58 +468,82 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
CL_UpdateUserPings( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_LEGACY );
|
||||
CL_ParseParticles( msg );
|
||||
break;
|
||||
case svc_restoresound:
|
||||
Con_Printf( S_ERROR "%s: svc_restoresound: implement me!\n", __func__ );
|
||||
CL_ParseRestoreSoundPacket( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_LegacyParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
CL_ParseReliableEvent( msg, PROTO_LEGACY );
|
||||
CL_ParseReliableEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
CL_ParseBaseline( msg, PROTO_LEGACY );
|
||||
CL_ParseBaseline( msg, true );
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
CL_ParseTempEntity( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
|
||||
break;
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_LEGACY );
|
||||
CL_ParseSignon( msg );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_intermission:
|
||||
cl.intermission = 1;
|
||||
break;
|
||||
case svc_legacy_modelindex:
|
||||
CL_LegacyPrecacheModel( msg );
|
||||
break;
|
||||
case svc_legacy_soundindex:
|
||||
CL_LegacyPrecacheSound( msg );
|
||||
break;
|
||||
case svc_cdtrack:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
|
||||
param2 = MSG_ReadByte( msg );
|
||||
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
|
||||
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_legacy_eventindex:
|
||||
CL_LegacyPrecacheEvent(msg);
|
||||
break;
|
||||
case svc_weaponanim:
|
||||
param1 = MSG_ReadByte( msg ); // iAnim
|
||||
param2 = MSG_ReadByte( msg ); // body
|
||||
CL_WeaponAnim( param1, param2 );
|
||||
break;
|
||||
case svc_bspdecal:
|
||||
CL_ParseStaticDecal( msg );
|
||||
break;
|
||||
case svc_roomtype:
|
||||
param1 = MSG_ReadShort( msg );
|
||||
Cvar_SetValue( "room_type", param1 );
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg, PROTO_LEGACY );
|
||||
CL_RegisterUserMessage( msg );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, false, PROTO_LEGACY );
|
||||
playerbytes = CL_ParsePacketEntities( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, true, PROTO_LEGACY );
|
||||
playerbytes = CL_ParsePacketEntities( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
@@ -564,6 +590,9 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_director:
|
||||
CL_ParseDirector( msg );
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
@@ -574,7 +603,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
CL_ParseUserMessage( msg, cmd );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
@@ -586,7 +615,7 @@ void CL_LegacyPrecache_f( void )
|
||||
int spawncount, i;
|
||||
model_t *mod;
|
||||
|
||||
if( cls.legacymode != PROTO_LEGACY )
|
||||
if( !cls.legacymode )
|
||||
return;
|
||||
|
||||
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
||||
@@ -629,3 +658,8 @@ void CL_LegacyPrecache_f( void )
|
||||
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
|
||||
cls.signon = SIGNONS - 1;
|
||||
}
|
||||
|
||||
qboolean CL_LegacyMode( void )
|
||||
{
|
||||
return cls.legacymode == PROTO_LEGACY;
|
||||
}
|
||||
|
||||
@@ -1,762 +0,0 @@
|
||||
/*
|
||||
cl_parse.c - parse a message received from the server (GoldSrc 48 protocol)
|
||||
Copyright (C) 2008 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
#include "server.h"
|
||||
|
||||
static void CL_ParseExtraInfo( sizebuf_t *msg )
|
||||
{
|
||||
string clientfallback;
|
||||
|
||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
||||
if( COM_CheckStringEmpty( clientfallback ))
|
||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
||||
|
||||
if( MSG_ReadByte( msg ))
|
||||
{
|
||||
Cvar_FullSet( "sv_cheats", "1", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
{
|
||||
Delta_InitClient(); // finalize client delta's
|
||||
|
||||
clgame.movevars.gravity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.stopspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.maxspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.spectatormaxspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.accelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.airaccelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.wateraccelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.friction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.edgefriction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.waterfriction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.entgravity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.bounce = MSG_ReadFloat( msg );
|
||||
clgame.movevars.stepsize = MSG_ReadFloat( msg );
|
||||
clgame.movevars.maxvelocity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.zmax = MSG_ReadFloat( msg );
|
||||
clgame.movevars.waveHeight = MSG_ReadFloat( msg );
|
||||
clgame.movevars.footsteps = MSG_ReadByte( msg );
|
||||
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
||||
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_r = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_g = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_b = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_x = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_y = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_z = MSG_ReadFloat( msg );
|
||||
|
||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||
|
||||
// water alpha is not allowed
|
||||
if( !FBitSet( world.flags, FWORLD_WATERALPHA ))
|
||||
clgame.movevars.wateralpha = 1.0f;
|
||||
|
||||
// update sky if changed
|
||||
if( Q_strcmp( clgame.oldmovevars.skyName, clgame.movevars.skyName ) && cl.video_prepped )
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
clgame.oldmovevars = clgame.movevars;
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
|
||||
// keep features an actual!
|
||||
clgame.oldmovevars.features = clgame.movevars.features = host.features;
|
||||
}
|
||||
|
||||
typedef struct delta_header_t
|
||||
{
|
||||
qboolean remove : 1;
|
||||
qboolean custom : 1;
|
||||
qboolean instanced : 1;
|
||||
uint instanced_baseline_index : 6;
|
||||
uint offset : 6;
|
||||
} delta_header_t;
|
||||
|
||||
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
|
||||
{
|
||||
int entnum = oldnum;
|
||||
memset( hdr, 0, sizeof( *hdr ));
|
||||
|
||||
if( !delta )
|
||||
{
|
||||
// if we have one bit set, then it's a next entity in line
|
||||
// if we have next bit NON set, then it's a one of next 64 entities
|
||||
// if not, it's a new entity
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
entnum++;
|
||||
else if( MSG_ReadOneBit( msg ) == 0 )
|
||||
entnum += MSG_ReadUBitLong( msg, 6 );
|
||||
else
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
}
|
||||
else
|
||||
{
|
||||
// does this packet encode entity deletion?
|
||||
hdr->remove = MSG_ReadOneBit( msg );
|
||||
|
||||
// same logic as above
|
||||
if( MSG_ReadOneBit( msg ) == 0 )
|
||||
entnum += MSG_ReadUBitLong( msg, 6 );
|
||||
else entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
}
|
||||
|
||||
// if we are not removing this entity
|
||||
if( !hdr->remove )
|
||||
{
|
||||
hdr->custom = MSG_ReadOneBit( msg );
|
||||
|
||||
// do we got instanced baselines in svc_spawnbaselines?
|
||||
if( cl.instanced_baseline_count )
|
||||
{
|
||||
hdr->instanced = MSG_ReadOneBit( msg );
|
||||
if( hdr->instanced )
|
||||
hdr->instanced_baseline_index = MSG_ReadUBitLong( msg, 6 );
|
||||
}
|
||||
|
||||
if( !delta && !hdr->instanced )
|
||||
{
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
hdr->offset = MSG_ReadUBitLong( msg, 6 );
|
||||
}
|
||||
}
|
||||
|
||||
return entnum;
|
||||
}
|
||||
|
||||
static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
|
||||
{
|
||||
if( hdr->custom )
|
||||
return DT_CUSTOM_ENTITY_STATE_T;
|
||||
|
||||
if( CL_IsPlayerIndex( entnum ))
|
||||
return DT_ENTITY_STATE_PLAYER_T;
|
||||
|
||||
return DT_ENTITY_STATE_T;
|
||||
}
|
||||
|
||||
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
{
|
||||
frame->valid = false;
|
||||
cl.validsequence = 0; // can't render a frame
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int num = 0;
|
||||
entity_state_t from = { 0 }, to;
|
||||
delta_header_t hdr;
|
||||
|
||||
if( MSG_ReadWord( msg ) != 0 )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
if( hdr.remove )
|
||||
continue;
|
||||
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
|
||||
{
|
||||
cl_entity_t *ent;
|
||||
entity_state_t *to;
|
||||
qboolean newent = from == NULL;
|
||||
int pack = frame->num_entities;
|
||||
qboolean has_update = msg != NULL;
|
||||
|
||||
// alloc next slot to store update
|
||||
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
||||
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
ent = CL_EDICT_NUM( newnum );
|
||||
if( hdr->remove )
|
||||
{
|
||||
if( !newent )
|
||||
CL_KillDeadBeams( ent );
|
||||
else
|
||||
Con_Printf( S_WARN "%s: entity remove on non-delta update (%d)\n", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
ent->index = newnum; // enumerate entity index
|
||||
if( newent )
|
||||
{
|
||||
if( hdr->instanced )
|
||||
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
||||
else if( hdr->offset != 0 )
|
||||
from = &cls.packet_entities[(cls.next_client_entities - hdr->offset) % cls.num_client_entities];
|
||||
else
|
||||
from = &ent->baseline;
|
||||
}
|
||||
|
||||
if( has_update )
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( hdr, newnum ), from, to, cl.mtime[0] );
|
||||
else memcpy( to, from, sizeof( entity_state_t ));
|
||||
|
||||
to->entityType = hdr->custom ? ENTITY_BEAM : ENTITY_NORMAL;
|
||||
to->number = newnum;
|
||||
|
||||
if( newent )
|
||||
{
|
||||
// interpolation must be reset
|
||||
SETVISBIT( frame->flags, pack );
|
||||
|
||||
// release beams from previous entity
|
||||
CL_KillDeadBeams( ent );
|
||||
}
|
||||
|
||||
// add entity to packet
|
||||
cls.next_client_entities++;
|
||||
frame->num_entities++;
|
||||
}
|
||||
|
||||
static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *from )
|
||||
{
|
||||
delta_header_t fakehdr =
|
||||
{
|
||||
.custom = FBitSet( from->entityType, ENTITY_BEAM ) == ENTITY_BEAM,
|
||||
};
|
||||
CL_DeltaEntityGS( &fakehdr, NULL, frame, num, from );
|
||||
}
|
||||
|
||||
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *frame, *oldframe;
|
||||
int oldindex, newnum, oldnum, numbase = 0;
|
||||
entity_state_t *oldent;
|
||||
int count;
|
||||
int playerbytes = 0;
|
||||
|
||||
// save first uncompressed packet as timestamp
|
||||
if( cls.changelevel && !delta && cls.demorecording )
|
||||
CL_WriteDemoJumpTime();
|
||||
|
||||
count = MSG_ReadWord( msg );
|
||||
|
||||
frame = &cl.frames[cl.parsecountmod];
|
||||
memset( frame->flags, 0, sizeof( frame->flags ));
|
||||
frame->first_entity = cls.next_client_entities;
|
||||
frame->num_entities = 0;
|
||||
frame->valid = true;
|
||||
|
||||
if( delta )
|
||||
{
|
||||
uint oldpacket = MSG_ReadByte( msg );
|
||||
oldframe = &cl.frames[oldpacket & CL_UPDATE_MASK];
|
||||
|
||||
if( !CL_ValidateDeltaPacket( oldpacket, oldframe ))
|
||||
{
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_FlushEntityPacketGS( frame, msg );
|
||||
MSG_EndBitWriting( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldframe = NULL;
|
||||
cl.send_reply = true;
|
||||
cls.demowaiting = false;
|
||||
}
|
||||
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
oldent = NULL;
|
||||
oldindex = 0;
|
||||
oldnum = CL_UpdateOldEntNum( oldindex, oldframe, &oldent );
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int bufstart;
|
||||
qboolean player;
|
||||
delta_header_t hdr;
|
||||
int val = MSG_ReadWord( msg );
|
||||
|
||||
if( val )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
numbase = newnum = CL_ParseDeltaHeader( msg, delta, numbase, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
while( oldnum < newnum )
|
||||
{
|
||||
if( !delta )
|
||||
Con_Printf( S_WARN "%s: old frame copy on non-delta update (%d < %d)\n", __func__, oldnum, newnum );
|
||||
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_CopyPacketEntity( frame, oldnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
|
||||
bufstart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
if( oldnum == newnum )
|
||||
{
|
||||
if( !delta )
|
||||
Con_Printf( S_WARN "%s: delta entity on non-delta update (%d)\n", __func__, oldnum );
|
||||
|
||||
// from delta
|
||||
CL_DeltaEntityGS( &hdr, msg, frame, newnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
else if( oldnum > newnum )
|
||||
{
|
||||
// from baseline
|
||||
CL_DeltaEntityGS( &hdr, msg, frame, newnum, NULL );
|
||||
}
|
||||
|
||||
if( player ) playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
|
||||
}
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
// any remaining entities in the old frame are copied over
|
||||
while( oldnum != MAX_ENTNUMBER )
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_CopyPacketEntity( frame, oldnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
|
||||
if( frame->num_entities != count )
|
||||
Con_Reportf( S_WARN "CL_Parse%sPacketEntitiesGS: (%i should be %i)\n", delta ? "Delta" : "", frame->num_entities, count );
|
||||
|
||||
if( !frame->valid )
|
||||
return playerbytes;
|
||||
|
||||
CL_ProcessPacket( frame );
|
||||
CL_SetSolidEntities();
|
||||
|
||||
// first update, received world, remove loading plaque
|
||||
if( cls.signon == ( SIGNONS - 1 ))
|
||||
{
|
||||
cls.signon = SIGNONS;
|
||||
CL_SignonReply( PROTO_GOLDSRC );
|
||||
}
|
||||
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
static float MSG_ReadGSBitCoord( sizebuf_t *sb )
|
||||
{
|
||||
float value = 0;
|
||||
int ival, fval;
|
||||
|
||||
ival = MSG_ReadOneBit( sb );
|
||||
fval = MSG_ReadOneBit( sb );
|
||||
|
||||
if( ival || fval )
|
||||
{
|
||||
int sign = MSG_ReadOneBit( sb );
|
||||
|
||||
if( ival )
|
||||
ival = MSG_ReadUBitLong( sb, 12 );
|
||||
if( fval )
|
||||
fval = MSG_ReadUBitLong( sb, 3 );
|
||||
|
||||
value = (float)( fval / 8.0 + ival );
|
||||
if( sign )
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void MSG_ReadGSBitVec3Coord( sizebuf_t *sb, vec3_t fa )
|
||||
{
|
||||
qboolean x, y, z;
|
||||
|
||||
VectorClear( fa );
|
||||
|
||||
x = MSG_ReadOneBit( sb );
|
||||
y = MSG_ReadOneBit( sb );
|
||||
z = MSG_ReadOneBit( sb );
|
||||
if( x )
|
||||
fa[0] = MSG_ReadGSBitCoord( sb );
|
||||
if( y )
|
||||
fa[1] = MSG_ReadGSBitCoord( sb );
|
||||
if( z )
|
||||
fa[2] = MSG_ReadGSBitCoord( sb );
|
||||
}
|
||||
|
||||
static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int chan, sound;
|
||||
float volume, attn;
|
||||
int flags, pitch, entnum;
|
||||
sound_t handle = 0;
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
flags = MSG_ReadUBitLong( msg, 9 );
|
||||
|
||||
if( FBitSet( flags, SND_VOLUME ))
|
||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( FBitSet( flags, SND_ATTENUATION ))
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
chan = MSG_ReadUBitLong( msg, 3 );
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
if( FBitSet( flags, SND_LEGACY_LARGE_INDEX ))
|
||||
sound = MSG_ReadWord( msg );
|
||||
else sound = MSG_ReadByte( msg );
|
||||
MSG_ReadGSBitVec3Coord( msg, pos );
|
||||
|
||||
if( FBitSet( flags, SND_PITCH ))
|
||||
pitch = MSG_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
|
||||
ClearBits( flags, SND_LEGACY_LARGE_INDEX );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
if( !cl.audio_prepped )
|
||||
return; // too early
|
||||
|
||||
// g-cont. sound and ambient sound have only difference with channel
|
||||
if( chan == CHAN_STATIC )
|
||||
{
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_ParseSpawnStaticSound( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int handle, entnum, pitch, flags;
|
||||
float volume, attn;
|
||||
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
handle = MSG_ReadShort( msg );
|
||||
volume = MSG_ReadByte( msg ) * ( 1.0f / 255.0f );
|
||||
attn = MSG_ReadByte( msg ) * ( 1.0f / 64.0f );
|
||||
entnum = MSG_ReadShort( msg );
|
||||
pitch = MSG_ReadByte( msg );
|
||||
flags = MSG_ReadByte( msg );
|
||||
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
ACTION MESSAGES
|
||||
|
||||
=====================================================================
|
||||
*/
|
||||
/*
|
||||
=====================
|
||||
CL_ParseGoldSrcServerMessage
|
||||
|
||||
dispatch messages
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd, param1;
|
||||
const char *s;
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark start position
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
// end of message (align bits)
|
||||
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
cmd = MSG_ReadServerCmd( msg );
|
||||
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_bad:
|
||||
Host_Error( "svc_bad\n" );
|
||||
break;
|
||||
case svc_nop:
|
||||
case svc_spawnstatic:
|
||||
case svc_goldsrc_damage:
|
||||
case svc_goldsrc_killedmonster:
|
||||
case svc_goldsrc_foundsecret:
|
||||
// this does nothing
|
||||
break;
|
||||
case svc_disconnect:
|
||||
s = MSG_ReadString( msg );
|
||||
if( COM_CheckStringEmpty( s ))
|
||||
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
||||
CL_Drop ();
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_event:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseEvent( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_goldsrc_version:
|
||||
param1 = MSG_ReadLong( msg );
|
||||
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
||||
break;
|
||||
case svc_setview:
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_ParseSoundPacketGS( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
if( cl_trace_stufftext.value )
|
||||
{
|
||||
size_t len = Q_strlen( s );
|
||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||
}
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
break;
|
||||
case svc_goldsrc_serverinfo:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_goldsrc_deltadescription:
|
||||
Delta_ParseTableField_GS( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseClientData( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_goldsrc_stopsound:
|
||||
param1 = MSG_ReadWord( msg );
|
||||
S_StopSound( param1 >> 3, param1 & 7, NULL );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_pings:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_UpdateUserPings( msg );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseReliableEvent( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseBaseline( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
||||
break;
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_goldsrc_spawnstaticsound:
|
||||
CL_ParseSpawnStaticSound( msg );
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_goldsrc_decalname:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
s = MSG_ReadString( msg );
|
||||
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_goldsrc_newusermsg:
|
||||
CL_RegisterUserMessage( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntitiesGS( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_choke:
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
break;
|
||||
case svc_resourcelist:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_goldsrc_newmovevars:
|
||||
CL_ParseNewMovevars( msg );
|
||||
break;
|
||||
case svc_resourcerequest:
|
||||
CL_ParseResourceRequest( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
break;
|
||||
case svc_filetxferfailed:
|
||||
CL_ParseFileTransferFailed( msg );
|
||||
break;
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_voiceinit:
|
||||
CL_ParseVoiceInit( msg );
|
||||
break;
|
||||
case svc_voicedata:
|
||||
CL_ParseVoiceData( msg, PROTO_GOLDSRC );
|
||||
cl.frames[cl.parsecountmod].graphdata.voicebytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_goldsrc_sendextrainfo:
|
||||
CL_ParseExtraInfo( msg );
|
||||
break;
|
||||
case svc_goldsrc_timescale:
|
||||
// we can set sys_timescale to anything we want but in GoldSrc it's locked for
|
||||
// HLTV and demoplayback. Do we really want to have it then if both are out of scope?
|
||||
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
||||
MSG_ReadFloat( msg );
|
||||
break;
|
||||
case svc_goldsrc_sendcvarvalue:
|
||||
CL_ParseCvarValue( msg, false, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_goldsrc_sendcvarvalue2:
|
||||
CL_ParseCvarValue( msg, true, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_exec:
|
||||
CL_ParseExec( msg );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ void GAME_EXPORT CL_PopPMStates( void )
|
||||
CL_IsPredicted
|
||||
===============
|
||||
*/
|
||||
static qboolean CL_IsPredicted( void )
|
||||
qboolean CL_IsPredicted( void )
|
||||
{
|
||||
if( cl_nopred.value || cl.intermission )
|
||||
return false;
|
||||
|
||||
@@ -431,7 +431,7 @@ static void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits )
|
||||
cls.signon = SIGNONS;
|
||||
|
||||
// Clear loading plaque.
|
||||
CL_SignonReply( PROTO_QUAKE );
|
||||
CL_SignonReply ();
|
||||
}
|
||||
|
||||
// alloc next slot to store update
|
||||
@@ -626,7 +626,7 @@ CL_ParseStaticEntity
|
||||
|
||||
===================
|
||||
*/
|
||||
static void CL_ParseQuakeStaticEntity( sizebuf_t *msg )
|
||||
static void CL_ParseStaticEntity( sizebuf_t *msg )
|
||||
{
|
||||
entity_state_t state;
|
||||
cl_entity_t *ent;
|
||||
@@ -950,7 +950,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
break;
|
||||
case svc_time:
|
||||
Cbuf_AddText( "\n" ); // new frame was started
|
||||
CL_ParseServerTime( msg, PROTO_QUAKE );
|
||||
CL_ParseServerTime( msg );
|
||||
break;
|
||||
case svc_print:
|
||||
str = MSG_ReadString( msg );
|
||||
@@ -1006,7 +1006,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
CL_ParseQuakeDamage( msg );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_ParseQuakeStaticEntity( msg );
|
||||
CL_ParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_spawnbinary:
|
||||
// never used in Quake
|
||||
|
||||
@@ -853,6 +853,7 @@ void SCR_Shutdown( void )
|
||||
{
|
||||
if( !scr_init ) return;
|
||||
|
||||
Cmd_RemoveCommand( "timerefresh" );
|
||||
Cmd_RemoveCommand( "skyname" );
|
||||
Cmd_RemoveCommand( "viewpos" );
|
||||
UI_SetActiveMenu( false );
|
||||
|
||||
@@ -35,17 +35,17 @@ TEMPENTS MANAGEMENT
|
||||
#define SHARD_VOLUME 12.0f // on shard ever n^3 units
|
||||
#define MAX_MUZZLEFLASH 3
|
||||
|
||||
static TEMPENTITY *cl_active_tents;
|
||||
static TEMPENTITY *cl_free_tents;
|
||||
static TEMPENTITY *cl_tempents = NULL; // entities pool
|
||||
TEMPENTITY *cl_active_tents;
|
||||
TEMPENTITY *cl_free_tents;
|
||||
TEMPENTITY *cl_tempents = NULL; // entities pool
|
||||
|
||||
static model_t *cl_sprite_muzzleflash[MAX_MUZZLEFLASH]; // muzzle flashes
|
||||
static model_t *cl_sprite_ricochet = NULL;
|
||||
static model_t *cl_sprite_glow = NULL;
|
||||
model_t *cl_sprite_dot = NULL;
|
||||
model_t *cl_sprite_shell = NULL;
|
||||
model_t *cl_sprite_muzzleflash[MAX_MUZZLEFLASH]; // muzzle flashes
|
||||
model_t *cl_sprite_dot = NULL;
|
||||
model_t *cl_sprite_ricochet = NULL;
|
||||
model_t *cl_sprite_shell = NULL;
|
||||
model_t *cl_sprite_glow = NULL;
|
||||
|
||||
static const char *const cl_default_sprites[] =
|
||||
const char *cl_default_sprites[] =
|
||||
{
|
||||
// built-in sprites
|
||||
"sprites/muzzleflash1.spr",
|
||||
@@ -169,28 +169,6 @@ void CL_AddClientResources( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ClearTempEnts
|
||||
|
||||
================
|
||||
*/
|
||||
static void CL_ClearTempEnts( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !cl_tempents ) return;
|
||||
|
||||
for( i = 0; i < GI->max_tents - 1; i++ )
|
||||
{
|
||||
cl_tempents[i].next = &cl_tempents[i+1];
|
||||
cl_tempents[i].entity.trivial_accept = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
cl_tempents[GI->max_tents-1].next = NULL;
|
||||
cl_free_tents = cl_tempents;
|
||||
cl_active_tents = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -207,6 +185,29 @@ void CL_InitTempEnts( void )
|
||||
CL_LoadClientSprites ();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ClearTempEnts
|
||||
|
||||
================
|
||||
*/
|
||||
void CL_ClearTempEnts( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !cl_tempents ) return;
|
||||
|
||||
for( i = 0; i < GI->max_tents - 1; i++ )
|
||||
{
|
||||
cl_tempents[i].next = &cl_tempents[i+1];
|
||||
cl_tempents[i].entity.trivial_accept = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
cl_tempents[GI->max_tents-1].next = NULL;
|
||||
cl_free_tents = cl_tempents;
|
||||
cl_active_tents = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_FreeTempEnts
|
||||
@@ -443,16 +444,11 @@ alloc normal\low priority tempentity
|
||||
*/
|
||||
TEMPENTITY *CL_TempEntAlloc( const vec3_t org, model_t *pmodel )
|
||||
{
|
||||
static float cl_lasttimewarn;
|
||||
TEMPENTITY *pTemp;
|
||||
|
||||
if( !cl_free_tents )
|
||||
{
|
||||
if( cl_lasttimewarn < host.realtime )
|
||||
{
|
||||
Con_DPrintf( "Overflow %d temporary ents!\n", GI->max_tents );
|
||||
cl_lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
Con_DPrintf( "Overflow %d temporary ents!\n", GI->max_tents );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1896,13 +1892,13 @@ CL_ParseTempEntity
|
||||
handle temp-entity messages
|
||||
==============
|
||||
*/
|
||||
void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
{
|
||||
sizebuf_t buf, *pbuf;
|
||||
byte msg_data[2048];
|
||||
sizebuf_t buf;
|
||||
byte pbuf[2048];
|
||||
int iSize;
|
||||
int type, color, count, flags;
|
||||
int decalIndex = 0, modelIndex = 0, entityIndex = 0;
|
||||
int decalIndex, modelIndex, entityIndex;
|
||||
float scale, life, frameRate, vel, random;
|
||||
float brightness, r, g, b;
|
||||
vec3_t pos, pos2, ang;
|
||||
@@ -1913,30 +1909,23 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
sound_t hSound;
|
||||
const char *name;
|
||||
|
||||
if( proto != PROTO_GOLDSRC )
|
||||
{
|
||||
if( proto == PROTO_LEGACY )
|
||||
iSize = MSG_ReadByte( msg );
|
||||
else iSize = MSG_ReadWord( msg );
|
||||
if( cls.legacymode )
|
||||
iSize = MSG_ReadByte( msg );
|
||||
else iSize = MSG_ReadWord( msg );
|
||||
|
||||
// this will probably be fatal anyway
|
||||
if( iSize > sizeof( msg_data ))
|
||||
Con_Printf( S_ERROR "%s: Temp buffer overflow!\n", __func__ );
|
||||
decalIndex = modelIndex = entityIndex = 0;
|
||||
|
||||
// parse user message into buffer
|
||||
MSG_ReadBytes( msg, msg_data, iSize );
|
||||
// this will probably be fatal anyway
|
||||
if( iSize > sizeof( pbuf ))
|
||||
Con_Printf( S_ERROR "%s: Temp buffer overflow!\n", __func__ );
|
||||
|
||||
// init a safe tempbuffer
|
||||
MSG_Init( &buf, "TempEntity", msg_data, iSize );
|
||||
// parse user message into buffer
|
||||
MSG_ReadBytes( msg, pbuf, iSize );
|
||||
|
||||
pbuf = &buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
pbuf = msg;
|
||||
}
|
||||
// init a safe tempbuffer
|
||||
MSG_Init( &buf, "TempEntity", pbuf, iSize );
|
||||
|
||||
type = MSG_ReadByte( pbuf );
|
||||
type = MSG_ReadByte( &buf );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
@@ -1953,29 +1942,29 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
case TE_BEAMRING:
|
||||
case TE_BEAMHOSE:
|
||||
case TE_KILLBEAM:
|
||||
CL_ParseViewBeam( pbuf, type );
|
||||
CL_ParseViewBeam( &buf, type );
|
||||
break;
|
||||
case TE_GUNSHOT:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
R_RicochetSound( pos );
|
||||
R_RunParticleEffect( pos, vec3_origin, 0, 20 );
|
||||
break;
|
||||
case TE_EXPLOSION:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
scale = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
frameRate = MSG_ReadByte( pbuf );
|
||||
flags = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
frameRate = MSG_ReadByte( &buf );
|
||||
flags = MSG_ReadByte( &buf );
|
||||
R_Explosion( pos, modelIndex, scale, frameRate, flags );
|
||||
break;
|
||||
case TE_TAREXPLOSION:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
R_BlobExplosion( pos );
|
||||
|
||||
if(( name = SoundList_Get( Explode, 0 )))
|
||||
@@ -1985,48 +1974,48 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
break;
|
||||
case TE_SMOKE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
scale = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
frameRate = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
frameRate = MSG_ReadByte( &buf );
|
||||
pTemp = R_DefaultSprite( pos, modelIndex, frameRate );
|
||||
R_Sprite_Smoke( pTemp, scale );
|
||||
break;
|
||||
case TE_TRACER:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
R_TracerEffect( pos, pos2 );
|
||||
break;
|
||||
case TE_SPARKS:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
R_SparkShower( pos );
|
||||
break;
|
||||
case TE_LAVASPLASH:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
R_LavaSplash( pos );
|
||||
break;
|
||||
case TE_TELEPORT:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
R_TeleportSplash( pos );
|
||||
break;
|
||||
case TE_EXPLOSION2:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
color = MSG_ReadByte( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
color = MSG_ReadByte( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
R_ParticleExplosion2( pos, color, count );
|
||||
|
||||
dl = CL_AllocDlight( 0 );
|
||||
@@ -2046,25 +2035,25 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
case TE_WORLDDECAL:
|
||||
case TE_WORLDDECALHIGH:
|
||||
case TE_DECALHIGH:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
if( type == TE_BSPDECAL )
|
||||
{
|
||||
decalIndex = MSG_ReadShort( pbuf );
|
||||
entityIndex = MSG_ReadShort( pbuf );
|
||||
decalIndex = MSG_ReadShort( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
if( entityIndex )
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
else modelIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
decalIndex = MSG_ReadByte( pbuf );
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
|
||||
decalIndex += 256;
|
||||
|
||||
if( type == TE_DECALHIGH || type == TE_DECAL )
|
||||
entityIndex = MSG_ReadShort( pbuf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
else entityIndex = 0;
|
||||
|
||||
pEnt = CL_GetEntityByIndex( entityIndex );
|
||||
@@ -2073,197 +2062,197 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, type == TE_BSPDECAL ? FDECAL_PERMANENT : 0 );
|
||||
break;
|
||||
case TE_IMPLOSION:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
scale = MSG_ReadByte( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
scale = MSG_ReadByte( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_Implosion( pos, scale, count, life );
|
||||
break;
|
||||
case TE_SPRITETRAIL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
life = (float)MSG_ReadByte( pbuf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
life = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( &buf );
|
||||
if( !scale ) scale = 1.0f;
|
||||
else scale *= 0.1f;
|
||||
vel = (float)MSG_ReadByte( pbuf ) * 10;
|
||||
random = (float)MSG_ReadByte( pbuf ) * 10;
|
||||
vel = (float)MSG_ReadByte( &buf ) * 10;
|
||||
random = (float)MSG_ReadByte( &buf ) * 10;
|
||||
R_Sprite_Trail( type, pos, pos2, modelIndex, count, life, scale, random, 255, vel );
|
||||
break;
|
||||
case TE_SPRITE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
scale = (float)MSG_ReadByte( pbuf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( pbuf ) / 255.0f;
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
|
||||
|
||||
R_TempSprite( pos, vec3_origin, scale, modelIndex,
|
||||
kRenderTransAdd, kRenderFxNone, brightness, 0.0, FTENT_SPRANIMATE );
|
||||
break;
|
||||
case TE_GLOWSPRITE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
life = (float)MSG_ReadByte( pbuf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( pbuf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( pbuf ) / 255.0f;
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
life = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
|
||||
|
||||
R_TempSprite( pos, vec3_origin, scale, modelIndex,
|
||||
kRenderGlow, kRenderFxNoDissipation, brightness, life, FTENT_FADEOUT );
|
||||
break;
|
||||
case TE_STREAK_SPLASH:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
color = MSG_ReadByte( pbuf );
|
||||
count = MSG_ReadShort( pbuf );
|
||||
vel = (float)MSG_ReadShort( pbuf );
|
||||
random = (float)MSG_ReadShort( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
color = MSG_ReadByte( &buf );
|
||||
count = MSG_ReadShort( &buf );
|
||||
vel = (float)MSG_ReadShort( &buf );
|
||||
random = (float)MSG_ReadShort( &buf );
|
||||
R_StreakSplash( pos, pos2, color, count, vel, -random, random );
|
||||
break;
|
||||
case TE_DLIGHT:
|
||||
dl = CL_AllocDlight( 0 );
|
||||
dl->origin[0] = MSG_ReadCoord( pbuf );
|
||||
dl->origin[1] = MSG_ReadCoord( pbuf );
|
||||
dl->origin[2] = MSG_ReadCoord( pbuf );
|
||||
dl->radius = (float)(MSG_ReadByte( pbuf ) * 10.0f);
|
||||
dl->color.r = MSG_ReadByte( pbuf );
|
||||
dl->color.g = MSG_ReadByte( pbuf );
|
||||
dl->color.b = MSG_ReadByte( pbuf );
|
||||
dl->die = cl.time + (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
dl->decay = (float)(MSG_ReadByte( pbuf ) * 10.0f);
|
||||
dl->origin[0] = MSG_ReadCoord( &buf );
|
||||
dl->origin[1] = MSG_ReadCoord( &buf );
|
||||
dl->origin[2] = MSG_ReadCoord( &buf );
|
||||
dl->radius = (float)(MSG_ReadByte( &buf ) * 10.0f);
|
||||
dl->color.r = MSG_ReadByte( &buf );
|
||||
dl->color.g = MSG_ReadByte( &buf );
|
||||
dl->color.b = MSG_ReadByte( &buf );
|
||||
dl->die = cl.time + (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
dl->decay = (float)(MSG_ReadByte( &buf ) * 10.0f);
|
||||
break;
|
||||
case TE_ELIGHT:
|
||||
dl = CL_AllocElight( MSG_ReadShort( pbuf ));
|
||||
dl->origin[0] = MSG_ReadCoord( pbuf );
|
||||
dl->origin[1] = MSG_ReadCoord( pbuf );
|
||||
dl->origin[2] = MSG_ReadCoord( pbuf );
|
||||
dl->radius = MSG_ReadCoord( pbuf );
|
||||
dl->color.r = MSG_ReadByte( pbuf );
|
||||
dl->color.g = MSG_ReadByte( pbuf );
|
||||
dl->color.b = MSG_ReadByte( pbuf );
|
||||
life = (float)MSG_ReadByte( pbuf ) * 0.1f;
|
||||
dl = CL_AllocElight( MSG_ReadShort( &buf ));
|
||||
dl->origin[0] = MSG_ReadCoord( &buf );
|
||||
dl->origin[1] = MSG_ReadCoord( &buf );
|
||||
dl->origin[2] = MSG_ReadCoord( &buf );
|
||||
dl->radius = MSG_ReadCoord( &buf );
|
||||
dl->color.r = MSG_ReadByte( &buf );
|
||||
dl->color.g = MSG_ReadByte( &buf );
|
||||
dl->color.b = MSG_ReadByte( &buf );
|
||||
life = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
dl->die = cl.time + life;
|
||||
dl->decay = MSG_ReadCoord( pbuf );
|
||||
dl->decay = MSG_ReadCoord( &buf );
|
||||
if( life != 0 ) dl->decay /= life;
|
||||
break;
|
||||
case TE_TEXTMESSAGE:
|
||||
CL_ParseTextMessage( pbuf );
|
||||
CL_ParseTextMessage( &buf );
|
||||
break;
|
||||
case TE_LINE:
|
||||
case TE_BOX:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
life = (float)(MSG_ReadShort( pbuf ) * 0.1f);
|
||||
r = MSG_ReadByte( pbuf );
|
||||
g = MSG_ReadByte( pbuf );
|
||||
b = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
life = (float)(MSG_ReadShort( &buf ) * 0.1f);
|
||||
r = MSG_ReadByte( &buf );
|
||||
g = MSG_ReadByte( &buf );
|
||||
b = MSG_ReadByte( &buf );
|
||||
if( type == TE_LINE ) R_ParticleLine( pos, pos2, r, g, b, life );
|
||||
else R_ParticleBox( pos, pos2, r, g, b, life );
|
||||
break;
|
||||
case TE_LARGEFUNNEL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
flags = MSG_ReadShort( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
flags = MSG_ReadShort( &buf );
|
||||
R_LargeFunnel( pos, flags );
|
||||
R_FunnelSprite( pos, modelIndex, flags );
|
||||
break;
|
||||
case TE_BLOODSTREAM:
|
||||
case TE_BLOOD:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
color = MSG_ReadByte( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
color = MSG_ReadByte( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
if( type == TE_BLOOD ) R_Blood( pos, pos2, color, count );
|
||||
else R_BloodStream( pos, pos2, color, count );
|
||||
break;
|
||||
case TE_SHOWLINE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
R_ShowLine( pos, pos2 );
|
||||
break;
|
||||
case TE_FIZZ:
|
||||
entityIndex = MSG_ReadShort( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
scale = MSG_ReadByte( pbuf ); // same as density
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
scale = MSG_ReadByte( &buf ); // same as density
|
||||
pEnt = CL_GetEntityByIndex( entityIndex );
|
||||
R_FizzEffect( pEnt, modelIndex, scale );
|
||||
break;
|
||||
case TE_MODEL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
ang[0] = 0.0f;
|
||||
ang[1] = MSG_ReadAngle( pbuf ); // yaw angle
|
||||
ang[1] = MSG_ReadAngle( &buf ); // yaw angle
|
||||
ang[2] = 0.0f;
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
flags = MSG_ReadByte( pbuf ); // sound flags
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
flags = MSG_ReadByte( &buf ); // sound flags
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_TempModel( pos, pos2, ang, life, modelIndex, flags );
|
||||
break;
|
||||
case TE_EXPLODEMODEL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
vel = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadShort( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
vel = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadShort( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_TempSphereModel( pos, vel, life, count, modelIndex );
|
||||
break;
|
||||
case TE_BREAKMODEL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
ang[0] = MSG_ReadCoord( pbuf );
|
||||
ang[1] = MSG_ReadCoord( pbuf );
|
||||
ang[2] = MSG_ReadCoord( pbuf );
|
||||
random = (float)MSG_ReadByte( pbuf ) * 10.0f;
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
flags = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
ang[0] = MSG_ReadCoord( &buf );
|
||||
ang[1] = MSG_ReadCoord( &buf );
|
||||
ang[2] = MSG_ReadCoord( &buf );
|
||||
random = (float)MSG_ReadByte( &buf ) * 10.0f;
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
flags = MSG_ReadByte( &buf );
|
||||
R_BreakModel( pos, pos2, ang, random, life, count, modelIndex, (char)flags );
|
||||
break;
|
||||
case TE_GUNSHOTDECAL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
entityIndex = MSG_ReadShort( pbuf );
|
||||
decalIndex = MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 );
|
||||
R_BulletImpactParticles( pos );
|
||||
flags = COM_RandomLong( 0, 0x7fff );
|
||||
@@ -2272,139 +2261,139 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
break;
|
||||
case TE_SPRAY:
|
||||
case TE_SPRITE_SPRAY:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
vel = (float)MSG_ReadByte( pbuf );
|
||||
random = (float)MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
vel = (float)MSG_ReadByte( &buf );
|
||||
random = (float)MSG_ReadByte( &buf );
|
||||
if( type == TE_SPRAY )
|
||||
{
|
||||
flags = MSG_ReadByte( pbuf ); // rendermode
|
||||
flags = MSG_ReadByte( &buf ); // rendermode
|
||||
R_Spray( pos, pos2, modelIndex, count, vel, random, flags );
|
||||
}
|
||||
else R_Sprite_Spray( pos, pos2, modelIndex, count, vel * 2.0f, random );
|
||||
break;
|
||||
case TE_ARMOR_RICOCHET:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
scale = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_RicochetSprite( pos, cl_sprite_ricochet, 0.1f, scale );
|
||||
R_RicochetSound( pos );
|
||||
break;
|
||||
case TE_PLAYERDECAL:
|
||||
color = MSG_ReadByte( pbuf ) - 1; // playernum
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
entityIndex = MSG_ReadShort( pbuf );
|
||||
decalIndex = MSG_ReadByte( pbuf );
|
||||
color = MSG_ReadByte( &buf ) - 1; // playernum
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
CL_PlayerDecal( color, decalIndex, entityIndex, pos );
|
||||
break;
|
||||
case TE_BUBBLES:
|
||||
case TE_BUBBLETRAIL:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
scale = MSG_ReadCoord( pbuf ); // water height
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
vel = MSG_ReadCoord( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
scale = MSG_ReadCoord( &buf ); // water height
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
vel = MSG_ReadCoord( &buf );
|
||||
if( type == TE_BUBBLES ) R_Bubbles( pos, pos2, scale, modelIndex, count, vel );
|
||||
else R_BubbleTrail( pos, pos2, scale, modelIndex, count, vel );
|
||||
break;
|
||||
case TE_BLOODSPRITE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf ); // sprite #1
|
||||
decalIndex = MSG_ReadShort( pbuf ); // sprite #2
|
||||
color = MSG_ReadByte( pbuf );
|
||||
scale = (float)MSG_ReadByte( pbuf );
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf ); // sprite #1
|
||||
decalIndex = MSG_ReadShort( &buf ); // sprite #2
|
||||
color = MSG_ReadByte( &buf );
|
||||
scale = (float)MSG_ReadByte( &buf );
|
||||
R_BloodSprite( pos, color, modelIndex, decalIndex, scale );
|
||||
break;
|
||||
case TE_PROJECTILE:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
life = MSG_ReadByte( pbuf );
|
||||
color = MSG_ReadByte( pbuf ); // playernum
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
life = MSG_ReadByte( &buf );
|
||||
color = MSG_ReadByte( &buf ); // playernum
|
||||
R_Projectile( pos, pos2, modelIndex, life, color, NULL );
|
||||
break;
|
||||
case TE_PLAYERSPRITES:
|
||||
color = MSG_ReadShort( pbuf ); // entitynum
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
random = (float)MSG_ReadByte( pbuf );
|
||||
color = MSG_ReadShort( &buf ); // entitynum
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
random = (float)MSG_ReadByte( &buf );
|
||||
R_PlayerSprites( color, modelIndex, count, random );
|
||||
break;
|
||||
case TE_PARTICLEBURST:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
scale = (float)MSG_ReadShort( pbuf );
|
||||
color = MSG_ReadByte( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
scale = (float)MSG_ReadShort( &buf );
|
||||
color = MSG_ReadByte( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_ParticleBurst( pos, scale, color, life );
|
||||
break;
|
||||
case TE_FIREFIELD:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
scale = (float)MSG_ReadShort( pbuf );
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
count = MSG_ReadByte( pbuf );
|
||||
flags = MSG_ReadByte( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
scale = (float)MSG_ReadShort( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
flags = MSG_ReadByte( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_FireField( pos, scale, modelIndex, count, flags, life );
|
||||
break;
|
||||
case TE_PLAYERATTACHMENT:
|
||||
color = MSG_ReadByte( pbuf ); // playernum
|
||||
scale = MSG_ReadCoord( pbuf ); // height
|
||||
modelIndex = MSG_ReadShort( pbuf );
|
||||
life = (float)(MSG_ReadShort( pbuf ) * 0.1f);
|
||||
color = MSG_ReadByte( &buf ); // playernum
|
||||
scale = MSG_ReadCoord( &buf ); // height
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
life = (float)(MSG_ReadShort( &buf ) * 0.1f);
|
||||
R_AttachTentToPlayer( color, modelIndex, scale, life );
|
||||
break;
|
||||
case TE_KILLPLAYERATTACHMENTS:
|
||||
color = MSG_ReadByte( pbuf ); // playernum
|
||||
color = MSG_ReadByte( &buf ); // playernum
|
||||
R_KillAttachedTents( color );
|
||||
break;
|
||||
case TE_MULTIGUNSHOT:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf ) * 0.1f;
|
||||
pos2[1] = MSG_ReadCoord( pbuf ) * 0.1f;
|
||||
pos2[2] = MSG_ReadCoord( pbuf ) * 0.1f;
|
||||
ang[0] = MSG_ReadCoord( pbuf ) * 0.01f;
|
||||
ang[1] = MSG_ReadCoord( pbuf ) * 0.01f;
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf ) * 0.1f;
|
||||
pos2[1] = MSG_ReadCoord( &buf ) * 0.1f;
|
||||
pos2[2] = MSG_ReadCoord( &buf ) * 0.1f;
|
||||
ang[0] = MSG_ReadCoord( &buf ) * 0.01f;
|
||||
ang[1] = MSG_ReadCoord( &buf ) * 0.01f;
|
||||
ang[2] = 0.0f;
|
||||
count = MSG_ReadByte( pbuf );
|
||||
decalIndices[0] = MSG_ReadByte( pbuf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
decalIndices[0] = MSG_ReadByte( &buf );
|
||||
R_MultiGunshot( pos, pos2, ang, count, 1, decalIndices );
|
||||
break;
|
||||
case TE_USERTRACER:
|
||||
pos[0] = MSG_ReadCoord( pbuf );
|
||||
pos[1] = MSG_ReadCoord( pbuf );
|
||||
pos[2] = MSG_ReadCoord( pbuf );
|
||||
pos2[0] = MSG_ReadCoord( pbuf );
|
||||
pos2[1] = MSG_ReadCoord( pbuf );
|
||||
pos2[2] = MSG_ReadCoord( pbuf );
|
||||
life = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
color = MSG_ReadByte( pbuf );
|
||||
scale = (float)(MSG_ReadByte( pbuf ) * 0.1f);
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
pos2[0] = MSG_ReadCoord( &buf );
|
||||
pos2[1] = MSG_ReadCoord( &buf );
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
color = MSG_ReadByte( &buf );
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
R_UserTracerParticle( pos, pos2, life, color, scale, 0, NULL );
|
||||
break;
|
||||
default:
|
||||
@@ -2413,7 +2402,7 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
|
||||
// throw warning
|
||||
if( MSG_CheckOverflow( pbuf ))
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Con_DPrintf( S_WARN "%s: overflow TE message %i\n", __func__, type );
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ void R_MultiGunshot( const vec3_t org, const vec3_t dir, const vec3_t noise, int
|
||||
void R_FireField( float *org, int radius, int modelIndex, int count, int flags, float life );
|
||||
void R_PlayerSprites( int client, int modelIndex, int count, int size );
|
||||
void R_Sprite_WallPuff( struct tempent_s *pTemp, float scale );
|
||||
void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b );
|
||||
void R_RicochetSound( const vec3_t pos );
|
||||
struct dlight_s *CL_AllocDlight( int key );
|
||||
struct dlight_s *CL_AllocElight( int key );
|
||||
|
||||
@@ -129,6 +129,7 @@ typedef struct
|
||||
|
||||
// misc local info
|
||||
qboolean repredicting; // repredicting in progress
|
||||
qboolean thirdperson;
|
||||
qboolean apply_effects; // local player will not added but we should apply their effects: flashlight etc
|
||||
float idealpitch;
|
||||
int viewmodel;
|
||||
@@ -277,8 +278,6 @@ typedef struct
|
||||
int lostpackets; // count lost packets and show dialog in menu
|
||||
|
||||
double frametime_remainder;
|
||||
|
||||
uint worldmapCRC;
|
||||
} client_t;
|
||||
|
||||
/*
|
||||
@@ -310,6 +309,14 @@ typedef enum
|
||||
CL_CHANGELEVEL, // draw 'loading' during changelevel
|
||||
} scrstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTO_CURRENT = 0, // Xash3D 49
|
||||
PROTO_LEGACY = 1, // Xash3D 48
|
||||
PROTO_QUAKE = 2, // Quake 15
|
||||
PROTO_GOLDSRC = 3, // GoldSrc 48
|
||||
} connprotocol_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
@@ -560,6 +567,7 @@ 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;
|
||||
@@ -652,7 +660,6 @@ extern gameui_static_t gameui;
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
extern convar_t showpause;
|
||||
extern convar_t mp_decals;
|
||||
extern convar_t cl_logomaxdim;
|
||||
extern convar_t cl_allow_download;
|
||||
@@ -747,13 +754,13 @@ 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( connprotocol_t proto, sizebuf_t *msg, int from, int to );
|
||||
void CL_SetupNetchanForProtocol( connprotocol_t proto );
|
||||
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
|
||||
int CL_GetFragmentSize( void *unused , fragsize_t mode );
|
||||
qboolean CL_PrecacheResources( void );
|
||||
void CL_SetupOverviewParams( void );
|
||||
void CL_UpdateFrameLerp( void );
|
||||
int CL_IsDevOverviewMode( void );
|
||||
void CL_SignonReply( connprotocol_t proto );
|
||||
void CL_SignonReply( void );
|
||||
void CL_ClearState( void );
|
||||
|
||||
//
|
||||
@@ -783,8 +790,8 @@ int CL_GetDemoComment( const char *demoname, char *comment );
|
||||
//
|
||||
// cl_events.c
|
||||
//
|
||||
void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseEvent( sizebuf_t *msg );
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg );
|
||||
void CL_SetEventIndex( const char *szEvName, int ev_index );
|
||||
void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
|
||||
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
|
||||
@@ -861,21 +868,20 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
// cl_parse.c
|
||||
//
|
||||
void CL_ParseSetAngle( sizebuf_t *msg );
|
||||
void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseLightStyle( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseLightStyle( sizebuf_t *msg );
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseResource( sizebuf_t *msg );
|
||||
void CL_ParseClientData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseClientData( sizebuf_t *msg );
|
||||
void CL_UpdateUserPings( sizebuf_t *msg );
|
||||
void CL_ParseParticles( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseParticles( sizebuf_t *msg );
|
||||
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
|
||||
void CL_ParseBaseline( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseSignon( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseSignon( sizebuf_t *msg );
|
||||
void CL_ParseRestore( sizebuf_t *msg );
|
||||
void CL_ParseStaticDecal( sizebuf_t *msg );
|
||||
void CL_ParseAddAngle( sizebuf_t *msg );
|
||||
void CL_RegisterUserMessage( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseResourceList( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_RegisterUserMessage( sizebuf_t *msg );
|
||||
void CL_ParseMovevars( sizebuf_t *msg );
|
||||
void CL_ParseResourceRequest( sizebuf_t *msg );
|
||||
void CL_ParseCustomization( sizebuf_t *msg );
|
||||
@@ -884,22 +890,18 @@ void CL_ParseSoundFade( sizebuf_t *msg );
|
||||
void CL_ParseFileTransferFailed( sizebuf_t *msg );
|
||||
void CL_ParseHLTV( sizebuf_t *msg );
|
||||
void CL_ParseDirector( sizebuf_t *msg );
|
||||
void CL_ParseVoiceInit( sizebuf_t *msg );
|
||||
void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseResLocation( sizebuf_t *msg );
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext, const connprotocol_t proto );
|
||||
void CL_ParseServerMessage( sizebuf_t *msg );
|
||||
qboolean CL_ParseCommonDLLMessage( sizebuf_t *msg, connprotocol_t proto, int svc_num, int startoffset );
|
||||
void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseTempEntity( sizebuf_t *msg );
|
||||
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
|
||||
qboolean CL_RequestMissingResources( void );
|
||||
void CL_RegisterResources( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_RegisterResources ( sizebuf_t *msg );
|
||||
void CL_ParseViewEntity( sizebuf_t *msg );
|
||||
void CL_ParseServerTime( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num, connprotocol_t proto );
|
||||
void CL_ParseServerTime( sizebuf_t *msg );
|
||||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
|
||||
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
|
||||
void CL_ParseTextMessage( sizebuf_t *msg );
|
||||
void CL_ParseExec( sizebuf_t *msg );
|
||||
void CL_BatchResourceRequest( qboolean initialize );
|
||||
int CL_EstimateNeededResources( void );
|
||||
|
||||
@@ -909,11 +911,6 @@ int CL_EstimateNeededResources( void );
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg );
|
||||
void CL_LegacyPrecache_f( void );
|
||||
|
||||
//
|
||||
// cl_parse_gs.c
|
||||
//
|
||||
void CL_ParseGoldSrcServerMessage( sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
//
|
||||
@@ -955,6 +952,7 @@ void CL_SetSolidPlayers( int playernum );
|
||||
void CL_InitClientMove( void );
|
||||
void CL_PredictMovement( qboolean repredicting );
|
||||
void CL_CheckPredictionError( void );
|
||||
qboolean CL_IsPredicted( void );
|
||||
int CL_WaterEntity( const float *rgflPos );
|
||||
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
|
||||
pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
|
||||
@@ -977,9 +975,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg );
|
||||
//
|
||||
struct channel_s;
|
||||
struct rawchan_s;
|
||||
qboolean CL_ValidateDeltaPacket( uint oldpacket, frame_t *oldframe );
|
||||
int CL_UpdateOldEntNum( int oldindex, frame_t *oldframe, entity_state_t **oldent );
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto );
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta );
|
||||
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
|
||||
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
|
||||
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
|
||||
@@ -1029,6 +1025,7 @@ void CL_InitParticles( void );
|
||||
void CL_ClearParticles( void );
|
||||
void CL_FreeParticles( void );
|
||||
void CL_InitTempEnts( void );
|
||||
void CL_ClearTempEnts( void );
|
||||
void CL_FreeTempEnts( void );
|
||||
void CL_TempEntUpdate( void );
|
||||
void CL_InitViewBeams( void );
|
||||
|
||||
@@ -875,6 +875,7 @@ void Con_Print( const char *txt )
|
||||
Con_DeleteLastLine();
|
||||
cr_pending = 0;
|
||||
}
|
||||
|
||||
c = *txt;
|
||||
|
||||
switch( c )
|
||||
@@ -882,13 +883,10 @@ void Con_Print( const char *txt )
|
||||
case '\0':
|
||||
break;
|
||||
case '\r':
|
||||
if( txt[1] != '\n' )
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = 1;
|
||||
bufpos = 0;
|
||||
}
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = 1;
|
||||
bufpos = 0;
|
||||
break;
|
||||
case '\n':
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
@@ -896,7 +894,6 @@ void Con_Print( const char *txt )
|
||||
bufpos = 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
buf[bufpos++] = c | mask;
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
|
||||
{
|
||||
@@ -1944,7 +1941,7 @@ void Con_DrawConsole( void )
|
||||
{
|
||||
if( !cl_allow_levelshots.value && !cls.timedemo )
|
||||
{
|
||||
if( cls.key_dest != key_console && ( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )))
|
||||
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
|
||||
con.vislines = con.showlines = 0;
|
||||
else con.vislines = con.showlines = refState.height;
|
||||
}
|
||||
|
||||
@@ -569,9 +569,10 @@ IN_EngineAppendMove
|
||||
Called from cl_main.c after generating command in client
|
||||
================
|
||||
*/
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active )
|
||||
void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
|
||||
{
|
||||
float forward, side, pitch, yaw;
|
||||
usercmd_t *cmd = cmd1;
|
||||
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
return;
|
||||
|
||||
@@ -25,7 +25,6 @@ INPUT
|
||||
*/
|
||||
|
||||
#include "keydefs.h"
|
||||
#include "usercmd.h"
|
||||
|
||||
//
|
||||
// input.c
|
||||
@@ -44,7 +43,7 @@ void IN_ToggleClientMouse( int newstate, int oldstate );
|
||||
|
||||
uint IN_CollectInputDevices( void );
|
||||
void IN_LockInputDevices( qboolean lock );
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
|
||||
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
|
||||
|
||||
extern convar_t m_yaw;
|
||||
extern convar_t m_pitch;
|
||||
|
||||
@@ -1894,7 +1894,7 @@ S_VoiceRecordStart_f
|
||||
*/
|
||||
static void S_VoiceRecordStart_f( void )
|
||||
{
|
||||
if( cls.state != ca_active )
|
||||
if( cls.state != ca_active || cls.legacymode )
|
||||
return;
|
||||
|
||||
Voice_RecordStart();
|
||||
|
||||
@@ -248,12 +248,6 @@ static const char *VOX_GetDirectory( char *szpath, const char *psz, int nsize )
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
// HACKHACK: some modders send strings like "/fvox/_period four"
|
||||
// which should get parsed as "_period four" said by fvox
|
||||
// it might be incorrect but ignore first slash here for now
|
||||
if( psz[0] == '/' )
|
||||
psz++;
|
||||
|
||||
// search / backwards
|
||||
p = Q_strrchr( psz, '/' );
|
||||
|
||||
@@ -601,8 +595,8 @@ static void Test_VOX_GetDirectory( void )
|
||||
{
|
||||
"", "", "vox/",
|
||||
"bark bark", "bark bark", "vox/",
|
||||
"barney/meow", "meow", "barney/",
|
||||
"/fvox/_period", "_period", "fvox/",
|
||||
"barney/meow", "meow", "barney/"
|
||||
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -396,9 +396,6 @@ void Voice_RecordStart( void )
|
||||
{
|
||||
Voice_RecordStop();
|
||||
|
||||
if( !voice.initialized )
|
||||
return;
|
||||
|
||||
if( voice_inputfromfile.value )
|
||||
{
|
||||
voice.input_file = FS_LoadSound( "voice_input.wav", NULL, 0 );
|
||||
@@ -418,7 +415,7 @@ void Voice_RecordStart( void )
|
||||
}
|
||||
}
|
||||
|
||||
if( !Voice_IsRecording( ) && voice.device_opened )
|
||||
if( !Voice_IsRecording() )
|
||||
voice.is_recording = VoiceCapture_Activate( true );
|
||||
|
||||
if( Voice_IsRecording() )
|
||||
@@ -630,8 +627,7 @@ qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit )
|
||||
{
|
||||
if( Q_strcmp( pszCodecName, VOICE_OPUS_CUSTOM_CODEC ))
|
||||
{
|
||||
if( COM_CheckStringEmpty( pszCodecName ))
|
||||
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
|
||||
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
|
||||
|
||||
// reset saved codec name, we won't enable voice for this connection
|
||||
voice_codec_init[0] = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef enum
|
||||
T_COUNT
|
||||
} cvartype_t;
|
||||
|
||||
static const char *const cvartypes[] = { NULL, "BOOL", "NUMBER", "LIST", "STRING" };
|
||||
const char *cvartypes[] = { NULL, "BOOL", "NUMBER", "LIST", "STRING" };
|
||||
|
||||
typedef struct parserstate_s
|
||||
{
|
||||
|
||||
@@ -24,27 +24,18 @@ GNU General Public License for more details.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte *const data;
|
||||
const int maxsize;
|
||||
int cursize;
|
||||
byte *data;
|
||||
int cursize;
|
||||
int maxsize;
|
||||
} cmdbuf_t;
|
||||
|
||||
static qboolean cmd_wait;
|
||||
static byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
static byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
static cmdbuf_t cmd_text =
|
||||
{
|
||||
.data = cmd_text_buf,
|
||||
.maxsize = ARRAYSIZE( cmd_text_buf ),
|
||||
};
|
||||
static cmdbuf_t filteredcmd_text =
|
||||
{
|
||||
.data = filteredcmd_text_buf,
|
||||
.maxsize = ARRAYSIZE( filteredcmd_text_buf ),
|
||||
};
|
||||
static cmdalias_t *cmd_alias;
|
||||
static uint cmd_condition;
|
||||
static int cmd_condlevel;
|
||||
qboolean cmd_wait;
|
||||
cmdbuf_t cmd_text, filteredcmd_text;
|
||||
byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
cmdalias_t *cmd_alias;
|
||||
uint cmd_condition;
|
||||
int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
@@ -57,6 +48,20 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Init
|
||||
============
|
||||
*/
|
||||
static void Cbuf_Init( void )
|
||||
{
|
||||
cmd_text.data = cmd_text_buf;
|
||||
filteredcmd_text.data = filteredcmd_text_buf;
|
||||
|
||||
filteredcmd_text.maxsize = cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
filteredcmd_text.cursize = cmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Clear
|
||||
@@ -1214,13 +1219,13 @@ void Cmd_Unlink( int group )
|
||||
cmd_t **prev;
|
||||
int count = 0;
|
||||
|
||||
if( FBitSet( group, CMD_SERVERDLL ) && Cvar_VariableInteger( "host_gameloaded" ))
|
||||
if( Cvar_VariableInteger( "host_gameloaded" ) && FBitSet( group, CMD_SERVERDLL ))
|
||||
return;
|
||||
|
||||
if( FBitSet( group, CMD_CLIENTDLL ) && Cvar_VariableInteger( "host_clientloaded" ))
|
||||
if( Cvar_VariableInteger( "host_clientloaded" ) && FBitSet( group, CMD_CLIENTDLL ))
|
||||
return;
|
||||
|
||||
if( FBitSet( group, CMD_GAMEUIDLL ) && Cvar_VariableInteger( "host_gameuiloaded" ))
|
||||
if( Cvar_VariableInteger( "host_gameuiloaded" ) && FBitSet( group, CMD_GAMEUIDLL ))
|
||||
return;
|
||||
|
||||
prev = &cmd_functions;
|
||||
@@ -1382,6 +1387,8 @@ Cmd_Init
|
||||
*/
|
||||
void Cmd_Init( void )
|
||||
{
|
||||
Cbuf_Init();
|
||||
|
||||
cmd_functions = NULL;
|
||||
cmd_condition = 0;
|
||||
cmd_alias = NULL;
|
||||
|
||||
@@ -23,7 +23,7 @@ GNU General Public License for more details.
|
||||
#include "client.h"
|
||||
#include "library.h"
|
||||
|
||||
static const char *const file_exts[] =
|
||||
static const char *file_exts[] =
|
||||
{
|
||||
// ban text files that don't make sense as resource
|
||||
"cfg", "lst", "ini", "log",
|
||||
@@ -759,6 +759,25 @@ void GAME_EXPORT COM_FreeFile( void *buffer )
|
||||
free( buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
COM_NormalizeAngles
|
||||
|
||||
=============
|
||||
*/
|
||||
void COM_NormalizeAngles( vec3_t angles )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( angles[i] > 180.0f )
|
||||
angles[i] -= 360.0f;
|
||||
else if( angles[i] < -180.0f )
|
||||
angles[i] += 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnGetModelType
|
||||
@@ -824,7 +843,7 @@ int GAME_EXPORT COM_CompareFileTime( const char *filename1, const char *filename
|
||||
if( ft1 == -1 || ft2 == -1 )
|
||||
return bRet;
|
||||
|
||||
*iCompare = ft1 < ft2 ? -1 : ( ft1 > ft2 ? 1 : 0 );
|
||||
*iCompare = Host_CompareFileTime( ft1, ft2 );
|
||||
bRet = 1;
|
||||
}
|
||||
|
||||
@@ -879,40 +898,18 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
char lwrfilename[4096];
|
||||
const char *first, *last;
|
||||
const char *ext;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
return false;
|
||||
|
||||
ext = COM_FileExtension( filename );
|
||||
len = Q_strlen( filename );
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
// only allow extensionless files that start with !MD5
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ))
|
||||
{
|
||||
if( COM_CheckStringEmpty( ext ))
|
||||
return false;
|
||||
|
||||
len = Q_strlen( filename );
|
||||
|
||||
if( len != 36 )
|
||||
return false;
|
||||
|
||||
for( i = 4; i < len; i++ )
|
||||
{
|
||||
if(( filename[i] >= '0' && filename[i] <= '9' ) ||
|
||||
( filename[i] >= 'A' && filename[i] <= 'F' ))
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ) && ext[0] == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) )
|
||||
return false;
|
||||
@@ -1045,13 +1042,28 @@ void GAME_EXPORT pfnResetTutorMessageDecayData( void )
|
||||
|
||||
void Test_RunCommon( void )
|
||||
{
|
||||
Msg( "Checking COM_IsSafeFileToDownload...\n" );
|
||||
char *file = (char *)"q asdf \"qwerty\" \"f \\\"f\" meowmeow\n// comment \"stuff ignored\"\nbark";
|
||||
int len;
|
||||
char buf[5];
|
||||
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302BC732" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD56f1ffd8c96bd64c9c27955309f6ecfe6" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302B.exe" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5/../../valve/resource/GameMenu.res" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "not-a-virus-trust-me.bat" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "a-texture.png" ), true );
|
||||
Msg( "Checking COM_ParseFile...\n" );
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "q" ) && len == 1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "asdf" ) && len == 4);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "qwer" ) && len == -1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "f \"f" ) && len == 4);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "meow" ) && len == -1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "bark" ) && len == 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -168,7 +168,6 @@ extern convar_t sys_timescale;
|
||||
extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
extern convar_t hpk_custom_file;
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
|
||||
|
||||
@@ -529,6 +528,7 @@ typedef void( *pfnChangeGame )( const char *progname );
|
||||
qboolean Host_IsQuakeCompatible( void );
|
||||
void EXPORT Host_Shutdown( void );
|
||||
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func );
|
||||
int Host_CompareFileTime( int ft1, int ft2 );
|
||||
void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 );
|
||||
void Host_AbortCurrentFrame( void ) NORETURN;
|
||||
void Host_WriteServerConfig( const char *name );
|
||||
@@ -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 mask, uint32_t features );
|
||||
void Host_ValidateEngineFeatures( uint32_t features );
|
||||
void Host_Frame( double time );
|
||||
void Host_Credits( void );
|
||||
|
||||
@@ -670,15 +670,6 @@ void HPAK_FlushHostQueue( void );
|
||||
#define INPUT_DEVICE_JOYSTICK (1<<2)
|
||||
#define INPUT_DEVICE_VR (1<<3)
|
||||
|
||||
|
||||
typedef enum connprotocol_e
|
||||
{
|
||||
PROTO_CURRENT = 0, // Xash3D 49
|
||||
PROTO_LEGACY, // Xash3D 48
|
||||
PROTO_QUAKE, // Quake 15
|
||||
PROTO_GOLDSRC, // GoldSrc 48
|
||||
} connprotocol_t;
|
||||
|
||||
// shared calls
|
||||
struct physent_s;
|
||||
struct sv_client_s;
|
||||
@@ -689,6 +680,7 @@ qboolean CL_IsThirdPerson( void );
|
||||
qboolean CL_IsIntermission( void );
|
||||
qboolean CL_Initialized( void );
|
||||
char *CL_Userinfo( void );
|
||||
void CL_LegacyUpdateInfo( void );
|
||||
void CL_CharEvent( int key );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) MALLOC_LIKE( free, 1 );
|
||||
@@ -769,34 +761,13 @@ void UI_ShowConnectionWarning( void );
|
||||
void Cmd_Null_f( void );
|
||||
void Rcon_Print( host_redirect_t *rd, const char *pMsg );
|
||||
qboolean COM_ParseVector( char **pfile, float *v, size_t size );
|
||||
void COM_NormalizeAngles( vec3_t angles );
|
||||
int COM_FileSize( const char *filename );
|
||||
void COM_FreeFile( void *buffer );
|
||||
int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare );
|
||||
char *va( const char *format, ... ) _format( 1 );
|
||||
qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multiplayer );
|
||||
|
||||
static inline void COM_NormalizeAngles( vec3_t angles )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( angles[i] > 180.0f )
|
||||
angles[i] -= 360.0f;
|
||||
else if( angles[i] < -180.0f )
|
||||
angles[i] += 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
connprotocol_t CL_Protocol( void );
|
||||
#else
|
||||
static inline connprotocol_t CL_Protocol( void )
|
||||
{
|
||||
return PROTO_CURRENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline qboolean Host_IsLocalGame( void )
|
||||
{
|
||||
if( SV_Active( ))
|
||||
@@ -846,16 +817,6 @@ void NET_MasterClear( void );
|
||||
void NET_MasterShutdown( void );
|
||||
qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat );
|
||||
|
||||
//
|
||||
// munge.c
|
||||
//
|
||||
void COM_Munge( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge( byte *data, size_t len, int seq );
|
||||
void COM_Munge2( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge2( byte *data, size_t len, int seq );
|
||||
void COM_Munge3( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge3( byte *data, size_t len, int seq );
|
||||
|
||||
//
|
||||
// sounds.c
|
||||
//
|
||||
|
||||
@@ -18,6 +18,8 @@ GNU General Public License for more details.
|
||||
#include "const.h"
|
||||
#include "kbutton.h"
|
||||
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
|
||||
typedef struct autocomplete_list_s
|
||||
@@ -1010,7 +1012,7 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
|
||||
return Cmd_CheckMapsList_R( fRefresh, true );
|
||||
}
|
||||
|
||||
static const autocomplete_list_t cmd_list[] =
|
||||
autocomplete_list_t cmd_list[] =
|
||||
{
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "changelevel2", 1, Cmd_GetMapList },
|
||||
@@ -1073,7 +1075,7 @@ for various cmds
|
||||
*/
|
||||
static qboolean Cmd_AutocompleteName( const char *source, int arg, char *buffer, size_t bufsize )
|
||||
{
|
||||
const autocomplete_list_t *list;
|
||||
autocomplete_list_t *list;
|
||||
|
||||
for( list = cmd_list; list->name; list++ )
|
||||
{
|
||||
|
||||
@@ -18,17 +18,17 @@ GNU General Public License for more details.
|
||||
#include "base_cmd.h"
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
static convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
typedef struct cvar_filter_quirks_s
|
||||
{
|
||||
const char *gamedir; // gamedir to enable for
|
||||
const char *cvars; // list of cvars should be excluded from filter
|
||||
} cvar_filter_quirks_t;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
static const cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
static cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
{
|
||||
// EXAMPLE:
|
||||
//{
|
||||
@@ -44,9 +44,9 @@ static const cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
"cl_dodmusic" // Day of Defeat Beta 1.3 cvar
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static const cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
|
||||
static cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
|
||||
#endif
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
|
||||
|
||||
@@ -70,14 +70,15 @@ find the specified variable by name
|
||||
*/
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
||||
{
|
||||
convar_t *var;
|
||||
// TODO: ignore group for cvar
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
return (convar_t *)BaseCmd_Find( HM_CVAR, var_name );
|
||||
#else
|
||||
convar_t *var;
|
||||
|
||||
if( !var_name )
|
||||
return NULL;
|
||||
|
||||
#if defined(XASH_HASHED_VARS) // TODO: ignore_group
|
||||
var = BaseCmd_Find( HM_CVAR, var_name );
|
||||
#else
|
||||
for( var = cvar_vars; var; var = var->next )
|
||||
{
|
||||
if( ignore_group && FBitSet( ignore_group, var->flags ))
|
||||
@@ -86,13 +87,9 @@ convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
||||
if( !Q_stricmp( var_name, var->name ))
|
||||
return var;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// HACKHACK: HL25 compatibility
|
||||
if( !var && !Q_stricmp( var_name, "gl_widescreen_yfov" ))
|
||||
var = Cvar_FindVarExt( "r_adjust_fov", ignore_group );
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -618,7 +615,7 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
return Cvar_Get( var_name, value, FCVAR_USER_CREATED, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if( !Cmd_CurrentCommandIsPrivileged( ))
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_PRIVILEGED ))
|
||||
@@ -974,6 +971,7 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// check if game-specific filter exceptions should be applied
|
||||
// TODO: for cmd exceptions, make generic function
|
||||
if( cvar_active_filter_quirks )
|
||||
@@ -1004,6 +1002,7 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
|
||||
return false;
|
||||
@@ -1258,7 +1257,6 @@ void Cvar_Unlink( int group )
|
||||
pending_cvar_t *Cvar_PrepareToUnlink( int group )
|
||||
{
|
||||
pending_cvar_t *list = NULL;
|
||||
pending_cvar_t *tail = NULL;
|
||||
convar_t *cv;
|
||||
|
||||
for( cv = cvar_vars; cv != NULL; cv = cv->next )
|
||||
@@ -1271,18 +1269,12 @@ pending_cvar_t *Cvar_PrepareToUnlink( int group )
|
||||
|
||||
namelen = Q_strlen( cv->name ) + 1;
|
||||
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
|
||||
p->next = NULL;
|
||||
p->next = list;
|
||||
p->cv_cur = cv;
|
||||
p->cv_next = cv->next;
|
||||
p->cv_allocated = FBitSet( cv->flags, FCVAR_ALLOCATED ) ? true : false;
|
||||
Q_strncpy( p->cv_name, cv->name, namelen );
|
||||
|
||||
if( list == NULL )
|
||||
list = p;
|
||||
else
|
||||
tail->next = p;
|
||||
|
||||
tail = p;
|
||||
list = p;
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
@@ -16,37 +16,12 @@ 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;
|
||||
|
||||
const char *CL_MsgInfo( int cmd )
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
{
|
||||
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 )
|
||||
@@ -159,6 +134,11 @@ void GAME_EXPORT S_StopSound(int entnum, int channel, const char *soundname)
|
||||
|
||||
}
|
||||
|
||||
int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GAME_EXPORT CL_GetMaxClients( void )
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -40,7 +40,7 @@ GNU General Public License for more details.
|
||||
#include "render_api.h" // decallist_t
|
||||
#include "tests.h"
|
||||
|
||||
static pfnChangeGame pChangeGame = NULL;
|
||||
pfnChangeGame pChangeGame = NULL;
|
||||
host_parm_t host; // host parms
|
||||
|
||||
#ifdef XASH_ENGINE_TESTS
|
||||
@@ -49,8 +49,8 @@ struct tests_stats_s tests_stats;
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in development-mode" );
|
||||
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_FILTERABLE, "scale frame time" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", FCVAR_SERVER, "framerate in dedicated mode" );
|
||||
|
||||
static CVAR_DEFINE_AUTO( sys_ticrate, "100", FCVAR_SERVER, "framerate in dedicated mode" );
|
||||
static CVAR_DEFINE_AUTO( host_serverstate, "0", FCVAR_READ_ONLY, "displays current server state" );
|
||||
static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
|
||||
static CVAR_DEFINE_AUTO( host_clientloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
|
||||
@@ -69,14 +69,14 @@ typedef struct feature_message_s
|
||||
const char *arg;
|
||||
} feature_message_t;
|
||||
|
||||
static const feature_message_t bugcomp_features[] =
|
||||
static feature_message_t bugcomp_features[] =
|
||||
{
|
||||
{ BUGCOMP_PENTITYOFENTINDEX_FLAG, "pfnPEntityOfEntIndex bugfix revert", "peoei" },
|
||||
{ BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG, "GoldSrc Message Rewrite Facility", "gsmrf" },
|
||||
{ BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE, "spatialize sounds with zero attenuation", "sp_attn_none" },
|
||||
};
|
||||
|
||||
static const feature_message_t engine_features[] =
|
||||
static feature_message_t engine_features[] =
|
||||
{
|
||||
{ ENGINE_WRITE_LARGE_COORD, "Big World Support" },
|
||||
{ ENGINE_QUAKE_COMPATIBLE, "Quake Compatibility" },
|
||||
@@ -200,6 +200,19 @@ static void Sys_PrintUsage( const char *exename )
|
||||
Sys_Quit();
|
||||
}
|
||||
|
||||
int Host_CompareFileTime( int ft1, int ft2 )
|
||||
{
|
||||
if( ft1 < ft2 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if( ft1 > ft2 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Host_ShutdownServer( void )
|
||||
{
|
||||
SV_Shutdown( "Server was killed\n" );
|
||||
@@ -210,7 +223,7 @@ void Host_ShutdownServer( void )
|
||||
Host_PrintEngineFeatures
|
||||
================
|
||||
*/
|
||||
static void Host_PrintFeatures( uint32_t flags, const char *s, const feature_message_t *features, size_t size )
|
||||
static void Host_PrintFeatures( uint32_t flags, const char *s, feature_message_t *features, size_t size )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -228,8 +241,15 @@ Host_ValidateEngineFeatures
|
||||
validate features bits and set host.features
|
||||
==============
|
||||
*/
|
||||
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features )
|
||||
void Host_ValidateEngineFeatures( uint32_t features )
|
||||
{
|
||||
uint32_t mask = ENGINE_FEATURES_MASK;
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ) && cls.legacymode )
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
#endif
|
||||
|
||||
// don't allow unsupported bits
|
||||
features &= mask;
|
||||
|
||||
@@ -1052,9 +1072,6 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
Host_RunTests( 0 );
|
||||
#endif
|
||||
|
||||
#if XASH_DEDICATED
|
||||
Platform_SetupSigtermHandling();
|
||||
#endif
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
|
||||
FS_Init( basedir );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
{ LUMP_MODELS, 1, MAX_MAP_MODELS, sizeof( dmodel_t ), -1, "models", CHECK_OVERFLOW, (const void **)&srcmodel.submodels, &srcmodel.numsubmodels },
|
||||
};
|
||||
|
||||
static const mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
static mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
{
|
||||
{ LUMP_LIGHTVECS, 0, MAX_MAP_LIGHTING, sizeof( byte ), -1, "deluxmaps", USE_EXTRAHEADER, (const void **)&srcmodel.deluxdata, &srcmodel.deluxdatasize },
|
||||
{ LUMP_FACEINFO, 0, MAX_MAP_FACEINFO, sizeof( dfaceinfo_t ), -1, "faceinfos", CHECK_OVERFLOW|USE_EXTRAHEADER, (const void **)&srcmodel.faceinfo, &srcmodel.numfaceinfo },
|
||||
@@ -347,7 +347,7 @@ Mod_LoadLump
|
||||
generic loader
|
||||
=================
|
||||
*/
|
||||
static void Mod_LoadLump( const byte *in, const mlumpinfo_t *info, mlumpstat_t *stat, int flags )
|
||||
static void Mod_LoadLump( const byte *in, mlumpinfo_t *info, mlumpstat_t *stat, int flags )
|
||||
{
|
||||
int version = ((dheader_t *)in)->version;
|
||||
size_t numelems, real_entrysize;
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
munge.c - protocol mangling for GoldSrc
|
||||
Copyright (C) ReHLDS developers
|
||||
Copyright (C) 2023 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 "common.h"
|
||||
|
||||
static const byte mungify_table[] =
|
||||
{
|
||||
0x7A, 0x64, 0x05, 0xF1, 0x1B, 0x9B, 0xA0, 0xB5,
|
||||
0xCA, 0xED, 0x61, 0x0D, 0x4A, 0xDF, 0x8E, 0xC7,
|
||||
};
|
||||
|
||||
static const byte mungify_table2[] =
|
||||
{
|
||||
0x05, 0x61, 0x7A, 0xED, 0x1B, 0xCA, 0x0D, 0x9B,
|
||||
0x4A, 0xF1, 0x64, 0xC7, 0xB5, 0x8E, 0xDF, 0xA0,
|
||||
};
|
||||
|
||||
static const byte mungify_table3[] =
|
||||
{
|
||||
0x20, 0x07, 0x13, 0x61, 0x03, 0x45, 0x17, 0x72,
|
||||
0x0A, 0x2D, 0x48, 0x0C, 0x4A, 0x12, 0xA9, 0xB5,
|
||||
};
|
||||
|
||||
static uint COM_SwapLong( uint c )
|
||||
{
|
||||
return ((( c >> 0 ) & 0xFF) << 24 ) +
|
||||
((( c >> 8 ) & 0xFF) << 16 ) +
|
||||
((( c >> 16 ) & 0xFF) << 8 ) +
|
||||
((( c >> 24 ) & 0xFF) << 0 );
|
||||
}
|
||||
|
||||
static void COM_GenericMunge( byte *data, const size_t len, const int seq, const byte *table, const qboolean reverse )
|
||||
{
|
||||
const size_t mungelen = len / 4;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < mungelen; i++ )
|
||||
{
|
||||
uint32_t c;
|
||||
void *pc = &data[i * 4];
|
||||
byte *p;
|
||||
int j;
|
||||
|
||||
memcpy( &c, pc, sizeof( c ));
|
||||
c ^= seq;
|
||||
if( !reverse )
|
||||
c = COM_SwapLong( c );
|
||||
|
||||
p = (byte *)&c;
|
||||
for( j = 0; j < 4; j++ )
|
||||
*p++ ^= (0xa5 | (j << j) | j | table[(i + j) & 0x0f]);
|
||||
|
||||
if( reverse )
|
||||
c = COM_SwapLong( c );
|
||||
c ^= ~seq;
|
||||
memcpy( pc, &c, sizeof( c ));
|
||||
}
|
||||
}
|
||||
|
||||
// Anti-proxy/aimbot obfuscation code
|
||||
// COM_UnMunge should reversably fixup the data
|
||||
void COM_Munge( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table, true );
|
||||
}
|
||||
|
||||
void COM_Munge2( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table2, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge2( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table2, true );
|
||||
}
|
||||
|
||||
void COM_Munge3( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table3, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge3( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table3, true );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
void Test_RunMunge( void )
|
||||
{
|
||||
const char *msg = "0123456789qwertyuiopasdfghjklzxcvbnmaa";
|
||||
const char *expected[][3] =
|
||||
{
|
||||
{
|
||||
"\x33\x2a\x61\x30\x2d\x6e\x35\x74\x2d\x79\x79\x78\x73\x34\x32\x25\x30\x2f\x39\x35\x26\x3c\x33\x61\x31\x22\x78\x67\x29\x68\x6a\x6c\x7d\x7e\x72\x36\x61\x61",
|
||||
"\x69\x2a\x31\x30\x2d\x36\x25\x74\x77\x61\x79\x38\x6b\x34\x62\x25\x30\x7f\x39\x35\x76\x34\x33\x61\x39\x2a\x78\x67\x23\x68\x7a\x6c\x7d\x66\x72\x76\x61\x61",
|
||||
"\x69\x6a\x71\x30\x6f\x7e\x25\x74\x3f\x69\x69\x38\x63\x2c\x62\x25\x28\x77\x29\x75\x7c\x2c\x73\x21\x23\x62\x38\x27\x6b\x28\x2a\x6c\x3d\x3e\x72\x36\x61\x61",
|
||||
}, {
|
||||
"\x32\x2a\x61\x31\x2c\x6e\x35\x75\x2c\x79\x79\x79\x72\x34\x32\x24\x31\x2f\x39\x34\x27\x3c\x33\x60\x30\x22\x78\x66\x28\x68\x6a\x6d\x7c\x7e\x72\x37\x61\x61",
|
||||
"\x68\x2a\x31\x31\x2c\x36\x25\x75\x76\x61\x79\x39\x6a\x34\x62\x24\x31\x7f\x39\x34\x77\x34\x33\x60\x38\x2a\x78\x66\x22\x68\x7a\x6d\x7c\x66\x72\x77\x61\x61",
|
||||
"\x68\x6a\x71\x31\x6e\x7e\x25\x75\x3e\x69\x69\x39\x62\x2c\x62\x24\x29\x77\x29\x74\x7d\x2c\x73\x20\x22\x62\x38\x26\x6a\x28\x2a\x6d\x3c\x3e\x72\x37\x61\x61",
|
||||
}
|
||||
};
|
||||
string buf;
|
||||
size_t msglen = Q_strlen( msg ) + 1;
|
||||
int i;
|
||||
|
||||
Q_strncpy( buf, msg, msglen );
|
||||
|
||||
for( i = 0; i < 0xFF; i++ )
|
||||
{
|
||||
COM_Munge( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
//for( int j = 0; j < msglen; j++ )
|
||||
// printf( "\\x%02x", buf[j] );
|
||||
//printf( "\n" );
|
||||
TASSERT( !memcmp( buf, expected[i][0], msglen ));
|
||||
}
|
||||
COM_UnMunge( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
|
||||
COM_Munge2( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
TASSERT( !memcmp( buf, expected[i][1], msglen ));
|
||||
}
|
||||
COM_UnMunge2( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
|
||||
COM_Munge3( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
TASSERT( !memcmp( buf, expected[i][2], msglen ));
|
||||
}
|
||||
COM_UnMunge3( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -17,13 +17,15 @@ GNU General Public License for more details.
|
||||
#include "protocol.h"
|
||||
#include "net_buffer.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
//#define DEBUG_NET_MESSAGES_SEND
|
||||
//#define DEBUG_NET_MESSAGES_READ
|
||||
|
||||
// precalculated bit masks for WriteUBitLong.
|
||||
// Using these tables instead of doing the calculations
|
||||
// gives a 33% speedup in WriteUBitLong.
|
||||
static uint32_t BitWriteMasks[32][33];
|
||||
static uint32_t ExtraMasks[32];
|
||||
const char *const svc_strings[svc_lastmsg+1] =
|
||||
const char *svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
@@ -79,7 +81,7 @@ const char *const svc_strings[svc_lastmsg+1] =
|
||||
"svc_director",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_unused54",
|
||||
"svc_deltapacketbones",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
@@ -87,7 +89,7 @@ const char *const svc_strings[svc_lastmsg+1] =
|
||||
"svc_exec",
|
||||
};
|
||||
|
||||
const char *const svc_legacy_strings[svc_lastmsg+1] =
|
||||
const char *svc_legacy_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_legacy_changing] = "svc_legacy_changing",
|
||||
[svc_legacy_ambientsound] = "svc_legacy_ambientsound",
|
||||
@@ -98,7 +100,7 @@ const char *const svc_legacy_strings[svc_lastmsg+1] =
|
||||
[svc_legacy_chokecount] = "svc_legacy_chokecount",
|
||||
};
|
||||
|
||||
const char *const svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
const char *svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_goldsrc_version] = "svc_goldsrc_version",
|
||||
[svc_goldsrc_serverinfo] = "svc_goldsrc_serverinfo",
|
||||
@@ -117,7 +119,7 @@ const char *const svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
[svc_goldsrc_sendcvarvalue2] = "svc_goldsrc_sendcvarvalue2",
|
||||
};
|
||||
|
||||
const char *const svc_quake_strings[svc_lastmsg+1] =
|
||||
const char *svc_quake_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_updatestat] = "svc_quake_updatestat",
|
||||
[svc_version] = "svc_quake_version",
|
||||
@@ -211,23 +213,17 @@ void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits )
|
||||
// do we have a valid # of bits to encode with?
|
||||
Assert( numbits >= 1 && numbits <= 32 );
|
||||
|
||||
if( sb->iAlternateSign )
|
||||
// NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
if( data < 0 )
|
||||
{
|
||||
MSG_WriteOneBit( sb, data < 0 ? 1 : 0 );
|
||||
MSG_WriteUBitLong( sb, (uint)abs( data ), numbits - 1 );
|
||||
MSG_WriteUBitLong( sb, (uint)( 0x80000000 + data ), numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( data < 0 )
|
||||
{
|
||||
MSG_WriteUBitLong( sb, (uint)( 0x80000000 + data ), numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteUBitLong( sb, (uint)data, numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 0 );
|
||||
}
|
||||
MSG_WriteUBitLong( sb, (uint)data, numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,30 +317,28 @@ void MSG_WriteVec3Angles( sizebuf_t *sb, const float *fa )
|
||||
|
||||
void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
|
||||
{
|
||||
if( unlikely( net_send_debug.value ))
|
||||
#ifdef DEBUG_NET_MESSAGES_SEND
|
||||
if( name != NULL )
|
||||
{
|
||||
if( name != NULL )
|
||||
// get custom name
|
||||
Con_Printf( "^1sv^7 write: %s\n", name );
|
||||
}
|
||||
else if( type == NS_SERVER )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get custom name
|
||||
Con_Printf( "^1sv^7 (%d) write: %s\n", sb->iCurBit, name );
|
||||
}
|
||||
else if( type == NS_SERVER )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
Con_Printf( "^1sv^7 (%d) write: %s\n", sb->iCurBit, svc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
else if( type == NS_CLIENT )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg && cmd != clc_nop )
|
||||
{
|
||||
Con_Printf( "^1cl^7 (%d) write: %s\n", sb->iCurBit, clc_strings[cmd] );
|
||||
}
|
||||
// get engine message name
|
||||
Con_Printf( "^1sv^7 write: %s\n", svc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
|
||||
else if( type == NS_CLIENT )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1cl^7 write: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
MSG_WriteUBitLong( sb, cmd, sizeof( uint8_t ) << 3 );
|
||||
}
|
||||
|
||||
@@ -539,22 +533,12 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
|
||||
{
|
||||
int r, sign;
|
||||
|
||||
if( sb->iAlternateSign )
|
||||
{
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
|
||||
if( sign )
|
||||
r = -r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
|
||||
if( sign )
|
||||
r = -( BIT( numbits - 1 ) - r );
|
||||
}
|
||||
// NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
if( sign ) r = -( BIT( numbits - 1 ) - r );
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -570,31 +554,22 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
|
||||
{
|
||||
int cmd = MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
|
||||
|
||||
if( unlikely( net_recv_debug.value ))
|
||||
#ifdef DEBUG_NET_MESSAGES_READ
|
||||
if( type == NS_SERVER )
|
||||
{
|
||||
if( type == NS_SERVER )
|
||||
{
|
||||
if( cmd != svc_nop )
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
}
|
||||
else if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1sv^7 read: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
}
|
||||
|
||||
else if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1sv^7 read: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
#endif
|
||||
return cmd;
|
||||
}
|
||||
|
||||
int MSG_ReadChar( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
|
||||
}
|
||||
|
||||
int MSG_ReadByte( sizebuf_t *sb )
|
||||
@@ -604,13 +579,7 @@ int MSG_ReadByte( sizebuf_t *sb )
|
||||
|
||||
int MSG_ReadShort( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
|
||||
}
|
||||
|
||||
int MSG_ReadWord( sizebuf_t *sb )
|
||||
@@ -642,13 +611,7 @@ void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa )
|
||||
|
||||
int MSG_ReadLong( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
|
||||
}
|
||||
|
||||
uint MSG_ReadDword( sizebuf_t *sb )
|
||||
|
||||
@@ -42,9 +42,6 @@ struct sizebuf_s
|
||||
int iCurBit;
|
||||
int nDataBits;
|
||||
const char *pDebugName; // buffer name (pointer to const name)
|
||||
|
||||
// to support GoldSrc broken signed integers
|
||||
int iAlternateSign;
|
||||
};
|
||||
|
||||
#define MSG_StartReading MSG_StartWriting
|
||||
@@ -74,7 +71,6 @@ static inline void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pDa
|
||||
sb->nDataBits = nBits;
|
||||
|
||||
sb->pDebugName = pDebugName;
|
||||
sb->iAlternateSign = 0;
|
||||
}
|
||||
|
||||
static inline void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
@@ -173,26 +169,6 @@ static inline qboolean MSG_Overflow( sizebuf_t *sb, int nBits )
|
||||
return sb->bOverflow;
|
||||
}
|
||||
|
||||
static inline void MSG_EndBitWriting( sizebuf_t *sb )
|
||||
{
|
||||
sb->iAlternateSign--;
|
||||
|
||||
if( sb->iAlternateSign < 0 )
|
||||
{
|
||||
Con_Printf( "%s: non-even MSG_Start/EndBitWriting\n", __func__ );
|
||||
sb->iAlternateSign = 0;
|
||||
}
|
||||
|
||||
// we have native bit ops here, just pad to closest byte
|
||||
if(( sb->iCurBit & 7 ) != 0 )
|
||||
MSG_SeekToBit( sb, 8 - ( sb->iCurBit & 7 ), SEEK_CUR );
|
||||
}
|
||||
|
||||
static inline void MSG_StartBitWriting( sizebuf_t *sb )
|
||||
{
|
||||
sb->iAlternateSign++;
|
||||
}
|
||||
|
||||
void MSG_InitMasks( void ); // called once at startup engine
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "net_encode.h"
|
||||
#include "protocol.h"
|
||||
#if !XASH_DEDICATED
|
||||
#include <bzlib.h>
|
||||
#endif // !XASH_DEDICATED
|
||||
|
||||
#define MAKE_FRAGID( id, count ) ((( id & 0xffff ) << 16 ) | ( count & 0xffff ))
|
||||
#define FRAG_GETID( fragid ) (( fragid >> 16 ) & 0xffff )
|
||||
@@ -87,12 +84,10 @@ such as during the connection stage while waiting for the client to load,
|
||||
then a packet only needs to be delivered if there is something in the
|
||||
unacknowledged reliable
|
||||
*/
|
||||
CVAR_DEFINE_AUTO( net_showpackets, "0", FCVAR_PRIVILEGED, "show network packets" );
|
||||
CVAR_DEFINE_AUTO( net_showpackets, "0", 0, "show network packets" );
|
||||
static CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
|
||||
static CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
|
||||
static CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
|
||||
CVAR_DEFINE_AUTO( net_send_debug, "0", FCVAR_PRIVILEGED, "enable debugging output for outgoing messages" );
|
||||
CVAR_DEFINE_AUTO( net_recv_debug, "0", FCVAR_PRIVILEGED, "enable debugging output for incoming messages" );
|
||||
|
||||
int net_drop;
|
||||
netadr_t net_from;
|
||||
@@ -100,58 +95,12 @@ sizebuf_t net_message;
|
||||
static poolhandle_t net_mempool;
|
||||
byte net_message_buffer[NET_MAX_MESSAGE];
|
||||
|
||||
static const char *const ns_strings[NS_COUNT] =
|
||||
const char *ns_strings[NS_COUNT] =
|
||||
{
|
||||
"Client",
|
||||
"Server",
|
||||
};
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
void bz_internal_error( int errcode );
|
||||
void bz_internal_error( int errcode )
|
||||
{
|
||||
Con_Printf( S_ERROR "bzip2/libbzip2: internal error number %d.\n"
|
||||
"This is a bug in bzip2/libbzip2, %s.\n"
|
||||
"Please report it at: https://gitlab.com/bzip2/bzip2/-/issues\n"
|
||||
"If this happened when you were using some program which uses\n"
|
||||
"libbzip2 as a component, you should also report this bug to\n"
|
||||
"the author(s) of that program.\n"
|
||||
"Please make an effort to report this bug;\n"
|
||||
"timely and accurate bug reports eventually lead to higher\n"
|
||||
"quality software. Thanks.\n\n",
|
||||
errcode, BZ2_bzlibVersion( ));
|
||||
|
||||
if (errcode == 1007) {
|
||||
Con_Printf(
|
||||
"\n*** A special note about internal error number 1007 ***\n"
|
||||
"\n"
|
||||
"Experience suggests that a common cause of i.e. 1007\n"
|
||||
"is unreliable memory or other hardware. The 1007 assertion\n"
|
||||
"just happens to cross-check the results of huge numbers of\n"
|
||||
"memory reads/writes, and so acts (unintendedly) as a stress\n"
|
||||
"test of your memory system.\n"
|
||||
"\n"
|
||||
"I suggest the following: try compressing the file again,\n"
|
||||
"possibly monitoring progress in detail with the -vv flag.\n"
|
||||
"\n"
|
||||
"* If the error cannot be reproduced, and/or happens at different\n"
|
||||
" points in compression, you may have a flaky memory system.\n"
|
||||
" Try a memory-test program. I have used Memtest86\n"
|
||||
" (www.memtest86.com). At the time of writing it is free (GPLd).\n"
|
||||
" Memtest86 tests memory much more thorougly than your BIOSs\n"
|
||||
" power-on test, and may find failures that the BIOS doesn't.\n"
|
||||
"\n"
|
||||
"* If the error can be repeatably reproduced, this is a bug in\n"
|
||||
" bzip2, and I would very much like to hear about it. Please\n"
|
||||
" let me know, and, ideally, save a copy of the file causing the\n"
|
||||
" problem -- without which I will be unable to investigate it.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
Sys_Error( "bzip2/libbzip2: internal error number %d\n", errcode );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
/*
|
||||
=================================
|
||||
@@ -267,8 +216,6 @@ void Netchan_Init( void )
|
||||
Cvar_RegisterVariable( &net_chokeloop );
|
||||
Cvar_RegisterVariable( &net_showdrop );
|
||||
Cvar_RegisterVariable( &net_qport );
|
||||
Cvar_RegisterVariable( &net_send_debug );
|
||||
Cvar_RegisterVariable( &net_recv_debug );
|
||||
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
|
||||
|
||||
net_mempool = Mem_AllocPool( "Network Pool" );
|
||||
@@ -318,18 +265,12 @@ Netchan_Setup
|
||||
called to open a channel to a remote system
|
||||
==============
|
||||
*/
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ), uint flags )
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ))
|
||||
{
|
||||
Netchan_Clear( chan );
|
||||
|
||||
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;
|
||||
@@ -340,10 +281,6 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, voi
|
||||
chan->qport = qport;
|
||||
chan->client = client;
|
||||
chan->pfnBlockSize = pfnBlockSize;
|
||||
chan->split = FBitSet( flags, NETCHAN_USE_LEGACY_SPLIT ) ? true : false;
|
||||
chan->use_munge = FBitSet( flags, NETCHAN_USE_MUNGE ) ? true : false;
|
||||
chan->use_bz2 = FBitSet( flags, NETCHAN_USE_BZIP2 ) ? true : false;
|
||||
chan->gs_netchan = FBitSet( flags, NETCHAN_GOLDSRC ) ? true : false;
|
||||
|
||||
MSG_Init( &chan->message, "NetData", chan->message_buf, sizeof( chan->message_buf ));
|
||||
}
|
||||
@@ -520,7 +457,7 @@ Netchan_OutOfBand
|
||||
Sends an out-of-band datagram
|
||||
================
|
||||
*/
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int len, const byte *data )
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int len, byte *data )
|
||||
{
|
||||
byte buf[MAX_PRINT_MSG + 4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
@@ -744,39 +681,21 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
||||
if( MSG_GetNumBytesWritten( msg ) == 0 )
|
||||
return;
|
||||
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t ));
|
||||
|
||||
if( chan->use_bz2 && memcmp( MSG_GetData( msg ), "BZ2", 4 ))
|
||||
if( !LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte pbOut[0x10000];
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
uint uCompressedSize = MSG_GetNumBytesWritten( msg ) - 4;
|
||||
if( !BZ2_bzBuffToBuffCompress( pbOut, &uCompressedSize, MSG_GetData( msg ), uSourceSize, 9, 0, 30 ))
|
||||
{
|
||||
if( uCompressedSize < uSourceSize )
|
||||
{
|
||||
Con_Reportf( "Compressing split packet with BZip2 (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
memcpy( msg->pData, "BZ2", 4 );
|
||||
memcpy( msg->pData + 4, pbOut, uCompressedSize );
|
||||
MSG_SeekToBit( msg, uCompressedSize << 3, SEEK_SET );
|
||||
}
|
||||
}
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( !chan->use_bz2 && !LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
uint uCompressedSize = 0;
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
byte *pbOut = LZSS_Compress( msg->pData, uSourceSize, &uCompressedSize );
|
||||
uint uCompressedSize = 0;
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
byte *pbOut = LZSS_Compress( msg->pData, uSourceSize, &uCompressedSize );
|
||||
|
||||
if( pbOut && uCompressedSize > 0 && uCompressedSize < uSourceSize )
|
||||
{
|
||||
Con_Reportf( "Compressing split packet with LZSS (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
Con_Reportf( "Compressing split packet (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
memcpy( msg->pData, pbOut, uCompressedSize );
|
||||
MSG_SeekToBit( msg, uCompressedSize << 3, SEEK_SET );
|
||||
}
|
||||
@@ -923,7 +842,9 @@ void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filenam
|
||||
|
||||
if( !size ) return;
|
||||
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
if( !LZSS_IsCompressed( pbuf ))
|
||||
{
|
||||
@@ -1019,14 +940,16 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
Con_Printf( S_WARN "Unable to transfer %s due to path length overflow\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(( filesize = FS_FileSize( filename, false )) <= 0 )
|
||||
{
|
||||
Con_Printf( S_WARN "Unable to open %s for transfer\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", filename );
|
||||
compressedFileTime = FS_FileTime( compressedfilename, false );
|
||||
@@ -1175,20 +1098,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
|
||||
p = n;
|
||||
}
|
||||
|
||||
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ) )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte buf[0x10000];
|
||||
uint uDecompressedLen = sizeof( buf );
|
||||
|
||||
BZ2_bzBuffToBuffDecompress( buf, &uDecompressedLen, MSG_GetData( msg ) + 4, MSG_GetNumBytesWritten( msg ) - 4, 1, 0 );
|
||||
memcpy( msg->pData, buf, uDecompressedLen );
|
||||
size = uDecompressedLen;
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( !chan->use_bz2 && LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
if( LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
uint uDecompressedLen = LZSS_GetActualSize( MSG_GetData( msg ));
|
||||
byte buf[NET_MAX_MESSAGE];
|
||||
@@ -1225,8 +1135,7 @@ Netchan_CopyFileFragments
|
||||
*/
|
||||
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
{
|
||||
char filename[MAX_OSPATH], compressor[32];
|
||||
uint uncompressedSize;
|
||||
char filename[MAX_OSPATH];
|
||||
int nsize, pos;
|
||||
byte *buffer;
|
||||
fragbuf_t *p, *n;
|
||||
@@ -1249,12 +1158,6 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
MSG_Clear( msg );
|
||||
|
||||
Q_strncpy( filename, MSG_ReadString( msg ), sizeof( filename ));
|
||||
compressor[0] = 0;
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
Q_strncpy( compressor, MSG_ReadString( msg ), sizeof( compressor ));
|
||||
uncompressedSize = MSG_ReadLong( msg );
|
||||
}
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
@@ -1325,26 +1228,10 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
p = n;
|
||||
}
|
||||
|
||||
if( chan->gs_netchan && chan->use_bz2 && !Q_stricmp( compressor, "bz2" ))
|
||||
if( LZSS_IsCompressed( buffer ))
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte *uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
|
||||
Con_DPrintf( "Decompressing file %s (%d -> %d bytes)\n", filename, nsize, uncompressedSize );
|
||||
BZ2_bzBuffToBuffDecompress( uncompressedBuffer, &uncompressedSize, buffer, nsize, 1, 0 );
|
||||
Mem_Free( buffer );
|
||||
nsize = uncompressedSize;
|
||||
buffer = uncompressedBuffer;
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( LZSS_IsCompressed( buffer ))
|
||||
{
|
||||
byte *uncompressedBuffer;
|
||||
|
||||
uncompressedSize = LZSS_GetActualSize( buffer ) + 1;
|
||||
uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
uint uncompressedSize = LZSS_GetActualSize( buffer ) + 1;
|
||||
byte *uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
|
||||
nsize = LZSS_Decompress( buffer, uncompressedBuffer );
|
||||
Mem_Free( buffer );
|
||||
@@ -1504,7 +1391,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, const byte *data )
|
||||
void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
{
|
||||
byte send_buf[NET_MAX_MESSAGE];
|
||||
qboolean send_reliable_fragment;
|
||||
@@ -1521,9 +1408,6 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
return;
|
||||
}
|
||||
|
||||
if( chan->pfnBlockSize == NULL ) // not initialized
|
||||
return;
|
||||
|
||||
// if the remote side dropped the last reliable message, resend it
|
||||
send_reliable = false;
|
||||
|
||||
@@ -1562,9 +1446,12 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
// stall reliable payloads if sending from frag buffer
|
||||
if( send_from_regular && ( send_from_frag[FRAG_NORMAL_STREAM] ))
|
||||
{
|
||||
int maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
int maxsize = MAX_RELIABLE_PAYLOAD;
|
||||
send_from_regular = false;
|
||||
|
||||
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
if( maxsize == 0 )
|
||||
maxsize = MAX_RELIABLE_PAYLOAD;
|
||||
|
||||
@@ -1706,7 +1593,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
MSG_WriteLong( &send, w2 );
|
||||
|
||||
// send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT && !chan->gs_netchan )
|
||||
if( chan->sock == NS_CLIENT )
|
||||
{
|
||||
MSG_WriteWord( &send, (int)net_qport.value );
|
||||
}
|
||||
@@ -1719,16 +1606,8 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
{
|
||||
MSG_WriteByte( &send, 1 );
|
||||
MSG_WriteLong( &send, chan->reliable_fragid[i] );
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
MSG_WriteShort( &send, chan->frag_startpos[i] >> 3 );
|
||||
MSG_WriteShort( &send, chan->frag_length[i] >> 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteLong( &send, chan->frag_startpos[i] );
|
||||
MSG_WriteLong( &send, chan->frag_length[i] );
|
||||
}
|
||||
MSG_WriteLong( &send, chan->frag_startpos[i] );
|
||||
MSG_WriteLong( &send, chan->frag_length[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1746,7 +1625,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
|
||||
if( length )
|
||||
{
|
||||
int maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_UNRELIABLE );
|
||||
int maxsize = NET_MAX_MESSAGE;
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_UNRELIABLE );
|
||||
|
||||
if( (( MSG_GetNumBytesWritten( &send ) + length ) >> 3) <= maxsize )
|
||||
MSG_WriteBits( &send, data, length );
|
||||
@@ -1780,11 +1661,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, const byte *data )
|
||||
// send the datagram
|
||||
if( !CL_IsPlaybackDemo( ))
|
||||
{
|
||||
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 ));
|
||||
|
||||
int splitsize = 0;
|
||||
if( chan->pfnBlockSize )
|
||||
splitsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
NET_SendPacketEx( chan->sock, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), chan->remote_address, splitsize );
|
||||
}
|
||||
|
||||
@@ -1833,9 +1712,6 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
sequence = MSG_ReadLong( msg );
|
||||
sequence_ack = MSG_ReadLong( msg );
|
||||
|
||||
if( chan->use_munge )
|
||||
COM_UnMunge2( msg->pData + 8, ( msg->nDataBits >> 3 ) - 8, sequence & 0xFF );
|
||||
|
||||
// read the qport if we are a server
|
||||
if( chan->sock == NS_SERVER )
|
||||
qport = MSG_ReadShort( msg );
|
||||
@@ -1853,16 +1729,8 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
{
|
||||
frag_message[i] = true;
|
||||
fragid[i] = MSG_ReadLong( msg );
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
frag_offset[i] = MSG_ReadShort( msg ) << 3;
|
||||
frag_length[i] = MSG_ReadShort( msg ) << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
frag_offset[i] = MSG_ReadLong( msg );
|
||||
frag_length[i] = MSG_ReadLong( msg );
|
||||
}
|
||||
frag_offset[i] = MSG_ReadLong( msg );
|
||||
frag_length[i] = MSG_ReadLong( msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ GNU General Public License for more details.
|
||||
#define DT_TIMEWINDOW_BIG BIT( 6 ) // and re-encoded on the client relative to the client's clock
|
||||
#define DT_STRING BIT( 7 ) // A null terminated string, sent as 8 byte chars
|
||||
#define DT_SIGNED BIT( 8 ) // sign modificator
|
||||
#define DT_SIGNED_GS BIT( 31 ) // GoldSrc-specific sign modificator
|
||||
|
||||
#define NUM_FIELDS( x ) ((sizeof( x ) / sizeof( x[0] )) - 1)
|
||||
|
||||
@@ -48,7 +47,6 @@ GNU General Public License for more details.
|
||||
#define PHYS_DEF( x ) #x, offsetof( movevars_t, x ), sizeof( ((movevars_t *)0)->x )
|
||||
#define CLDT_DEF( x ) #x, offsetof( clientdata_t, x ), sizeof( ((clientdata_t *)0)->x )
|
||||
#define WPDT_DEF( x ) #x, offsetof( weapon_data_t, x ), sizeof( ((weapon_data_t *)0)->x )
|
||||
#define DESC_DEF( x ) #x, offsetof( goldsrc_delta_t, x ), sizeof( ((goldsrc_delta_t *)0)->x )
|
||||
|
||||
static qboolean delta_init = false;
|
||||
|
||||
@@ -317,18 +315,6 @@ static const delta_field_t ent_fields[] =
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const delta_field_t meta_fields[] =
|
||||
{
|
||||
{ DESC_DEF( fieldType ), },
|
||||
{ DESC_DEF( fieldName ), },
|
||||
{ DESC_DEF( fieldOffset ), },
|
||||
{ DESC_DEF( fieldSize ), },
|
||||
{ DESC_DEF( significant_bits ), },
|
||||
{ DESC_DEF( premultiply ), },
|
||||
{ DESC_DEF( postmultiply ), },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
typedef struct delta_test_struct_t
|
||||
{
|
||||
@@ -366,6 +352,22 @@ static const delta_field_t test_fields[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
DT_EVENT_T = 0,
|
||||
DT_MOVEVARS_T,
|
||||
DT_USERCMD_T,
|
||||
DT_CLIENTDATA_T,
|
||||
DT_WEAPONDATA_T,
|
||||
DT_ENTITY_STATE_T,
|
||||
DT_ENTITY_STATE_PLAYER_T,
|
||||
DT_CUSTOM_ENTITY_STATE_T,
|
||||
#if XASH_ENGINE_TESTS
|
||||
DT_DELTA_TEST_STRUCT_T,
|
||||
#endif
|
||||
DT_STRUCT_COUNT
|
||||
};
|
||||
|
||||
static delta_info_t dt_info[] =
|
||||
{
|
||||
[DT_EVENT_T] = { "event_t", ev_fields, NUM_FIELDS( ev_fields ) },
|
||||
@@ -373,7 +375,7 @@ static delta_info_t dt_info[] =
|
||||
[DT_USERCMD_T] = { "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) },
|
||||
[DT_CLIENTDATA_T] = { "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) },
|
||||
[DT_WEAPONDATA_T] = { "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) },
|
||||
[DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_ENTITY_STATE_PLAYER_T] = { "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_CUSTOM_ENTITY_STATE_T] = { "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
#if XASH_ENGINE_TESTS
|
||||
@@ -382,68 +384,6 @@ static delta_info_t dt_info[] =
|
||||
[DT_STRUCT_COUNT] = { NULL },
|
||||
};
|
||||
|
||||
// meta description is special, it cannot be overriden
|
||||
static const delta_info_t dt_goldsrc_meta =
|
||||
{
|
||||
.pName = "goldsrc_delta_t",
|
||||
.pInfo = meta_fields,
|
||||
.maxFields = NUM_FIELDS( meta_fields ),
|
||||
.numFields = NUM_FIELDS( meta_fields ),
|
||||
.pFields = (delta_t[NUM_FIELDS( meta_fields )])
|
||||
{
|
||||
{
|
||||
DESC_DEF( fieldType ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldName ),
|
||||
.flags = DT_STRING,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 1,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldOffset ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 16,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldSize ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 8,
|
||||
},
|
||||
{
|
||||
DESC_DEF( significant_bits ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 8,
|
||||
},
|
||||
{
|
||||
DESC_DEF( premultiply ),
|
||||
.flags = DT_FLOAT,
|
||||
.multiplier = 4000.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
{
|
||||
DESC_DEF( postmultiply ),
|
||||
.flags = DT_FLOAT,
|
||||
.multiplier = 4000.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
},
|
||||
.bInitialized = true
|
||||
};
|
||||
|
||||
static delta_info_t *Delta_FindStruct( const char *name )
|
||||
{
|
||||
int i;
|
||||
@@ -553,7 +493,7 @@ static qboolean Delta_AddField( delta_info_t *dt, const char *pName, int flags,
|
||||
int i;
|
||||
|
||||
// check for coexisting field
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields && pField; i++, pField++ )
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
if( !Q_strcmp( pField->name, pName ))
|
||||
{
|
||||
@@ -1226,7 +1166,7 @@ write fields by offsets
|
||||
assume from and to is valid
|
||||
=====================
|
||||
*/
|
||||
static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
|
||||
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
|
||||
{
|
||||
int signbit = FBitSet( pField->flags, DT_SIGNED ) ? 1 : 0;
|
||||
float flValue, flAngle;
|
||||
@@ -1234,6 +1174,14 @@ static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from
|
||||
int dt;
|
||||
const char *pStr;
|
||||
|
||||
if( Delta_CompareField( pField, from, to ))
|
||||
{
|
||||
MSG_WriteOneBit( msg, 0 ); // unchanged
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_WriteOneBit( msg, 1 ); // changed
|
||||
|
||||
if( pField->flags & DT_BYTE )
|
||||
{
|
||||
if( signbit )
|
||||
@@ -1307,20 +1255,6 @@ static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from
|
||||
pStr = (char *)((byte *)to + pField->offset );
|
||||
MSG_WriteString( msg, pStr );
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
|
||||
{
|
||||
if( Delta_CompareField( pField, from, to ))
|
||||
{
|
||||
MSG_WriteOneBit( msg, 0 ); // unchanged
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_WriteOneBit( msg, 1 ); // changed
|
||||
|
||||
Delta_WriteField_( msg, pField, from, to, timebase );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1379,7 +1313,7 @@ read fields by offsets
|
||||
assume 'from' and 'to' is valid
|
||||
=====================
|
||||
*/
|
||||
static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double timebase )
|
||||
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, const void *from, void *to, double timebase )
|
||||
{
|
||||
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
|
||||
float flValue, flAngle, flTime;
|
||||
@@ -1387,6 +1321,12 @@ static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double
|
||||
const char *pStr;
|
||||
char *pOut;
|
||||
|
||||
if( !MSG_ReadOneBit( msg ) )
|
||||
{
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert( pField->multiplier != 0.0f );
|
||||
|
||||
if( pField->flags & DT_BYTE )
|
||||
@@ -1470,85 +1410,9 @@ static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double
|
||||
pOut = (char *)((byte *)to + pField->offset );
|
||||
Q_strncpy( pOut, pStr, pField->size );
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, const void *from, void *to, double timebase )
|
||||
{
|
||||
if( !MSG_ReadOneBit( msg ))
|
||||
{
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
return false;
|
||||
}
|
||||
|
||||
Delta_ReadField_( msg, pField, to, timebase );
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Delta_ParseGSFields( sizebuf_t *msg, const delta_info_t *dt, const void *from, void *to, double timebase )
|
||||
{
|
||||
uint8_t bits[8] = { 0 };
|
||||
delta_t *pField;
|
||||
byte c;
|
||||
int i;
|
||||
|
||||
c = MSG_ReadUBitLong( msg, 3 );
|
||||
|
||||
for( i = 0; i < c; i++ )
|
||||
bits[i] = MSG_ReadByte( msg );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
if( FBitSet( bits[b], n ))
|
||||
Delta_ReadField_( msg, pField, to, timebase );
|
||||
else Delta_CopyField( pField, from, to, timebase );
|
||||
}
|
||||
}
|
||||
|
||||
void Delta_ReadGSFields( sizebuf_t *msg, int index, const void *from, void *to, double timebase )
|
||||
{
|
||||
const delta_info_t *dt = Delta_FindStructByIndex( index );
|
||||
Delta_ParseGSFields( msg, dt, from, to, timebase );
|
||||
}
|
||||
|
||||
void Delta_WriteGSFields( sizebuf_t *msg, int index, const void *from, const void *to, double timebase )
|
||||
{
|
||||
delta_info_t *dt = Delta_FindStructByIndex( index );
|
||||
delta_t *pField;
|
||||
uint8_t bits[8] = { 0 };
|
||||
uint c = 0;
|
||||
int i;
|
||||
|
||||
Delta_CustomEncode( dt, from, to );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
if( !Delta_CompareField( pField, from, to ))
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
SetBits( bits[b], n );
|
||||
c = b + 1;
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteUBitLong( msg, c, 3 );
|
||||
for( i = 0; i < c; i++ )
|
||||
MSG_WriteByte( msg, bits[i] );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
if( FBitSet( bits[b], n ))
|
||||
Delta_WriteField_( msg, pField, from, to, timebase );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
@@ -2018,10 +1882,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
int baseline_offset = 0;
|
||||
|
||||
if( number < 0 || number >= clgame.maxEntities )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: bad delta entity number: %i\n", __func__, number );
|
||||
return false;
|
||||
}
|
||||
Host_Error( "%s: bad delta entity number: %i\n", __func__, number );
|
||||
|
||||
fRemoveType = MSG_ReadUBitLong( msg, 2 );
|
||||
|
||||
@@ -2043,8 +1904,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
return false;
|
||||
}
|
||||
|
||||
Con_Printf( S_ERROR "%s: unknown update type %i\n", __func__, fRemoveType );
|
||||
return false;
|
||||
Host_Error( "%s: unknown update type %i\n", __func__, fRemoveType );
|
||||
}
|
||||
|
||||
if( !cls.legacymode )
|
||||
@@ -2092,11 +1952,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
|
||||
}
|
||||
|
||||
if( !dt || !dt->bInitialized )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: broken delta\n", __func__ );
|
||||
return true;
|
||||
}
|
||||
Assert( dt && dt->bInitialized );
|
||||
|
||||
pField = dt->pFields;
|
||||
Assert( pField != NULL );
|
||||
@@ -2111,44 +1967,6 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
return true;
|
||||
}
|
||||
|
||||
void Delta_ParseTableField_GS( sizebuf_t *msg )
|
||||
{
|
||||
const char *s = MSG_ReadString( msg );
|
||||
delta_info_t *dt = Delta_FindStruct( s );
|
||||
goldsrc_delta_t null = { 0 };
|
||||
int i, num_fields;
|
||||
|
||||
// delta encoders it's already initialized on this machine (local game)
|
||||
if( delta_init )
|
||||
Delta_Shutdown();
|
||||
|
||||
if( !dt )
|
||||
Host_Error( "%s: not initialized", __func__ );
|
||||
|
||||
num_fields = MSG_ReadShort( msg );
|
||||
if( num_fields > dt->maxFields )
|
||||
Host_Error( "%s: numFields > maxFields", __func__ );
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
for( i = 0; i < num_fields; i++ )
|
||||
{
|
||||
goldsrc_delta_t to;
|
||||
|
||||
Delta_ParseGSFields( msg, &dt_goldsrc_meta, &null, &to, 0.0f );
|
||||
|
||||
// patch our DT_SIGNED flag
|
||||
if( FBitSet( to.fieldType, DT_SIGNED_GS ))
|
||||
{
|
||||
ClearBits( to.fieldType, DT_SIGNED_GS );
|
||||
SetBits( to.fieldType, DT_SIGNED );
|
||||
}
|
||||
Delta_AddField( dt, to.fieldName, to.fieldType, to.significant_bits, to.premultiply, to.postmultiply );
|
||||
}
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Delta_WriteDescriptionToClient
|
||||
|
||||
@@ -33,22 +33,6 @@ enum
|
||||
DELTA_STATIC,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DT_EVENT_T = 0,
|
||||
DT_MOVEVARS_T,
|
||||
DT_USERCMD_T,
|
||||
DT_CLIENTDATA_T,
|
||||
DT_WEAPONDATA_T,
|
||||
DT_ENTITY_STATE_T,
|
||||
DT_ENTITY_STATE_PLAYER_T,
|
||||
DT_CUSTOM_ENTITY_STATE_T,
|
||||
#if XASH_ENGINE_TESTS
|
||||
DT_DELTA_TEST_STRUCT_T,
|
||||
#endif
|
||||
DT_STRUCT_COUNT
|
||||
};
|
||||
|
||||
// struct info (filled by engine)
|
||||
typedef struct
|
||||
{
|
||||
@@ -70,17 +54,6 @@ struct delta_s
|
||||
qboolean bInactive; // unsetted by user request
|
||||
};
|
||||
|
||||
typedef struct goldsrc_delta_s
|
||||
{
|
||||
int fieldType;
|
||||
char fieldName[32];
|
||||
int fieldOffset;
|
||||
short fieldSize;
|
||||
int significant_bits;
|
||||
float premultiply;
|
||||
float postmultiply;
|
||||
} goldsrc_delta_t;
|
||||
|
||||
typedef void (*pfnDeltaEncode)( struct delta_s *pFields, const byte *from, const byte *to );
|
||||
|
||||
typedef struct
|
||||
@@ -114,7 +87,6 @@ void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber );
|
||||
// send table over network
|
||||
void Delta_WriteDescriptionToClient( sizebuf_t *msg );
|
||||
void Delta_ParseTableField( sizebuf_t *msg );
|
||||
void Delta_ParseTableField_GS( sizebuf_t *msg );
|
||||
|
||||
|
||||
// encode routines
|
||||
@@ -137,7 +109,5 @@ void MSG_ReadWeaponData( sizebuf_t *msg, const struct weapon_data_s *from, struc
|
||||
void MSG_WriteDeltaEntity( const struct entity_state_s *from, const struct entity_state_s *to, sizebuf_t *msg, qboolean force, int type, double timebase, int ofs );
|
||||
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const struct entity_state_s *from, struct entity_state_s *to, int num, int type, double timebase );
|
||||
int Delta_TestBaseline( const struct entity_state_s *from, const struct entity_state_s *to, qboolean player, double timebase );
|
||||
void Delta_ReadGSFields( sizebuf_t *msg, int index, const void *from, void *to, double timebase );
|
||||
void Delta_WriteGSFields( sizebuf_t *msg, int index, const void *from, const void *to, double timebase );
|
||||
|
||||
#endif//NET_ENCODE_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -50,10 +50,8 @@ typedef enum
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
extern convar_t net_showpackets;
|
||||
extern convar_t net_clockwindow;
|
||||
extern convar_t net_send_debug;
|
||||
extern convar_t net_recv_debug;
|
||||
extern convar_t net_showpackets;
|
||||
extern convar_t net_clockwindow;
|
||||
|
||||
void NET_Init( void );
|
||||
void NET_Shutdown( void );
|
||||
@@ -61,6 +59,7 @@ 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 );
|
||||
@@ -78,17 +77,13 @@ 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
|
||||
qboolean CL_LegacyMode( void );
|
||||
int CL_GetSplitSize( void );
|
||||
#endif
|
||||
|
||||
void HTTP_AddCustomServer( const char *url );
|
||||
void HTTP_AddDownload( const char *path, int size, qboolean process, resource_t *res );
|
||||
void HTTP_AddDownload( const char *path, int size, qboolean process );
|
||||
void HTTP_ClearCustomServers( void );
|
||||
void HTTP_Shutdown( void );
|
||||
void HTTP_ResetProcessState( void );
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
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 );
|
||||
@@ -208,14 +208,6 @@ typedef enum fragsize_e
|
||||
FRAGSIZE_UNRELIABLE
|
||||
} fragsize_t;
|
||||
|
||||
typedef enum netchan_flags_e
|
||||
{
|
||||
NETCHAN_USE_LEGACY_SPLIT = BIT( 0 ),
|
||||
NETCHAN_USE_MUNGE = BIT( 1 ),
|
||||
NETCHAN_USE_BZIP2 = BIT( 2 ),
|
||||
NETCHAN_GOLDSRC = BIT( 3 ),
|
||||
} netchan_flags_t;
|
||||
|
||||
// Network Connection Channel
|
||||
typedef struct netchan_s
|
||||
{
|
||||
@@ -278,14 +270,10 @@ typedef struct netchan_s
|
||||
// added for net_speeds
|
||||
size_t total_sended;
|
||||
size_t total_received;
|
||||
qboolean split;
|
||||
unsigned int maxpacket;
|
||||
unsigned int splitid;
|
||||
netsplit_t netsplit;
|
||||
|
||||
qboolean split;
|
||||
qboolean use_munge;
|
||||
qboolean use_bz2;
|
||||
qboolean gs_netchan;
|
||||
netsplit_t netsplit;
|
||||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
@@ -299,14 +287,14 @@ extern int net_drop;
|
||||
|
||||
void Netchan_Init( void );
|
||||
void Netchan_Shutdown( void );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ), uint flags );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ) );
|
||||
void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filename, byte *pbuf, int size );
|
||||
qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *length );
|
||||
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, const byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, const byte *data );
|
||||
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_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 );
|
||||
|
||||
95
engine/common/pm_debug.c
Normal file
95
engine/common/pm_debug.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
pm_debug.c - player move debugging code
|
||||
Copyright (C) 2017 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "pm_local.h"
|
||||
#if !XASH_DEDICATED
|
||||
#include "client.h" // CL_Particle
|
||||
#endif
|
||||
|
||||
// expand debugging BBOX particle hulls by this many units.
|
||||
#define BOX_GAP 0.0f
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_ParticleLine
|
||||
|
||||
draw line from particles
|
||||
================
|
||||
*/
|
||||
void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
float len, curdist;
|
||||
vec3_t diff, pos;
|
||||
|
||||
// determine distance
|
||||
VectorSubtract( end, start, diff );
|
||||
len = VectorNormalizeLength( diff );
|
||||
curdist = 0;
|
||||
|
||||
while( curdist <= len )
|
||||
{
|
||||
VectorMA( start, curdist, diff, pos );
|
||||
CL_Particle( pos, pcolor, life, 0, zvel );
|
||||
curdist += 2.0f;
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawRectangle
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawRectangle( const vec3_t tl, const vec3_t bl, const vec3_t tr, const vec3_t br, int pcolor, float life )
|
||||
{
|
||||
PM_ParticleLine( tl, bl, pcolor, life, 0 );
|
||||
PM_ParticleLine( bl, br, pcolor, life, 0 );
|
||||
PM_ParticleLine( br, tr, pcolor, life, 0 );
|
||||
PM_ParticleLine( tr, tl, pcolor, life, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawBBox
|
||||
|
||||
================
|
||||
*/
|
||||
void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
vec3_t p[8], tmp;
|
||||
float gap = BOX_GAP;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
tmp[0] = (i & 1) ? mins[0] - gap : maxs[0] + gap;
|
||||
tmp[1] = (i & 2) ? mins[1] - gap : maxs[1] + gap ;
|
||||
tmp[2] = (i & 4) ? mins[2] - gap : maxs[2] + gap ;
|
||||
|
||||
VectorAdd( tmp, origin, tmp );
|
||||
VectorCopy( tmp, p[i] );
|
||||
}
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
}
|
||||
@@ -20,10 +20,17 @@ GNU General Public License for more details.
|
||||
|
||||
typedef int (*pfnIgnore)( physent_t *pe ); // custom trace filter
|
||||
|
||||
//
|
||||
// pm_debug.c
|
||||
//
|
||||
void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel );
|
||||
void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life );
|
||||
|
||||
//
|
||||
// pm_trace.c
|
||||
//
|
||||
void Pmove_Init( void );
|
||||
void PM_ClearPhysEnts( playermove_t *pmove );
|
||||
void PM_InitBoxHull( void );
|
||||
hull_t *PM_HullForBsp( physent_t *pe, playermove_t *pmove, float *offset );
|
||||
qboolean PM_RecursiveHullCheck( hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace );
|
||||
@@ -39,29 +46,7 @@ struct msurface_s *PM_TraceSurfacePmove( playermove_t *pmove, int ground, float
|
||||
const char *PM_TraceTexture( playermove_t *pmove, int ground, float *vstart, float *vend );
|
||||
int PM_PointContentsPmove( playermove_t *pmove, const float *p, int *truecontents );
|
||||
void PM_StuckTouch( playermove_t *pmove, int hitent, pmtrace_t *tr );
|
||||
|
||||
static inline void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
|
||||
{
|
||||
out->allsolid = in->allsolid;
|
||||
out->startsolid = in->startsolid;
|
||||
out->inopen = in->inopen;
|
||||
out->inwater = in->inwater;
|
||||
out->fraction = in->fraction;
|
||||
out->plane.dist = in->plane.dist;
|
||||
out->hitgroup = in->hitgroup;
|
||||
out->ent = ent;
|
||||
|
||||
VectorCopy( in->endpos, out->endpos );
|
||||
VectorCopy( in->plane.normal, out->plane.normal );
|
||||
}
|
||||
|
||||
static inline void PM_ClearPhysEnts( playermove_t *pmove )
|
||||
{
|
||||
pmove->nummoveent = 0;
|
||||
pmove->numphysent = 0;
|
||||
pmove->numvisent = 0;
|
||||
pmove->numtouch = 0;
|
||||
}
|
||||
void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent );
|
||||
|
||||
static inline void PM_InitTrace( trace_t *trace, const vec3_t end )
|
||||
{
|
||||
|
||||
@@ -55,6 +55,14 @@ void Pmove_Init( void )
|
||||
memcpy( host.player_maxs, pm_hullmaxs, sizeof( pm_hullmaxs ));
|
||||
}
|
||||
|
||||
void PM_ClearPhysEnts( playermove_t *pmove )
|
||||
{
|
||||
pmove->nummoveent = 0;
|
||||
pmove->numphysent = 0;
|
||||
pmove->numvisent = 0;
|
||||
pmove->numtouch = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
PM_InitBoxHull
|
||||
@@ -109,6 +117,21 @@ static hull_t *PM_HullForBox( const vec3_t mins, const vec3_t maxs )
|
||||
return &pm_boxhull;
|
||||
}
|
||||
|
||||
void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
|
||||
{
|
||||
out->allsolid = in->allsolid;
|
||||
out->startsolid = in->startsolid;
|
||||
out->inopen = in->inopen;
|
||||
out->inwater = in->inwater;
|
||||
out->fraction = in->fraction;
|
||||
out->plane.dist = in->plane.dist;
|
||||
out->hitgroup = in->hitgroup;
|
||||
out->ent = ent;
|
||||
|
||||
VectorCopy( in->endpos, out->endpos );
|
||||
VectorCopy( in->plane.normal, out->plane.normal );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
PM_HullPointContents
|
||||
|
||||
@@ -73,7 +73,7 @@ GNU General Public License for more details.
|
||||
#define svc_director 51 // <variable sized>
|
||||
#define svc_voiceinit 52 // <see code>
|
||||
#define svc_voicedata 53 // [byte][short][...]
|
||||
// reserved
|
||||
#define svc_deltapacketbones 54 // [short][byte][...]
|
||||
// reserved
|
||||
#define svc_resourcelocation 56 // [string]
|
||||
#define svc_querycvarvalue 57 // [string]
|
||||
@@ -93,7 +93,7 @@ GNU General Public License for more details.
|
||||
#define clc_voicedata 8
|
||||
#define clc_requestcvarvalue 9
|
||||
#define clc_requestcvarvalue2 10
|
||||
#define clc_lastmsg 11 // end client messages (11 is GoldSrc message)
|
||||
#define clc_lastmsg 10 // end client messages
|
||||
|
||||
#define MAX_VISIBLE_PACKET_BITS 11 // 2048 visible entities per frame (hl1 has 256)
|
||||
#define MAX_VISIBLE_PACKET (1<<MAX_VISIBLE_PACKET_BITS)
|
||||
@@ -277,11 +277,11 @@ GNU General Public License for more details.
|
||||
#define SU_ARMOR (1<<13)
|
||||
#define SU_WEAPON (1<<14)
|
||||
|
||||
extern const char *const svc_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_legacy_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_quake_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_goldsrc_strings[svc_lastmsg+1];
|
||||
extern const char *const clc_strings[clc_lastmsg+1];
|
||||
extern const char *svc_strings[svc_lastmsg+1];
|
||||
extern const char *svc_legacy_strings[svc_lastmsg+1];
|
||||
extern const char *svc_quake_strings[svc_lastmsg+1];
|
||||
extern const char *svc_goldsrc_strings[svc_lastmsg+1];
|
||||
extern const char *clc_strings[clc_lastmsg+1];
|
||||
|
||||
// FWGS extensions
|
||||
#define NET_EXT_SPLITSIZE (1U<<0) // set splitsize by cl_dlmax
|
||||
@@ -320,7 +320,8 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0" // TODO: implement IP filter
|
||||
|
||||
// GoldSrc protocol definitions
|
||||
#define PROTOCOL_GOLDSRC_VERSION 48
|
||||
#define PROTOCOL_GOLDSRC_VERSION_REAL 48
|
||||
#define PROTOCOL_GOLDSRC_VERSION (PROTOCOL_GOLDSRC_VERSION_REAL | (BIT( 7 ))) // should be 48, only to differentiate it from PROTOCOL_LEGACY_VERSION
|
||||
|
||||
#define svc_goldsrc_version svc_changing
|
||||
#define svc_goldsrc_serverinfo svc_serverdata
|
||||
@@ -341,66 +342,17 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define clc_goldsrc_hltv clc_requestcvarvalue // 9
|
||||
#define clc_goldsrc_requestcvarvalue clc_requestcvarvalue2 // 10
|
||||
#define clc_goldsrc_requestcvarvalue2 11
|
||||
#define clc_goldsrc_lastmsg 11
|
||||
#define clc_goldsrc_lastmsg 12
|
||||
|
||||
#define S2C_REJECT_BADPASSWORD '8'
|
||||
#define S2C_REJECT '9'
|
||||
#define S2C_CHALLENGE "A00000000"
|
||||
#define S2C_CONNECTION "B"
|
||||
|
||||
#define MAX_GOLDSRC_BACKUP_CMDS 8
|
||||
#define MAX_GOLDSRC_TOTAL_CMDS 16
|
||||
#define MAX_GOLDSRC_MODEL_BITS 10
|
||||
#define MAX_GOLDSRC_RESOURCE_BITS 12
|
||||
#define MAX_GOLDSRC_ENTITY_BITS 11
|
||||
// #define MAX_GOLDSRC_EDICTS BIT( MAX_ENTITY_BITS )
|
||||
#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
|
||||
|
||||
@@ -21,7 +21,7 @@ enum soundlst_type_e
|
||||
SoundList_List
|
||||
};
|
||||
|
||||
static const char *const soundlst_groups[SoundList_Groups] =
|
||||
static const char *soundlst_groups[SoundList_Groups] =
|
||||
{
|
||||
"BouncePlayerShell",
|
||||
"BounceWeaponShell",
|
||||
@@ -46,7 +46,7 @@ typedef struct soundlst_s
|
||||
int max; // the string count if type is group
|
||||
} soundlst_t;
|
||||
|
||||
static soundlst_t soundlst[SoundList_Groups];
|
||||
soundlst_t soundlst[SoundList_Groups];
|
||||
|
||||
static void SoundList_Print_f( void );
|
||||
static void SoundList_Free( soundlst_t *lst )
|
||||
|
||||
@@ -41,7 +41,6 @@ void Test_RunIPFilter( void );
|
||||
void Test_RunGamma( void );
|
||||
void Test_RunDelta( void );
|
||||
void Test_RunBuffer( void );
|
||||
void Test_RunMunge( void );
|
||||
|
||||
#define TEST_LIST_0 \
|
||||
Test_RunLibCommon(); \
|
||||
@@ -50,8 +49,7 @@ void Test_RunMunge( void );
|
||||
Test_RunCvar(); \
|
||||
Test_RunIPFilter(); \
|
||||
Test_RunBuffer(); \
|
||||
Test_RunDelta(); \
|
||||
Test_RunMunge();
|
||||
Test_RunDelta();
|
||||
|
||||
#define TEST_LIST_0_CLIENT \
|
||||
Test_RunCon(); \
|
||||
|
||||
@@ -20,6 +20,47 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "studio.h"
|
||||
|
||||
/*
|
||||
==================
|
||||
World_MoveBounds
|
||||
==================
|
||||
*/
|
||||
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( end[i] > start[i] )
|
||||
{
|
||||
boxmins[i] = start[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = end[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxmins[i] = end[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = start[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch )
|
||||
{
|
||||
if( trace->allsolid || trace->startsolid || trace->fraction < cliptrace->fraction )
|
||||
{
|
||||
trace->ent = touch;
|
||||
|
||||
if( cliptrace->startsolid )
|
||||
{
|
||||
*cliptrace = *trace;
|
||||
cliptrace->startsolid = true;
|
||||
}
|
||||
else *cliptrace = *trace;
|
||||
}
|
||||
|
||||
return *cliptrace;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
World_TransformAABB
|
||||
@@ -66,3 +107,31 @@ void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
RankForContents
|
||||
|
||||
Used for determine contents priority
|
||||
==================
|
||||
*/
|
||||
int RankForContents( int contents )
|
||||
{
|
||||
switch( contents )
|
||||
{
|
||||
case CONTENTS_EMPTY: return 0;
|
||||
case CONTENTS_WATER: return 1;
|
||||
case CONTENTS_TRANSLUCENT: return 2;
|
||||
case CONTENTS_CURRENT_0: return 3;
|
||||
case CONTENTS_CURRENT_90: return 4;
|
||||
case CONTENTS_CURRENT_180: return 5;
|
||||
case CONTENTS_CURRENT_270: return 6;
|
||||
case CONTENTS_CURRENT_UP: return 7;
|
||||
case CONTENTS_CURRENT_DOWN: return 8;
|
||||
case CONTENTS_SLIME: return 9;
|
||||
case CONTENTS_LAVA: return 10;
|
||||
case CONTENTS_SKY: return 11;
|
||||
case CONTENTS_SOLID: return 12;
|
||||
default: return 13; // any user contents has more priority than default
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,71 +36,10 @@ ENTITY AREA CHECKING
|
||||
#include "lightstyle.h"
|
||||
|
||||
// trace common
|
||||
static inline void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( end[i] > start[i] )
|
||||
{
|
||||
boxmins[i] = start[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = end[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxmins[i] = end[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = start[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch )
|
||||
{
|
||||
if( trace->allsolid || trace->startsolid || trace->fraction < cliptrace->fraction )
|
||||
{
|
||||
trace->ent = touch;
|
||||
|
||||
if( cliptrace->startsolid )
|
||||
{
|
||||
*cliptrace = *trace;
|
||||
cliptrace->startsolid = true;
|
||||
}
|
||||
else *cliptrace = *trace;
|
||||
}
|
||||
|
||||
return *cliptrace;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
RankForContents
|
||||
|
||||
Used for determine contents priority
|
||||
==================
|
||||
*/
|
||||
static inline int RankForContents( int contents )
|
||||
{
|
||||
switch( contents )
|
||||
{
|
||||
case CONTENTS_EMPTY: return 0;
|
||||
case CONTENTS_WATER: return 1;
|
||||
case CONTENTS_TRANSLUCENT: return 2;
|
||||
case CONTENTS_CURRENT_0: return 3;
|
||||
case CONTENTS_CURRENT_90: return 4;
|
||||
case CONTENTS_CURRENT_180: return 5;
|
||||
case CONTENTS_CURRENT_270: return 6;
|
||||
case CONTENTS_CURRENT_UP: return 7;
|
||||
case CONTENTS_CURRENT_DOWN: return 8;
|
||||
case CONTENTS_SLIME: return 9;
|
||||
case CONTENTS_LAVA: return 10;
|
||||
case CONTENTS_SKY: return 11;
|
||||
case CONTENTS_SOLID: return 12;
|
||||
default: return 13; // any user contents has more priority than default
|
||||
}
|
||||
}
|
||||
|
||||
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs );
|
||||
void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs );
|
||||
trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch );
|
||||
int RankForContents( int contents );
|
||||
|
||||
#define check_angles( x ) ( (int)x == 90 || (int)x == 180 || (int)x == 270 || (int)x == -90 || (int)x == -180 || (int)x == -270 )
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ typedef enum
|
||||
force_exactfile, // File on client must exactly match server's file
|
||||
force_model_samebounds, // For model files only, the geometry must fit in the same bbox
|
||||
force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox
|
||||
force_model_specifybounds_if_avail,
|
||||
} FORCE_TYPE;
|
||||
|
||||
// Returned by TraceLine
|
||||
|
||||
@@ -222,10 +222,6 @@ 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,56 +26,47 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "build.h"
|
||||
#if XASH_ANDROID && !XASH_64BIT
|
||||
#if defined __ANDROID__ && !defined XASH_64BIT
|
||||
#include <string.h>
|
||||
#include <android/log.h>
|
||||
#include "linker.h"
|
||||
|
||||
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;
|
||||
static Elf_Sym* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) {
|
||||
Elf_Sym* symtab = si->symtab;
|
||||
const char* strtab = si->strtab;
|
||||
|
||||
if( si->nbucket == 0 )
|
||||
return NULL;
|
||||
|
||||
for( n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n] )
|
||||
{
|
||||
const Elf_Sym *s = symtab + n;
|
||||
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;
|
||||
|
||||
if( strcmp( strtab + s->st_name, name ))
|
||||
continue;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned elfhash( const unsigned char *name )
|
||||
{
|
||||
unsigned h = 0;
|
||||
static unsigned elfhash(const char* _name) {
|
||||
const unsigned char* name = (const unsigned char*) _name;
|
||||
unsigned h = 0, g;
|
||||
|
||||
while( *name )
|
||||
{
|
||||
unsigned g;
|
||||
|
||||
h = ( h << 4 ) + *name++;
|
||||
g = h & 0xf0000000;
|
||||
h ^= g;
|
||||
h ^= g >> 24;
|
||||
}
|
||||
return h;
|
||||
while(*name) {
|
||||
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
|
||||
@@ -87,20 +78,21 @@ static unsigned elfhash( const unsigned 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( const soinfo *si, const char *name )
|
||||
{
|
||||
return soinfo_elf_lookup( si, elfhash((const unsigned char *)name ), name );
|
||||
static Elf_Sym* dlsym_handle_lookup(soinfo* si, const char* name) {
|
||||
return soinfo_elf_lookup(si, elfhash(name), name);
|
||||
}
|
||||
|
||||
extern "C" void *dlsym_weak( void *handle, const char *symbol )
|
||||
{
|
||||
soinfo *found = (soinfo *)handle;
|
||||
Elf_Sym *sym = dlsym_handle_lookup( found, symbol );
|
||||
extern "C" void* dlsym_weak(void* handle, const char* symbol) {
|
||||
|
||||
if( sym != NULL )
|
||||
return (void *)( sym->st_value + found->base /*load_bias*/ );
|
||||
soinfo* found = NULL;
|
||||
Elf_Sym* sym = NULL;
|
||||
found = reinterpret_cast<soinfo*>(handle);
|
||||
sym = dlsym_handle_lookup(found, symbol);
|
||||
|
||||
__android_log_print( ANDROID_LOG_ERROR, "dlsym-weak", "Failed when looking up %s\n", symbol );
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
#endif // XASH_ANDROID && !XASH_64BIT
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#ifndef _LINKER_H_
|
||||
#define _LINKER_H_
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -38,153 +39,163 @@
|
||||
|
||||
// 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
|
||||
};
|
||||
#define FLAG_LINKED 0x00000001
|
||||
#define FLAG_EXE 0x00000004 // The main executable
|
||||
#define FLAG_LINKER 0x00000010 // The linker itself
|
||||
#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 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
|
||||
|
||||
@@ -51,7 +51,6 @@ void IOS_LaunchDialog( void );
|
||||
|
||||
#if XASH_POSIX
|
||||
void Posix_Daemonize( void );
|
||||
void Posix_SetupSigtermHandling( void );
|
||||
#endif
|
||||
|
||||
#if XASH_SDL
|
||||
@@ -157,13 +156,6 @@ static inline qboolean Sys_DebuggerPresent( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void Platform_SetupSigtermHandling( void )
|
||||
{
|
||||
#if XASH_POSIX
|
||||
Posix_SetupSigtermHandling( );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ GNU General Public License for more details.
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include "platform/platform.h"
|
||||
#include "menu_int.h"
|
||||
|
||||
@@ -146,21 +145,6 @@ void Posix_Daemonize( void )
|
||||
|
||||
}
|
||||
|
||||
static void Posix_SigtermCallback( int signal )
|
||||
{
|
||||
Sys_Quit();
|
||||
}
|
||||
|
||||
void Posix_SetupSigtermHandling( void )
|
||||
{
|
||||
#if !XASH_PSVITA
|
||||
struct sigaction act = { 0 };
|
||||
act.sa_handler = Posix_SigtermCallback;
|
||||
act.sa_flags = 0;
|
||||
sigaction( SIGTERM, &act, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_TIMER == TIMER_POSIX
|
||||
double Platform_DoubleTime( void )
|
||||
{
|
||||
|
||||
@@ -674,7 +674,7 @@ static void VID_SetWindowIcon( SDL_Window *hWnd )
|
||||
if( ico && WIN_SetWindowIcon( ico ))
|
||||
return;
|
||||
}
|
||||
#endif // XASH_WIN32
|
||||
#endif // _WIN32 && !XASH_64BIT
|
||||
|
||||
Q_strncpy( iconpath, GI->iconpath, sizeof( iconpath ));
|
||||
COM_ReplaceExtension( iconpath, ".tga", sizeof( iconpath ));
|
||||
|
||||
@@ -61,6 +61,8 @@ 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
|
||||
//
|
||||
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from );
|
||||
qboolean SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from );
|
||||
|
||||
#endif//SERVER_H
|
||||
|
||||
@@ -19,7 +19,7 @@ GNU General Public License for more details.
|
||||
#include "net_encode.h"
|
||||
#include "net_api.h"
|
||||
|
||||
const char *const clc_strings[clc_lastmsg+1] =
|
||||
const char *clc_strings[clc_lastmsg+1] =
|
||||
{
|
||||
"clc_bad",
|
||||
"clc_nop",
|
||||
@@ -27,12 +27,11 @@ const char *const clc_strings[clc_lastmsg+1] =
|
||||
"clc_stringcmd",
|
||||
"clc_delta",
|
||||
"clc_resourcelist",
|
||||
"clc_legacy_userinfo",
|
||||
"clc_unused6",
|
||||
"clc_fileconsistency",
|
||||
"clc_voicedata",
|
||||
"clc_cvarvalue/clc_goldsrc_hltv",
|
||||
"clc_cvarvalue2/clc_goldsrc_requestcvarvalue",
|
||||
"clc_goldsrc_requestcvarvalue2",
|
||||
"clc_cvarvalue",
|
||||
"clc_cvarvalue2",
|
||||
};
|
||||
|
||||
typedef struct ucmd_s
|
||||
@@ -131,7 +130,7 @@ static void SV_GetChallenge( netadr_t from )
|
||||
}
|
||||
|
||||
// send it back
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, S2C_CHALLENGE" %i", svs.challenges[i].challenge );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, "challenge %i", svs.challenges[i].challenge );
|
||||
}
|
||||
|
||||
static int SV_GetFragmentSize( void *pcl, fragsize_t mode )
|
||||
@@ -194,9 +193,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, 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" );
|
||||
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" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -445,7 +444,7 @@ static void SV_ConnectClient( netadr_t from )
|
||||
newcl->listeners = -1;
|
||||
|
||||
// initailize netchan
|
||||
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize, 0 );
|
||||
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize );
|
||||
MSG_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf
|
||||
|
||||
Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 );
|
||||
@@ -456,7 +455,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, S2C_CONNECTION" %s", protinfo );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect %s", protinfo );
|
||||
|
||||
newcl->upstate = us_inactive;
|
||||
newcl->connection_started = host.realtime;
|
||||
@@ -604,7 +603,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, S2C_ERRORMSG"\nKicked with message:\n%s\n", buf );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, "errormsg\nKicked with message:\n%s\n", buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -612,7 +611,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, S2C_ERRORMSG"\nYou were kicked from the game\n" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, cl->netchan.remote_address, "errormsg\nYou were kicked from the game\n" );
|
||||
}
|
||||
|
||||
SV_DropClient( cl, false );
|
||||
@@ -714,18 +713,20 @@ 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, A2C_PRINT"\n%s", buf );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, adr, "print\n%s", buf );
|
||||
break;
|
||||
case RD_CLIENT:
|
||||
if( !sv.current_client || !FBitSet( sv.current_client->flags, FCL_FAKECLIENT ))
|
||||
return; // client not set
|
||||
if( !sv.current_client ) return; // client not set
|
||||
MSG_BeginServerCmd( &sv.current_client->netchan.message, svc_print );
|
||||
MSG_WriteString( &sv.current_client->netchan.message, buf );
|
||||
break;
|
||||
default:
|
||||
case RD_NONE:
|
||||
Con_Printf( S_ERROR "%s: %s: invalid destination\n", __func__, NET_AdrToString( adr ));
|
||||
break;
|
||||
}
|
||||
@@ -951,30 +952,14 @@ static void SV_Info( netadr_t from, int protocolVersion )
|
||||
if( remaining < 0 )
|
||||
{
|
||||
// should never happen?
|
||||
Con_Printf( S_ERROR "%s: infostring overflow!\n", __func__ );
|
||||
Con_Printf( S_ERROR "SV_Info: infostring overflow!\n" );
|
||||
return;
|
||||
}
|
||||
Q_strncpy( temp, hostname.string, remaining );
|
||||
Info_SetValueForKey( s, "host", temp, sizeof( 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 );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "info\n%s", s );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1008,7 +993,7 @@ static void SV_BuildNetAnswer( netadr_t from )
|
||||
{
|
||||
// send error unsupported protocol
|
||||
Info_SetValueForKey( string, "neterror", "protocol", sizeof( string ));
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_NETINFO" %i %i %s\n", context, type, string );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "netinfo %i %i %s\n", context, type, string );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1079,7 +1064,19 @@ static void SV_BuildNetAnswer( netadr_t from )
|
||||
break;
|
||||
}
|
||||
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, A2A_NETINFO" %i %i %s\n", context, type, string );
|
||||
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" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1107,7 +1104,10 @@ 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 ))
|
||||
@@ -1120,9 +1120,7 @@ void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
||||
|
||||
if( Rcon_Validate( ))
|
||||
{
|
||||
static char outputbuf[2048];
|
||||
char remaining[1024];
|
||||
char *p = remaining;
|
||||
SV_BeginRedirect( &host.rd, from, RD_PACKET, outputbuf, sizeof( outputbuf ) - 16, SV_FlushRedirect );
|
||||
|
||||
remaining[0] = 0;
|
||||
for( i = 2; i < Cmd_Argc(); i++ )
|
||||
@@ -1131,9 +1129,8 @@ 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 ));
|
||||
}
|
||||
|
||||
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" );
|
||||
@@ -1345,8 +1342,9 @@ otherwise see code SV_UpdateMovevars()
|
||||
*/
|
||||
void SV_FullUpdateMovevars( sv_client_t *cl, sizebuf_t *msg )
|
||||
{
|
||||
const movevars_t nullmovevars = { 0 };
|
||||
movevars_t nullmovevars;
|
||||
|
||||
memset( &nullmovevars, 0, sizeof( nullmovevars ));
|
||||
MSG_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
|
||||
}
|
||||
|
||||
@@ -1994,7 +1992,7 @@ static qboolean SV_Noclip_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
return true;
|
||||
|
||||
if( pEntity->v.movetype != MOVETYPE_NOCLIP )
|
||||
@@ -2020,7 +2018,7 @@ static qboolean SV_Godmode_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
return true;
|
||||
|
||||
pEntity->v.flags = pEntity->v.flags ^ FL_GODMODE;
|
||||
@@ -2041,7 +2039,7 @@ static qboolean SV_Notarget_f( sv_client_t *cl )
|
||||
{
|
||||
edict_t *pEntity = cl->edict;
|
||||
|
||||
if( sv.background || !Cvar_VariableInteger( "sv_cheats" ))
|
||||
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
|
||||
return true;
|
||||
|
||||
pEntity->v.flags = pEntity->v.flags ^ FL_NOTARGET;
|
||||
@@ -3038,7 +3036,7 @@ static qboolean SV_EntGetVars_f( sv_client_t *cl )
|
||||
return true;
|
||||
}
|
||||
|
||||
static const ucmd_t ucmds[] =
|
||||
ucmd_t ucmds[] =
|
||||
{
|
||||
{ "new", SV_New_f },
|
||||
{ "god", SV_Godmode_f },
|
||||
@@ -3058,7 +3056,7 @@ static const ucmd_t ucmds[] =
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const ucmd_t enttoolscmds[] =
|
||||
ucmd_t enttoolscmds[] =
|
||||
{
|
||||
{ "ent_list", SV_EntList_f },
|
||||
{ "ent_info", SV_EntInfo_f },
|
||||
@@ -3075,7 +3073,7 @@ SV_ExecuteUserCommand
|
||||
*/
|
||||
static void SV_ExecuteClientCommand( sv_client_t *cl, const char *s )
|
||||
{
|
||||
const ucmd_t *u;
|
||||
ucmd_t *u;
|
||||
|
||||
Cmd_TokenizeString( s );
|
||||
|
||||
@@ -3150,14 +3148,17 @@ connectionless packets.
|
||||
*/
|
||||
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
const char *pcmd, *args;
|
||||
char *args;
|
||||
const char *pcmd;
|
||||
char buf[MAX_SYSPATH];
|
||||
int len = sizeof( buf );
|
||||
|
||||
// prevent flooding from banned address
|
||||
if( SV_CheckIP( &from ))
|
||||
if( SV_CheckIP( &from ) )
|
||||
return;
|
||||
|
||||
MSG_Clear( msg );
|
||||
MSG_SeekToBit( msg, sizeof( uint32_t ) << 3, SEEK_CUR ); // skip the -1 marker
|
||||
MSG_ReadLong( msg );// skip the -1 marker
|
||||
|
||||
args = MSG_ReadStringLine( msg );
|
||||
Cmd_TokenizeString( args );
|
||||
@@ -3167,79 +3168,29 @@ 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( !svs.initialized )
|
||||
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 ))
|
||||
{
|
||||
// only process rcon if server not initialized
|
||||
if( !Q_strcmp( pcmd, C2S_RCON ))
|
||||
SV_RemoteCommand( net_from, &net_message );
|
||||
|
||||
return;
|
||||
netadr_t to;
|
||||
if( NET_StringToAdr( Cmd_Argv( 1 ), &to ) && !NET_IsReservedAdr( to ))
|
||||
SV_Info( to, PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
if( !Q_strcmp( pcmd, A2S_GOLDSRC_INFO ) || pcmd[0] == A2S_GOLDSRC_PLAYERS || pcmd[0] == A2S_GOLDSRC_RULES )
|
||||
else if( svgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
{
|
||||
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 );
|
||||
}
|
||||
// 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,6 +16,8 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_ClientPrintf
|
||||
|
||||
@@ -25,8 +25,8 @@ typedef struct
|
||||
byte sended[MAX_EDICTS_BYTES];
|
||||
} sv_ents_t;
|
||||
|
||||
static int c_fullsend; // just a debug counter
|
||||
static int c_notsend;
|
||||
int c_fullsend; // just a debug counter
|
||||
int c_notsend;
|
||||
|
||||
/*
|
||||
=======================
|
||||
|
||||
@@ -24,6 +24,8 @@ GNU General Public License for more details.
|
||||
#include "render_api.h" // modelstate_t
|
||||
#include "ref_common.h" // decals
|
||||
|
||||
#define ENTVARS_COUNT ARRAYSIZE( gEntvarsDescription )
|
||||
|
||||
// GameAPI functions declarations
|
||||
static int GAME_EXPORT pfnModelIndex( const char *m );
|
||||
|
||||
@@ -81,7 +83,7 @@ EntvarsDescription
|
||||
entavrs table for FindEntityByString
|
||||
=============
|
||||
*/
|
||||
static const TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
static TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
{
|
||||
DEFINE_ENTITY_FIELD( classname, FIELD_STRING ),
|
||||
DEFINE_ENTITY_FIELD( globalname, FIELD_STRING ),
|
||||
@@ -98,6 +100,20 @@ static const TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ),
|
||||
};
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_GetEntvarsDescription
|
||||
|
||||
entavrs table for FindEntityByString
|
||||
=============
|
||||
*/
|
||||
static TYPEDESCRIPTION *SV_GetEntvarsDescirption( int number )
|
||||
{
|
||||
if( number < 0 || number >= ENTVARS_COUNT )
|
||||
return NULL;
|
||||
return &gEntvarsDescription[number];
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_SysError
|
||||
@@ -627,16 +643,12 @@ Write ambient sounds into demo
|
||||
*/
|
||||
void SV_RestartAmbientSounds( void )
|
||||
{
|
||||
// TODO: we don't know sounds state on remote server
|
||||
// as it's used only for demos, maybe this could be implemented on client side?
|
||||
#if !XASH_DEDICATED
|
||||
soundlist_t soundInfo[256];
|
||||
string curtrack, looptrack;
|
||||
int i, nSounds;
|
||||
int position;
|
||||
|
||||
if( !SV_Active( ) || Host_IsDedicated( ))
|
||||
return;
|
||||
if( !SV_Active( )) return;
|
||||
|
||||
nSounds = S_GetCurrentStaticSounds( soundInfo, 256 );
|
||||
|
||||
@@ -651,12 +663,13 @@ void SV_RestartAmbientSounds( void )
|
||||
SV_StartSound( SV_PEntityOfEntIndex( si->entnum, true ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch );
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED // TODO: ???
|
||||
// restart soundtrack
|
||||
if( S_StreamGetCurrentState( curtrack, sizeof( curtrack ), looptrack, sizeof( looptrack ), &position ))
|
||||
{
|
||||
SV_StartMusic( curtrack, looptrack, position );
|
||||
}
|
||||
#endif // !XASH_DEDICATED
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -668,25 +681,31 @@ Write all the decals into demo
|
||||
*/
|
||||
void SV_RestartDecals( void )
|
||||
{
|
||||
// TODO: similar to SV_RestartAmbientSounds, this is only used for demo recording
|
||||
// and better be reimplemented on client side
|
||||
#if !XASH_DEDICATED
|
||||
decallist_t *list;
|
||||
int decalIndex;
|
||||
int modelIndex;
|
||||
sizebuf_t *msg;
|
||||
int i, numdecals;
|
||||
|
||||
if( !SV_Active( ) || Host_IsDedicated( ))
|
||||
return;
|
||||
if( !SV_Active( )) return;
|
||||
|
||||
// g-cont. add space for studiodecals if present
|
||||
list = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
numdecals = ref.dllFuncs.R_CreateDecalList( list );
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated() )
|
||||
{
|
||||
numdecals = ref.dllFuncs.R_CreateDecalList( list );
|
||||
|
||||
// remove decals from map
|
||||
ref.dllFuncs.R_ClearAllDecals();
|
||||
// remove decals from map
|
||||
ref.dllFuncs.R_ClearAllDecals();
|
||||
}
|
||||
else
|
||||
#endif // XASH_DEDICATED
|
||||
{
|
||||
// we probably running a dedicated server
|
||||
numdecals = 0;
|
||||
}
|
||||
|
||||
// write decals into reliable datagram
|
||||
msg = SV_GetReliableDatagram();
|
||||
@@ -709,7 +728,6 @@ void SV_RestartDecals( void )
|
||||
}
|
||||
|
||||
Z_Free( list );
|
||||
#endif // !XASH_DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1490,8 +1508,8 @@ SV_FindEntityByString
|
||||
*/
|
||||
static edict_t *GAME_EXPORT SV_FindEntityByString( edict_t *pStartEdict, const char *pszField, const char *pszValue )
|
||||
{
|
||||
int i = 0, e = 0;
|
||||
const TYPEDESCRIPTION *desc = NULL;
|
||||
int index = 0, e = 0;
|
||||
TYPEDESCRIPTION *desc = NULL;
|
||||
edict_t *ed;
|
||||
const char *t;
|
||||
|
||||
@@ -1500,13 +1518,10 @@ static edict_t *GAME_EXPORT SV_FindEntityByString( edict_t *pStartEdict, const c
|
||||
|
||||
if( pStartEdict ) e = NUM_FOR_EDICT( pStartEdict );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( gEntvarsDescription ); i++ )
|
||||
while(( desc = SV_GetEntvarsDescirption( index++ )) != NULL )
|
||||
{
|
||||
if( !Q_strcmp( pszField, gEntvarsDescription[i].fieldName ))
|
||||
{
|
||||
desc = &gEntvarsDescription[i];
|
||||
if( !Q_strcmp( pszField, desc->fieldName ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( desc == NULL )
|
||||
@@ -2985,22 +3000,24 @@ 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
|
||||
|
||||
/*
|
||||
==================
|
||||
@@ -3011,7 +3028,7 @@ Free strings on server stop. Reset string pointer on 64 bits
|
||||
*/
|
||||
void SV_EmptyStringPool( void )
|
||||
{
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
if( str64.dynamic ) // switch only after array fill (more space for multiplayer games)
|
||||
str64.pstringbase = str64.pstringarray;
|
||||
else
|
||||
@@ -3019,9 +3036,9 @@ void SV_EmptyStringPool( void )
|
||||
str64.pstringbase = str64.poldstringbase = str64.pstringarraystatic;
|
||||
str64.plast = str64.pstringbase + 1;
|
||||
}
|
||||
#else // !XASH_64BIT
|
||||
#else
|
||||
Mem_EmptyPool( svgame.stringspool );
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3035,7 +3052,7 @@ this helps not to lose strings that belongs to static game part
|
||||
*/
|
||||
void SV_SetStringArrayMode( qboolean dynamic )
|
||||
{
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
Con_Reportf( "%s(%d) %d\n", __func__, dynamic, str64.dynamic );
|
||||
|
||||
if( dynamic == str64.dynamic )
|
||||
@@ -3044,11 +3061,11 @@ void SV_SetStringArrayMode( qboolean dynamic )
|
||||
str64.dynamic = dynamic;
|
||||
|
||||
SV_EmptyStringPool();
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_AMD64 && XASH_LINUX && !XASH_ANDROID
|
||||
#define USE_MMAP 1
|
||||
#define USE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
@@ -3064,7 +3081,7 @@ this case need patched game dll with MAKE_STRING checking ptrdiff size
|
||||
*/
|
||||
static void SV_AllocStringPool( void )
|
||||
{
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
void *ptr = NULL;
|
||||
string lenstr;
|
||||
|
||||
@@ -3079,7 +3096,7 @@ static void SV_AllocStringPool( void )
|
||||
if( Sys_CheckParm( "-str64dup" ) )
|
||||
str64.allowdup = true;
|
||||
|
||||
#if USE_MMAP
|
||||
#ifdef USE_MMAP
|
||||
{
|
||||
uint flags;
|
||||
size_t pagesize = sysconf( _SC_PAGESIZE );
|
||||
@@ -3133,37 +3150,35 @@ static void SV_AllocStringPool( void )
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
}
|
||||
}
|
||||
#else // !USE_MMAP
|
||||
#else
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
#endif // !USE_MMAP
|
||||
#endif
|
||||
|
||||
str64.pstringarray = ptr;
|
||||
str64.pstringarraystatic = (byte*)ptr + str64.maxstringarray;
|
||||
str64.pstringbase = str64.poldstringbase = ptr;
|
||||
str64.plast = (byte*)ptr + 1;
|
||||
svgame.globals->pStringBase = ptr;
|
||||
#else // !XASH_64BIT
|
||||
#else
|
||||
svgame.stringspool = Mem_AllocPool( "Server Strings" );
|
||||
svgame.globals->pStringBase = "";
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SV_FreeStringPool( void )
|
||||
{
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
|
||||
#if USE_MMAP
|
||||
#ifdef USE_MMAP
|
||||
if( str64.pstringarray != str64.staticstringarray )
|
||||
munmap( str64.pstringarray, (str64.maxstringarray * 2) & ~(sysconf( _SC_PAGESIZE ) - 1) );
|
||||
else
|
||||
#endif // USE_MMAP
|
||||
{
|
||||
#endif
|
||||
Mem_Free( str64.staticstringarray );
|
||||
}
|
||||
#else // !XASH_64BIT
|
||||
#else
|
||||
Mem_FreePool( &svgame.stringspool );
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3234,7 +3249,9 @@ 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 )
|
||||
{
|
||||
@@ -3250,7 +3267,7 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
return i;
|
||||
}
|
||||
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
cmp = 1;
|
||||
|
||||
if( !str64.allowdup )
|
||||
@@ -3288,18 +3305,18 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
str64.maxalloc = newString - str64.pstringarray;
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#else // !XASH_64BIT
|
||||
#else
|
||||
len = SV_ProcessString( NULL, szValue );
|
||||
newString = Mem_Malloc( svgame.stringspool, len );
|
||||
SV_ProcessString( newString, szValue );
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
void SV_PrintStr64Stats_f( void )
|
||||
{
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
Con_Printf( "====================\n" );
|
||||
Con_Printf( "64 bit string pool statistics\n" );
|
||||
Con_Printf( "====================\n" );
|
||||
@@ -3308,9 +3325,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 // !XASH_64BIT
|
||||
#else
|
||||
Con_Printf( "Not implemented\n" );
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3324,7 +3341,7 @@ string_t SV_MakeString( const char *szValue )
|
||||
{
|
||||
if( svgame.physFuncs.pfnMakeString != NULL )
|
||||
return svgame.physFuncs.pfnMakeString( szValue );
|
||||
#if XASH_64BIT
|
||||
#ifdef XASH_64BIT
|
||||
{
|
||||
long long ptrdiff = szValue - svgame.globals->pStringBase;
|
||||
if( ptrdiff > INT_MAX || ptrdiff < INT_MIN )
|
||||
@@ -3332,9 +3349,9 @@ string_t SV_MakeString( const char *szValue )
|
||||
else
|
||||
return (int)ptrdiff;
|
||||
}
|
||||
#else // !XASH_64BIT
|
||||
#else
|
||||
return szValue - svgame.globals->pStringBase;
|
||||
#endif // !XASH_64BIT
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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, S2C_BANDWIDTHTEST );
|
||||
MSG_WriteString( &svs.testpacket, "testpacket" );
|
||||
svs.testpacket_crcpos = svs.testpacket.pData + MSG_GetNumBytesWritten( &svs.testpacket );
|
||||
MSG_WriteDword( &svs.testpacket, 0 ); // to be changed by crc
|
||||
|
||||
@@ -1028,8 +1028,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba
|
||||
if( !SV_InitGame( ))
|
||||
return false;
|
||||
|
||||
Delta_Init(); // re-initialize delta
|
||||
|
||||
// unlock sv_cheats in local game
|
||||
ClearBits( sv_cheats.flags, FCVAR_READ_ONLY );
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ static CVAR_DEFINE_AUTO( sv_waterfriction, "1", FCVAR_SERVER|FCVAR_MOVEVARS, "ho
|
||||
static CVAR_DEFINE_AUTO( sv_bounce, "1", FCVAR_SERVER|FCVAR_MOVEVARS, "bounce factor for entities with MOVETYPE_BOUNCE" );
|
||||
static CVAR_DEFINE_AUTO( sv_stepsize, "18", FCVAR_SERVER|FCVAR_MOVEVARS, "how high you and NPS's can step up" );
|
||||
CVAR_DEFINE_AUTO( sv_maxvelocity, "2000", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "max velocity for all things in the world" );
|
||||
static CVAR_DEFINE_AUTO( sv_zmax, "4096", FCVAR_MOVEVARS|FCVAR_SPONLY, "maximum viewable distance" );
|
||||
static CVAR_DEFINE_AUTO( sv_zmax, "4096", FCVAR_SERVER|FCVAR_MOVEVARS|FCVAR_SPONLY, "maximum viewable distance" );
|
||||
CVAR_DEFINE_AUTO( sv_wateramp, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "world waveheight factor" );
|
||||
static CVAR_DEFINE( sv_footsteps, "mp_footsteps", "1", FCVAR_SERVER|FCVAR_MOVEVARS, "play foot steps for players" );
|
||||
static CVAR_DEFINE( sv_footsteps, "mp_footsteps", "1", FCVAR_SERVER|FCVAR_MOVEVARS, "world gravity value" );
|
||||
CVAR_DEFINE_AUTO( sv_skyname, "desert", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "skybox name (can be dynamically changed in-game)" );
|
||||
static CVAR_DEFINE_AUTO( sv_rollangle, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED|FCVAR_ARCHIVE, "how much to tilt the view when strafing" );
|
||||
static CVAR_DEFINE_AUTO( sv_rollspeed, "200", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "how much strafing is necessary to tilt the view" );
|
||||
@@ -189,9 +189,6 @@ void SV_UpdateMovevars( qboolean initialize )
|
||||
if( !initialize && !host.movevars_changed )
|
||||
return;
|
||||
|
||||
// NOTE: this breaks Natural Selection mod on ns_machina map that uses model as sky
|
||||
// it sets the value to 4000000 that even exceeds the coord limit
|
||||
#if 0
|
||||
// check range
|
||||
if( sv_zmax.value < 256.0f ) Cvar_SetValue( "sv_zmax", 256.0f );
|
||||
|
||||
@@ -206,7 +203,6 @@ void SV_UpdateMovevars( qboolean initialize )
|
||||
if( sv_zmax.value > 32767.0f )
|
||||
Cvar_SetValue( "sv_zmax", 32767.0f );
|
||||
}
|
||||
#endif
|
||||
|
||||
svgame.movevars.gravity = sv_gravity.value;
|
||||
svgame.movevars.stopspeed = sv_stopspeed.value;
|
||||
@@ -389,7 +385,23 @@ static void SV_ReadPackets( void )
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
if( MSG_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
|
||||
{
|
||||
SV_ConnectionlessPacket( net_from, &net_message );
|
||||
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 );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -714,7 +726,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] = S2M_INFO; // skip 2 bytes of header
|
||||
char s[MAX_INFO_STRING] = "0\n"; // 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( ENGINE_FEATURES_MASK, svgame.physFuncs.SV_CheckFeatures( ));
|
||||
Host_ValidateEngineFeatures( svgame.physFuncs.SV_CheckFeatures( ));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// make sure what physic functions is cleared
|
||||
memset( &svgame.physFuncs, 0, sizeof( svgame.physFuncs ));
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, 0 );
|
||||
Host_ValidateEngineFeatures( 0 );
|
||||
return false; // just tell user about problems
|
||||
}
|
||||
|
||||
// physic interface is missed
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, 0 );
|
||||
Host_ValidateEngineFeatures( 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,15 @@ 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
|
||||
@@ -32,8 +41,7 @@ static void SV_SourceQuery_Details( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQuery", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_INFO );
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_DETAILS_RESPONSE );
|
||||
MSG_WriteByte( &buf, PROTOCOL_VERSION );
|
||||
|
||||
MSG_WriteString( &buf, hostname.string );
|
||||
@@ -61,7 +69,7 @@ static void SV_SourceQuery_Details( netadr_t from )
|
||||
MSG_WriteByte( &buf, GI->secure );
|
||||
MSG_WriteString( &buf, XASH_VERSION );
|
||||
|
||||
NET_SendPacket( NS_SERVER, MSG_GetNumBytesWritten( &buf ), MSG_GetData( &buf ), from );
|
||||
Netchan_OutOfBand( NS_SERVER, from, MSG_GetNumBytesWritten( &buf ), MSG_GetData( &buf ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -79,8 +87,7 @@ static void SV_SourceQuery_Rules( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQueryRules", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_RULES );
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_RULES_RESPONSE );
|
||||
|
||||
pos = MSG_GetNumBitsWritten( &buf );
|
||||
MSG_WriteShort( &buf, 0 );
|
||||
@@ -110,7 +117,7 @@ static void SV_SourceQuery_Rules( netadr_t from )
|
||||
MSG_SeekToBit( &buf, pos, SEEK_SET );
|
||||
MSG_WriteShort( &buf, cvar_count );
|
||||
|
||||
NET_SendPacket( NS_SERVER, total, MSG_GetData( &buf ), from );
|
||||
Netchan_OutOfBand( NS_SERVER, from, total, MSG_GetData( &buf ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +139,7 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
|
||||
MSG_Init( &buf, "TSourceEngineQueryPlayers", answer, sizeof( answer ));
|
||||
|
||||
MSG_WriteDword( &buf, 0xFFFFFFFFU );
|
||||
MSG_WriteByte( &buf, S2A_GOLDSRC_PLAYERS );
|
||||
MSG_WriteByte( &buf, SOURCE_QUERY_PLAYERS_RESPONSE );
|
||||
|
||||
pos = MSG_GetNumBitsWritten( &buf );
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
@@ -162,7 +168,7 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
MSG_SeekToBit( &buf, pos, SEEK_SET );
|
||||
MSG_WriteByte( &buf, count );
|
||||
|
||||
NET_SendPacket( NS_SERVER, total, MSG_GetData( &buf ), from );
|
||||
Netchan_OutOfBand( NS_SERVER, from, total, MSG_GetData( &buf ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,19 +177,24 @@ static void SV_SourceQuery_Players( netadr_t from )
|
||||
SV_SourceQuery_HandleConnnectionlessPacket
|
||||
==================
|
||||
*/
|
||||
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from )
|
||||
qboolean SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from )
|
||||
{
|
||||
if( !Q_strcmp( c, A2S_GOLDSRC_INFO ))
|
||||
switch( c[0] )
|
||||
{
|
||||
case SOURCE_QUERY_DETAILS:
|
||||
SV_SourceQuery_Details( from );
|
||||
}
|
||||
else switch( c[0] )
|
||||
{
|
||||
case A2S_GOLDSRC_RULES:
|
||||
return true;
|
||||
|
||||
case SOURCE_QUERY_RULES:
|
||||
SV_SourceQuery_Rules( from );
|
||||
break;
|
||||
case A2S_GOLDSRC_PLAYERS:
|
||||
return true;
|
||||
|
||||
case SOURCE_QUERY_PLAYERS:
|
||||
SV_SourceQuery_Players( from );
|
||||
break;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef struct
|
||||
float time;
|
||||
} SAVE_LIGHTSTYLE;
|
||||
|
||||
static void (__cdecl *pfnSaveGameComment)( char *buffer, int max_length ) = NULL;
|
||||
void (__cdecl *pfnSaveGameComment)( char *buffer, int max_length ) = NULL;
|
||||
|
||||
static TYPEDESCRIPTION gGameHeader[] =
|
||||
{
|
||||
@@ -218,7 +218,7 @@ static TYPEDESCRIPTION gTempEntvars[] =
|
||||
DEFINE_ENTITY_GLOBAL_FIELD( globalname, FIELD_STRING ),
|
||||
};
|
||||
|
||||
static const struct
|
||||
struct
|
||||
{
|
||||
const char *mapname;
|
||||
const char *titlename;
|
||||
@@ -1170,36 +1170,41 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
char name[MAX_QPATH];
|
||||
int i, id, version;
|
||||
char *pTokenData;
|
||||
decallist_t *decalList = NULL;
|
||||
SAVE_CLIENT header = { 0 };
|
||||
decallist_t *decalList;
|
||||
SAVE_CLIENT header;
|
||||
file_t *pFile;
|
||||
|
||||
// clearing the saving buffer to reuse
|
||||
SaveClear( pSaveData );
|
||||
|
||||
header.entityCount = sv.num_static_entities;
|
||||
memset( &header, 0, sizeof( header ));
|
||||
|
||||
// g-cont. add space for studiodecals if present
|
||||
decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
// initialize client header
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
if( !Host_IsDedicated() )
|
||||
{
|
||||
// g-cont. add space for studiodecals if present
|
||||
decalList = (decallist_t *)Mem_Calloc( host.mempool, sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
header.decalCount = ref.dllFuncs.R_CreateDecalList( decalList );
|
||||
|
||||
if( !changelevel ) // sounds won't going across transition
|
||||
{
|
||||
header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS );
|
||||
|
||||
// music not reqiured to save position: it's just continue playing on a next level
|
||||
S_StreamGetCurrentState(
|
||||
header.introTrack, sizeof( header.introTrack ),
|
||||
header.mainTrack, sizeof( header.mainTrack ),
|
||||
&header.trackPosition );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // XASH_DEDICATED
|
||||
{
|
||||
// we probably running a dedicated server
|
||||
header.decalCount = 0;
|
||||
}
|
||||
header.entityCount = sv.num_static_entities;
|
||||
|
||||
if( !changelevel )
|
||||
{
|
||||
// sounds won't going across transition
|
||||
header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS );
|
||||
#if !XASH_DEDICATED
|
||||
// music not reqiured to save position: it's just continue playing on a next level
|
||||
S_StreamGetCurrentState( header.introTrack, sizeof( header.introTrack ), header.mainTrack, sizeof( header.mainTrack ), &header.trackPosition );
|
||||
#endif
|
||||
}
|
||||
|
||||
// save viewentity to allow camera works after save\restore
|
||||
if( SV_IsValidEdict( cl->pViewEntity ) && cl->pViewEntity != cl->edict )
|
||||
@@ -1212,7 +1217,7 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "ClientHeader", &header, gSaveClient, ARRAYSIZE( gSaveClient ));
|
||||
|
||||
// store decals
|
||||
for( i = 0; decalList != NULL && i < header.decalCount; i++ )
|
||||
for( i = 0; i < header.decalCount; i++ )
|
||||
{
|
||||
// NOTE: apply landmark offset only for brush entities without origin brushes
|
||||
if( pSaveData->fUseLandmark && FBitSet( decalList[i].flags, FDECAL_USE_LANDMARK ))
|
||||
@@ -1220,9 +1225,7 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "DECALLIST", &decalList[i], gDecalEntry, ARRAYSIZE( gDecalEntry ));
|
||||
}
|
||||
|
||||
if( decalList )
|
||||
Mem_Free( decalList );
|
||||
Z_Free( decalList );
|
||||
|
||||
// write client entities
|
||||
for( i = 0; i < header.entityCount; i++ )
|
||||
@@ -2185,19 +2188,6 @@ qboolean SV_SaveGame( const char *pName )
|
||||
return SaveGameSlot( savename, comment );
|
||||
}
|
||||
|
||||
static int SV_CompareFileTime( int ft1, int ft2 )
|
||||
{
|
||||
if( ft1 < ft2 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if( ft1 > ft2 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_GetLatestSave
|
||||
@@ -2223,7 +2213,7 @@ const char *SV_GetLatestSave( void )
|
||||
if( ft > 0 )
|
||||
{
|
||||
// should we use the matched?
|
||||
if( !found || SV_CompareFileTime( newest, ft ) < 0 )
|
||||
if( !found || Host_CompareFileTime( newest, ft ) < 0 )
|
||||
{
|
||||
Q_strncpy( savename, t->filenames[i], sizeof( savename ));
|
||||
newest = ft;
|
||||
|
||||
@@ -80,24 +80,14 @@ def configure(conf):
|
||||
conf.env.HAVE_SDL2 = True
|
||||
else:
|
||||
conf.load('sdl2')
|
||||
if conf.options.SDL3:
|
||||
if not conf.env.HAVE_SDL3:
|
||||
conf.fatal('SDL3 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 3)
|
||||
else:
|
||||
if not conf.env.HAVE_SDL2:
|
||||
conf.fatal('SDL2 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 2)
|
||||
if not conf.env.HAVE_SDL2:
|
||||
conf.fatal('SDL2 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 2)
|
||||
|
||||
if conf.env.DEST_OS == 'haiku':
|
||||
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)
|
||||
@@ -128,6 +118,7 @@ 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
|
||||
|
||||
@@ -181,12 +172,13 @@ def build(bld):
|
||||
source += bld.path.ant_glob(['platform/misc/lib_static.c'])
|
||||
is_cxx_link = True
|
||||
|
||||
if bld.env.HAVE_SDL2 or bld.env.HAVE_SDL3:
|
||||
libs.append('SDL3' if bld.env.HAVE_SDL3 else 'SDL2')
|
||||
if bld.env.HAVE_SDL2:
|
||||
libs.append('SDL2')
|
||||
source += bld.path.ant_glob(['platform/sdl/*.c'])
|
||||
|
||||
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':
|
||||
@@ -230,44 +222,43 @@ def build(bld):
|
||||
'client/*.c',
|
||||
'client/vgui/*.c',
|
||||
'client/avi/*.c'])
|
||||
is_cxx_link = True
|
||||
libs += ['opus', 'bzip2', 'MultiEmulator']
|
||||
libs += ['opus']
|
||||
|
||||
rpath = bld.env.DEFAULT_RPATH
|
||||
includes = ['server', 'client', 'client/vgui' ]
|
||||
|
||||
# Switch and PSVita have custom parameters
|
||||
if bld.env.DEST_OS in ['nswitch', 'psvita']:
|
||||
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:
|
||||
features = 'c cprogram'
|
||||
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:
|
||||
install_path = bld.env.LIBDIR
|
||||
if is_cxx_link:
|
||||
features = 'cxx c cxxshlib cshlib'
|
||||
# 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]
|
||||
else:
|
||||
features = 'c cshlib'
|
||||
install_path = bld.env.LIBDIR
|
||||
features = ['c', 'cxxshlib' if is_cxx_link else 'cshlib']
|
||||
|
||||
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,
|
||||
)
|
||||
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,
|
||||
)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
GetFSAPI
|
||||
@@ -25,7 +25,7 @@ def build(bld):
|
||||
libs += [ 'public', 'ANDROID' ]
|
||||
|
||||
bld.shlib(target = 'filesystem_stdio',
|
||||
features = 'seq',
|
||||
features = 'cxx seq',
|
||||
source = bld.path.ant_glob(['*.c', '*.cpp']),
|
||||
use = libs,
|
||||
install_path = bld.env.LIBDIR,
|
||||
|
||||
@@ -30,8 +30,9 @@ def build(bld):
|
||||
if bld.env.DEST_OS == 'linux':
|
||||
bld.env.LDFLAGS += ['-Wl,--no-as-needed', '-lm']
|
||||
|
||||
bld.program(source = source,
|
||||
bld(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,7 +216,6 @@ 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 ); // Xash3D-specific
|
||||
struct msurface_s *(*PM_TraceSurface)( int ground, float *vstart, float *vend );
|
||||
} playermove_t;
|
||||
#endif//PM_DEFS_H
|
||||
|
||||
@@ -119,8 +119,6 @@ const char *Q_PlatformStringByID( const int platform )
|
||||
return "nswitch";
|
||||
case PLATFORM_PSVITA:
|
||||
return "psvita";
|
||||
case PLATFORM_WASI:
|
||||
return "wasi";
|
||||
}
|
||||
|
||||
assert( 0 );
|
||||
@@ -206,8 +204,6 @@ const char *Q_ArchitectureStringByID( const int arch, const uint abi, const int
|
||||
return is64 ? "riscv64d" : "riscv32d";
|
||||
}
|
||||
break;
|
||||
case ARCHITECTURE_WASM:
|
||||
return is64 ? "wasm64" : "wasm32";
|
||||
}
|
||||
|
||||
assert( 0 );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user