This is just a simple RSA public key digital signature thing built on
libtomcrypt. The gist:
Some admin will generate a public/private key with rsa_make_keys, keeping the
private key secret. Using the private key and rsa_sign, the admin will sign
the autoupdater manifests, generating manifest.txt.sig.
The public key ships with the game (adding 270 bytes to the download), the
.sig is downloaded with the manifest by the autoupdater (256 bytes extra
download), then the autoupdater checks the manifest against the signature
with the public key. if the signature isn't valid (the manifest was tampered
with or corrupt), the autoupdater refuses to continue.
If the manifest is to be trusted, it lists sha256 checksums for every file to
download, so there's no need to sign every file; if they can't tamper with the
manifest, they can't tamper with any other file to be updated since the file's
listed sha256 won't match.
If the private key is compromised, we generate new keys and ship new
installers, so new installations will be able to update but existing ones
will need to do a new install to keep getting updates. Don't let the private
key get compromised. The private key doesn't go on a public server. Maybe it
doesn't even live on the admin's laptop hard drive.
If the download server is compromised and serving malware, the autoupdater
will reject it outright if they haven't compromised the private key, generated
a new manifest, and signed it with the private key.
libtomcrypt is sort of a big pile of source code, so instead of putting it
in revision control, we have a script to download it. Most things don't need
it. It lives on GitHub, so we _could_ do a git submodule, but most people
don't need it, so why waste their disk and bandwidth? That said, when compiled
you end up with a few hundred kilobytes of binary code to verify a signature
and no external dependencies, so it seems like a win.
Previously tested a mod cvar which may be wrong when multiple
mods are involved or config is reset. Let's check the server
cache's internet server count directly.
The blinking disconnect icon is drawn over lagometer in Q3.
Team Arena moved the lagometer location. Now let's draw the
disconnect icon over lagometer in Team Arena too!
"/team score" draws an oversized scoreboard in Q3. In Team Arena
it draws nothing. They probably intended to replace it with the
new .menu UI. But since it didn't happen, go ahead and use the Q3
tournament scoreboard.
- Actually use the second 'force' pass in G_Spawn when out of
available slots.
- Make G_EntitiesFree return qtrue if we can open a new slot.
(Only used when spawning Harvester skulls.)
Fixes not spawning Harvester skulls when there are no 'open freed
slots', but we have other slots available to open.
The Team Arena menu uses red team for single player but q3_ui
(and mods could) use blue. Also handle all the game types, not
just the ones used by Team Arena. Fixes FFA and Team DM.
Opening the find friend menu in the Team Arena server browser
hitches due to trying to resolve blank host names.
In UI_BuildFindPlayerList() status requests that are initial or
completed state or have timed out get reset. This means it starts
with MAX_SERVERSTATUSREQUESTS (16) blank host names. So just ignore
them in UI_GetServerStatusInfo().
The console message "1 servers listed in browser with 2 players."
would count clients multiple times when viewing favorite servers.
When viewing favorite servers in Team Arena UI, servers are added
to list before getting ping response. Each time UI checked pings
and inserted server it incremented the player count.
Filter favorite servers based on cached server info and new info
instead of only the cached info.
If cached server info is filtered out, don't add it to server list
but wait for getinfo response before marking server as invisible.
The player column in Team Arena UI lists clients and max clients
in format of "clients [maxclients]". When sorting by clients the
max clients is ignored which results in player column being
disorganized.
When servers have the same number of clients, sort based on max
clients. Otherwise client sort is sub-sorted based on order of
getinfo responses (ping).
Having to manually request the list, with two buttons (get new
list, refresh list) is somewhat confusing. Also since it looks
like there are no servers, users might not try to figure out
how to get the server list.
The first time viewing a master server list in Team Arena UI,
automatically request a new server list. After that the cache
will be available with a timestamp of the last refresh time.
I think this will make it easier to understand how the menu
works.
This may cause unneeded updating of the server cache because the
last refresh timestamp is per-fs_game but the server cache is
shared by all games. This will only occur once for each game
though so it's not a big concern.
Lots of Linux distros have different names (libcurl-gnutls.so vs etc), and
version the symbols (curl_global_init@@CURL_LIBSSL_3), so it's more compatible
to just dlsym the basic entry points we need and just demand that libcurl is
installed at all.
Alternately: we'll use our own libcurl build, but we'll probably have to dump
SSL support to make this sane to do.
Resolve master server addresses every 24 hours instead of keeping
result forever. Don't clear sv_master[1-5] cvar if the address fails
to resolve; it might work later.
constructions like (dataMask & ~3) was used to protect against out-of-bound load/store when address is 4-byte closer to dataMask
but at the same time it effectively cut low address bits for ALL load/store operations which is totally wrong in terms of conformance to ALLOWED (i.e. generated by q3lcc from C sources) low-level operations like packed binary data parsing
Save argument instead of using a pointer to cmd token memory that
might be overwritten when Cmd_TokenizeString() is called.
No known method for causing the issue without engine changes.
Cmd_TokenizeString() is called by FS_PureServerSetReferencedPaks()
in CL_Disconnect() but it's not an issue because the string is
blank.
Thanks @mickael9.
Check for truncated paths which could allow loading a library with
a non-standard extension. Also provides a better message for why a
valid library with a long path would fail to load.
Processing a callvote command after a vote passed to change maps but
has not been executed yet will result in 1) map change immediately
happening 2) after new map loads players have vote HUD messages but
Game VM doesn't have a vote in progress. The phantom vote status will
only be removed if players start a new vote or run vid_restart.
The underlying issue is that a second callvote sets vote config
strings but a map change is executed before they are sent to clients.
Resulting in clients getting "cs" reliable commands with the config
string changes _after_ the map change. Out of sync config strings.
Even if the underlying issue was fixed, the second vote would be lost.
So it's best to not force a map change to happen immediately anyway.
Reported by Tobias Kuehnhammer.
- Paths to search for mods are now specified in an array
- Mods can now consist solely of ".pk3dir" folders and still be
considered valid
- The function now has a consistent style
+seta, +sets, and +setu were ignored because Com_AddStartupCommands
thought Com_StartupVariable handled it.
+set didn't allow value to be multiple tokens which due to Unix shell
unintuitively removing quotes causes the variable to only be set to
the first token. This could be worked around by escaping quotes
ioq3ded +set g_motd \"hello world\"
but it doesn't match behavior of other start up commands (which now
includes seta, sets, and setu) that use all tokens.
source_t filename and includepath are 1024 but MAX_PATH is 64. As far as
I know the paths don't exceed that so this probably doesn't fix anything.
Similar changes were already made to l_script.c so this makes things
consistent. This was found because it was fixed in RTCW's code.
MISSIONPACK define is already required for this file or else it triggers an #error at the top of the file - removing redundant test that will never occur.
gcc 6 with -Wall -Wextra warns:
code/botlib/l_precomp.c: In function ‘PC_NameHash’:
code/botlib/l_precomp.c:551:2: warning: ‘register’ is not at beginning of declaration [-Wold-style-declaration]
int register hash, i;
^~~
Modern compilers either ignore the register storage class when
generating code, or generate better code without it, so just remove
most of them.
The remaining uses are in third-party bundled libraries (libjpeg, zlib),
and in a PowerPC-specific inline function consisting of inline
assembler (because I'm not 100% confident that it doesn't have
some practical use there).
If ERR_DROP during Com_GameRestart after shutting down client, Com_Error
needs to restart the client otherwise there is just a black window. Also,
clear the game restarting flag in Com_Error otherwise it's not possible to
run Com_GameRestart again later.
I don't know of a way to trigger ERR_DROP, in FS_Restart for instance,
without engine changes however.
Offer to restore settings when loading a mod that crashed, not the first
mod that gets loaded after a crash. Before the first mod loaded (usually
baseq3) would get the option even if missionpack or some other mod crashed.
- Make pid files separate for each fs_game.
- Remove/write pid every time switching fs_game.
- Create path before writing pid file otherwise it fails on first run.
- Show mod description.txt or fs_game instead of engine name in abnormal
exit message.
- Check com_fullyInitialized in Com_Error before removing PID,
otherwise "ioquake3 --version" segfaults when accessing fs_gamevar->string
(plus not fully initialized isn't really a normal shutdown).
As with the other branch of the if/else, each element of
foundPlayerServerNames is in fact the same size as each element of
foundPlayerServerAddresses, so it was fine; but it's better to make
it obvious that we are using the right array sizes.
This function is used in the Team Arena menus
I don't think it's actually possible to reach this line with
foundPlayerServerNames < 1, because by the time we get here we have
set it to 1 + the actual number of servers; but if we did, it would
clearly underflow into foundPlayerServerNames[-1], which would be
undefined behaviour. gcc 6 diagnoses this with a warning:
code/ui/ui_main.c: In function ‘UI_BuildFindPlayerList’:
code/ui/ui_main.c:4138:16: warning: array subscript is below array bounds [-Warray-bounds]
Also correct the sizeof() invocation to make it more obviously
correct (in fact the buffers for names and addresses happen to both
be of size MAX_ADDRESSLENGTH, so it was fine, but it's good to be
obvious).
Given an array b[] of length n, pointers to &b[0]..&b[n] are defined
(where only &b[0]..&b[n-1] can be validly dereferenced). &b[-1], or
equivalently b-1, is not something we can use in valid Standard C.
gcc 6 diagnoses this as:
code/client/snd_wavelet.c:33:9: warning: array subscript is below array bounds [-Warray-bounds]
and might take this undefined behaviour as permission to emit
"more efficient" object code that is not what the author expected,
for example nothing at all. Use a macro to fake a 1-based array instead.
The goal of reproducible builds is that a rebuild of the same source
code with the same compiler, libraries, etc. should result in the same
binaries. SOURCE_DATE_EPOCH provides a standard way for build systems
to fill in the date of the latest source change, typically from a git
commit or from metadata like the debian/changelog in Debian packages.
This does not change anything if SOURCE_DATE_EPOCH is not defined;
the intention is that a larger build system like a Debian package
will define it.
Please see https://reproducible-builds.org/ for more information about
reproducible builds.
Bot's lastkilledplayer was set to -1 after carrying out an ordered kill.
Later in BotChat_Random() the PlayerName function was passed -1 which
caused a "Error: PlayerName: playernum out of range" message.
I think the reason it was set to negative one is so that if the bot is
ordered to kill the player again, the bot will not say it's done and
drop the goal. Though, if the bot killed the player based on it's own
decision, it will just say it's done and drop the goal (bug?).
Let's check the time of the last kill to see if it happened since the
team order was received instead of setting lastkilledplayer to -1
after completing the team ordered kill. This fixes bot dropping goal
if target player was the last player they killed and the PlayerName
out of range error.
At the end of CL_RunCinematic, RoQShutdown sets currentHandle to -1.
This causes the return at the end to be return cinTable[-1].status.
Use return FMV_EOF when RoQShutdown is called.
I think FMV_EOF should be returned instead of FMV_IDLE which is set in
RoQShutdown because RoQShutdown is clearing out state so it can be reused
for a new cinematic.
The return value isn't actually read by the ioq3 client, renderers,
cgame, or ui.
Make Yes/No, Multi, Slider, and Bind items allow enter key to change
value without mouse over item. Add support for left and right arrow keys
and joystick button 1-4 to Yes/No, Multi, and Slider and many item
specific 'ownerdraw' key handlers.
Listbox still requires mouse hover and Team Arena main menu requires
mouse hover to get anywhere...
Enabling K_JOY1-4 to select in default key handler also caused additional
mouse button (K_AUX1-16) to select, which is done in q3_ui as well. Both
handle K_AUX equally badly (not treated as a mouse button and not handled
by item specific key handlers), so it's probably fine.
Explicitly set cull type for skybox to front, instead of using whatever
cull type the previous shader used (which could result in the skybox
not being visible due to only drawing back faces). The sky cloud stages
set the cull type so they are not affected by previous cull type.
Server/client VoIP protocol is handled by adding new cvars
cl_voipProtocol and sv_voipProtocol, sv_voip and cl_voip
are used to auto set/clear them. All users need to touch
are cl/sv_voip as 0 or 1 just like before.
Old Speex VoIP packets in demos are skipped.
New VoIP packets are skipped in demos if sv_voipProtocol
doesn't match cl_voipProtocol.
Notable difference between usage of speex and opus codecs,
when using Speex client would be sent 80ms at a time.
Using Opus, 60ms is sent at a time. This was changed because
the Opus codec supports encoding up to 60ms at a time.
(Simpler to send only one codec frame in a packet.)
The number of draw surfaces was range checked against number of surfaces for
the current view but needs to check total for the frame otherwise can read
past the end of the tr.refdef.drawSurfs array when there are multiple views.
Reserve space for end of list and swap buffer commands. These are absolutely
required and cannot be dropped. Dropping swap buffer command causes screen
to not update and possible crash from drawsurf buffer overflow if not enough
cmd buffer space for many continous frames.
Text_Width's scale argument will be multiplied by glyphScale, so don't
pass useScale that is already multiplied by glyphScale as this makes
the scale too big.
GNU platforms (Linux, kFreeBSD, Hurd) have endian.h to determine
endianness, so all architectures except x86_64 are in fact treated
identically, except that their ARCH_STRING is different.
The ARCH_STRING must always be identical to the ARCH from the Makefile,
otherwise the engine will not find its cgame, game and ui plugins
under their expected names and startup will fail. If we pass it in
from the Makefile, then an identical value is guaranteed, and we can
get rid of an increasingly long list of defined(__some_cpu__) tests.
The one remaining quirk is that we test __x86_64__ to determine
whether to define idx64; I've kept that, but separated it from
the ARCH_STRING.
On non-Linux platforms we only support a few architectures anyway,
so keeping the list up to date is less of a burden; *BSD porters
could probably use the same technique to get support for lots of
architectures with little effort, but I have not done that here,
because I cannot test it.
Windows must continue to support preprocessor-based architecture tests
in any case, so that the MSVC solutions (which do not use the Makefile)
can continue to work. However, Windows only runs on a few CPU families,
so this shouldn't be a significant burden in practice.
When cross-compiling, the tools are compiled for the build architecture
(COMPILE_PLATFORM, COMPILE_ARCH) rather than the host architecture
(PLATFORM, ARCH), so define ARCH_STRING to COMPILE_ARCH on a GNU
COMPILE_PLATFORM.
MASK_REG in EmitMovEDXStack would incorrectly emit asm if 'andit' was 0.
'andit' would never be 0 though so it wasn't causing issues.
Found by Coverity.
Windows' Sys_ListFiles would add files that contain the extension anywhere,
not only at the end of the file name.
Example: "word.pk3omghacks" use to be loaded as a pk3 file.
My last commit made it so that CGame "waterlevel 1" is feet in water,
but before it was erroneously about waist deep in water. The places
where it is checked it is suppose to be view position underwater.
Change comparisons to use correct value for view position underwater.
CG_WaterLevel() added lerpOrigin to itself instead of adding view height
when checking for waterlevel 2 and 3. This did not cause issues because
ioq3 only compared the calculated waterlevel to more or equal to 1.
Cinematic's startTime and lastTime are always set from CL_ScaledMilliseconds
which returns int and are converted back and forth to int and unsigned int.
This fixes a warning that abs() is used on an unsigned int.
If a bot is accompanying someone before map change or restart, the bot would
continue accompanying them but press up against them and orbit around them.
This is caused by the bot's formation distance being 0.
Save the formation distance so they maintain proper distance and do not
orbit around the player.
When the engine is compiled with Clang it appears that the return value
is being written to the WRONG address, either due to the vm_ variables being
changed (unexpectedly) elsewhere, or as a result of bad assembly assumptions;
having a stack variable pointing to where to write the return value seems
to do the trick.
This fixes the case where, for a trap_Register()-like call, weird numbers
are being returned when, during the process, an error message is printed
(which in Tremulous results in a QVM call and (nested) system call).
The renderer color is set to health color when drawing crosshair. After
drawing the crosshair, the renderer color was not cleared and could affect
other things. With cg_draw3dicons 0 and cg_drawCrosshairNames 0 it affected
the attacker icon.
Hopefully fixes the following warning
cg_draw.c:2315 assuming signed overflow does not occur when assuming that (X + c) < X is always false [-Wstrict-overflow]
Revert last commit so that grapple sky check is compatible with BSPC
BotImport_Trace in (removed from repo) code/bspc/be_aas_bspq3.c.
Set bsp_trace_t::surface.flags instead of surface.value to trace_t::surfaceFlags.
surface.flags is only used for the sky check for grapple AAS reachability.
surface.value is not used at all.
bsp_trace_t is not part of the game VM API, so this does not affect VM compatibility.
BotAI_Trace in game was changed to match server. surface.value/flags are not used in game.
Only send mouse events if both values are non-zero.
Hopefully this helps with the event overflow spam that can sometimes
happen on loads or laggy situations.
q3_ui would shown bot at index of number of bots in list.
game would send empty name to addbot command and command would think skill
(i.e., 2.000000) was the bot name.
"orders" menu script is not used by Team Arena.
The same C format string was given an int or string argument depending on if
ordering a single person or everyone. Make it always use int.
Sys_SetFloatEnv in sys_unix.c existed but was not called. It sets the
rounding mode to "to nearest" which is the default on Linux. Might be
required on other platforms, I don't know.
Using unix mode 0666 for creat was causing crashes when compiled with MSVC.
So use the marcos recommended by MSDN. MinGW also has the marcos, so apply
to Windows builds in general.
Similar to one of the changes by Tim Angus in fd986da: mbstowcs' third
argument is the number of wchar_t available in dest, not the number
of bytes.
This does not appear to be exploitable, because ioquake3 does
not actually call mumble_set_identity() or mumble_set_description()
anywhere, but it might be relevant to derivatives.
Spotted via compiler warnings.
Fixed LCC to correctly diagnose expressions with NPC. It no longer reports messages such as
warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent
[17:58] <Jacker> hey, you might be interested in checking out this
4da5a397b5 (diff-acaedc9d8b492f9af8966ae68597392cR615)
[17:58] <Jacker> its related to the ddos protection code you wrote
[17:59] <Jacker> in continuation to:
ab9b08e584
[17:59] <Jacker> in a case if the client has in the past connected to
the server days/weeks earlier and time wraps the client wont be able to
connect
[18:00] <Jacker> since in that case if the bucket of that clients ip
still exists it wont get checked correctly
Game sets CS_INTERMISSION to 1 at intermission, but does not clear it at
map_restart so it's only sent the first time. CG_MapRestart manually clears
cg.intermissionStarted (which is set to value of CS_INTERMISSION when it's
modified). So subsequent intermissions do not have cg.intermissionStarted
enabled.
Now CS_INTERMISSION is cleared and sent each time intermission is started
and cg.intermissionStarted is enabled each time.
This makes subsequent intermissions not play sounds in CG_CheckLocalSounds
during the 1 second between intermission starting and switching to scoreboard
(PM_INTERMISSION) and makes Team Arena voice chats not play.
Team Arena's text functions cast signed char values to int and use as an array index.
This works fine for values 0 to 127, but not for -128 to -1 which are a negative array index.
Instead use "character & 255" like client and original Q3 ui/cgame string drawing code.
The glyph for character 255 (lower case y with two dots above it) was
rendered, but it's glyph information was not stored in fontInfo_t and
not saved into .dat file (including the ones in Team Arena).
Attempting to load it from existing .dat font files is fine because
shader name is "" and gets 0 handle. The handle was already 0 anyway.
Stencil shadow is not drawn if a mesh, or multiple meshes with the same
entity and shader, have more than 500 vertexes. The issue is caused by storing
the projected positions in the tess vertex buffer. Use a new array instead.
GL1's R_CreateImage sets GL texture to 0 before it ends, so border color is not
applied to the fog image. GL_CLAMP is not used for fog image (in either renderer),
so it would presumably not be used even if applied to the fog image.
When starting the game in windowed mode, the window buffer used whatever
was on the screen before running the game. Kind of like you could see
through the window, but it doesn't update what happens behind it.
It makes it look like something is broken or non-responsive.
So clear the window opengl buffer to black.
Credit to theinvsblman for the code.
Fix CalcFog in generic_vp.glsl to fog fogged surfaces.
Now it's the same as CalcFog in fogpass_vp.glsl.
Fixes shaders that use adjustColorsForFog. Impact wallmarks, blood sprites, flame textures and so on.
This makes pasting in client console and UI edit fields work on X11 and OS X.
Sys_GetClipboardData is only used by client, so returning NULL in dedicated is fine.
External GLSL should probably only be used for development testing,
not released products. The GLSL files are tied to the code, and the
code changes some what often.
Fixes using OpenArena 0.8.8 which has incompatible GLSL files in a pk3.
The text lines don't meet at top of the sceen in 1920x1080, restore
drawing a cut off line across the top. In 640x480 this line isn't seen
at all. This is still better then trying to draw twice as many lines
than are actually seen (the way it was before the last commit).
In the renderers, dlightbits are never cleared from world surfaces.
The dlight image does not repeat, so if it draws on extra surfaces it's
not visible.
However if using a repeating image (tr.defaultImage instead of tr.dlightImage);
* In OpenGL1 image is only drawn on surfaces close to dlight origin.
* In OpenGL2 image is draw on surfaces clearly outside the dlight radius, including past non-dlighted surfaces.
It seems there was a similar issue with pshadowBits. So update surface
dlightBits even if 0, like already done for pshadowBits. This causes
only surfaces close to origin to be affected. (Though it is a little
farther than in OpenGL1.)
I have no idea why this isn't a problem in OpenGL1.
Zero length lightmap lump will have NULL tr.lightmaps.
OpenGL1 already has this check, because r_vertexLight 1
would crash Team Arena. OpenGL2 does not disable loading lightmaps
when r_vertexLight is 1 though, so it does not have that issue.
SDL1.2 branch disables key repeat when key catcher is 0.
Presumably to prevent binds from executing multiple times.
SDL2 replaced being able to disabled key repeat using SDL_EnableKeyRepeat
with a non-zero repeat value in the key event.
UI's PositionRotatedEntityOnTag is different than CGame's and
UI has switched pitch/roll for Gauntlet/BFG axis to get it to
look like /close to/ how it looks in CGame.
Making UI use the same *PositionRotatedEntityOnTag and axis as
CGame fixes the Gauntlet blade being wobbly in controls menu.
In Team Arena's Harvester mode, players corrupt your memory from beyond
the grave. Gib the players to stop the corruption!
CG_PlayerTokens is called for player entities, including corpses.
The entity number is used for the index in cg.skulltrails which only has
MAX_CLIENTS elements. This results in incorrect memory being overwritten
for corpse entities (as the entity number is >= MAX_CLIENTS).
So limit skull trails to valid entities (entity number < MAX_CLIENTS).
If a pk3 search path is passed to FS_FOpenFileReadDir, a non-zero
file handle is returned if file is not found. This causes incorrect
behavior in FS_ReadFileDir (when a pk3 search path is passed in)
which only checks file handle, not length, for seeing if file exists.
I don't know of any issues in ioq3 caused by this.
Setting SDL_GL_ACCELERATED_VISUAL was disabled for ioq3 SDL 1.2
for other reasons. However, it causes creating GL context to fail
if multisampling is enabled on X11 for both SDL1.2 and SDL2.
Tested using nVidia proprietary driver on Debian 7.
It doubles the size of the data compared to the default (22050),
so increase the buffer automatically. Likewise, decreasing speed
doesn't need as much (though that doesn't really matter).
If spawn var key or value is "" it caused R_GetEntityToken (available to
cgame, used by opengl2) to stop parsing, whereas game VM would continue.
Changed it to match parsing used for game VM
(see G_GET_ENTITY_TOKEN in code/server/sv_game.c).
The map poq3dm5 has a "wait" key with value "".
When R_GetEntityToken returns qfalse it resets pointer for parsing, by
R_ParseSpawnVars not returning qfalse it could cause an infinite loop.
Also add newlines to printfs.
Vertex lite surfaces being brighter than light maps looks bad,
they're meant to look the same. Especially in ET, which mixes
them fequently. It's noticeable in Q3 too though.
BSP lightmaps (i.e. not external HDR lightmaps) use
R_ColorShiftLightingBytes, now *Floats (used by vertex colors)
has the same behavior.
This may be a problem for HDR lightmaps, as the RGB will always be
scaled to 0.0 to 1.0 range.
I had enabled this for non-HDR before, but now HDR needs it too.
After playing Team Arena, if you switch to Q3A and try to play a demo with
cl_allowDownload enabled it would print "Need Paks: blah blah" and not play the demo.