Add additional checks to ensure that the `CVideo::Stop` function and the functions called by it will correctly stop the current video also if the video was not started successfully, i.e. if `CVideo::Start` returned `false` from any of the error branches.
In the `CVideo::Stop` function, iterate over the vectors of video and audio threads directly instead of using `m_VideoThreads` and `m_AudioThreads`, which do not reflect the actual count if the initialization failed before the threads were created.
In the `CVideo::Stop` function, only call `av_write_trailer` if the video recording was stated successfully, i.e. only if `avformat_write_header` was called successfully, as this will otherwise cause the client to crash. Closes#6375.
In the `CVideo::Stop` function, only call `avio_closep` if the format context was allocated.
In the `CVideo::FinishFrames` function, ensure that the codec has been allocated and opened, otherwise using it is not allowed.
Add assertions to the `CVideo::Start` and `Stop` functions to ensure that the same video is not started/stopped multiple times.
Crash with assertion when the size of the graphics is different from the video currently being rendered, instead of causing weirder bugs and a corrupted video file.
The wrong sampling rate was being used for video recording if the client is not restarted after changing the `snd_rate` config variable.
Ensure that the correct bit rate is used if the sample rate was adjusted because the selected value is not supposed.
Use `log_error` for all errors and consistently format all error messages.
Handle all ffmpeg errors and output the formatted ffmpeg error message when possible.
Register a log callback for ffmpeg log messages to delegate them to our logging system, to fix the log messages being interleaved with our log messages and not using the correct line breaks on Windows.
Stop video and demo immediately and show an error message popup if the video could not be started successfully.
Remove unnecessary debug output from ffmpeg.
Removed member prefix m_ used for local variables.
Removed all b, c, i hungarian notation prefixes for boolean, const and integers.
Fixed local variables using lower_snake_case instead of UpperCamelCase.
Renamed all ``float wSearch = TextRender()->TextWidth..`` to ``float SearchWidth = ..``.
When using the `remove_vote` command, the entire heap of vote options is allocated again without the entry being removed. This allocation was not considering the required alignment for `CVoteOptionServer` objects and potentially wasting space by aligning with `alignof(std::max_align_t)`. When allocating the entries with the `add_vote` command, the alignment is already specified correctly.
Relevant upstream commit:
d2924b5ad6
Closes https://github.com/ChillerDragon/ddnet/issues/7
The snap item obj_character contains a field called m_TriggeredEvents
https://chillerdragon.github.io/teeworlds-protocol/07/snap_items.html#obj_character
It is responsible for effects and sounds. Those flags are set in the gamecore.
So if the servers gamecore ticks twice and resets the flags before a snap is
sent the client misses the information. Which is not too big of a
problem since the client has his own gamecore running (prediction) which
also sets those flags. But it is still wrong and teeworlds does always
include the triggered events in the snap.
So this commit fixes it using the same approach as teeworlds.
By not resetting the triggered events until a snap was sent.
Always use the server address from the network client to reconnect to the correct server after being disconnected due to wrong password. The password popup is only shown after being disconnected, so the server address of the network client should always the address of the server which the client should reconnect to with the password. Using `ui_server_address` was causing the wrong address to be used after being redirected to another server and if the config variable is changed while the password popup is open.
Closes#8260.
Fix leak of pending future logger log messages if the future logger is not set, in particular when the `logfile` config variable is not set or the file could not be opened, by setting a logger that discards all log messages in this case.
Closes#8265.
When changing the screen width, height or refresh rate config variables to 0 or negative values, which are not allowed by the backend, automatically revert the config variables to the actual values again to ensure that the config variables stay in sync with the state of the window. This fixes the client crashing in the graphics settings when setting the screen width and height to 0 via the console, which causes a division by zero when calculating the aspect ratio.
According to the documentation, this function returns `0` on success and a negative number (error code) otherwise, which would cause an allocation of an invalid size.
The third parameter of the `op_read` function specifies the remaining size of the buffer, but we always passed the total size of the buffer without respecting the position at which the data is written into the buffer.
Set the data pointer of the sample only when the sample has been loaded successfully, so the invalid sample data is not freed again when decoding fails.
Otherwise the snapshots may incorrectly be invalidated because a change of the `cl_dummy` variable is detected when connecting to another server after disconnecting while the dummy is active.
Send dummy ready and enter game when connection is online based on its state instead of when the security token is not unknown anymore, which should effectively be the same condition but more understandable. This is also how it's already done for the main connection so the `SecurityTokenUnknown` function can be removed as it's unused now.
The console was not keeping its current scoll position if entries from the backlog are removed due to being recycled when new entries are added. For this purpose, a callback function is added to the ringbuffer to handle popped items, so the scrolling position of the console can be updated based on the number of lines of the removed backlog entries.
Fix backlog corruption in `CConsole::PumpBacklogPending` when many backlog entries are allocated at the same time. When allocating many entries from the `m_Backlog` ringbuffer at the same time, the first entries being allocated may already have been recycled again, so the pointers to them being stored in the temporary vector of new backlog entries were pointing arbitrarily into the ringbuffer data, which could cause corruption of the structural and user data of the ringbuffer. Now, we iterate over the entire backlog and only update uninitialized entries instead of storing the new entries separately.
This was sometimes caught as a misaligned access with UBSan:
```
src/engine/shared/ringbuffer.cpp:160:14: runtime error: member access within misaligned address 0x00014126f4df for type 'struct CItem', which requires 8 byte alignment
0x00014126f4df: note: pointer points here
<memory cannot be printed>
0 0x5825349a6a1c in CRingBufferBase::Prev(void*) src/engine/shared/ringbuffer.cpp:160
1 0x5825334e8934 in CTypedRingBuffer<CGameConsole::CInstance::CBacklogEntry>::Prev(CGameConsole::CInstance::CBacklogEntry*) src/engine/shared/ringbuffer.h:59
2 0x5825334d13e6 in CGameConsole::OnRender() src/game/client/components/console.cpp:1259
3 0x582533bce058 in CGameClient::OnRender() src/game/client/gameclient.cpp:715
4 0x582532f3cc44 in CClient::Render() src/engine/client/client.cpp:894
5 0x582532f9d236 in CClient::Run() src/engine/client/client.cpp:2971
6 0x582533002e5e in main src/engine/client/client.cpp:4523
```
Fix out-of-bounds accesses when rendering ghost players, which use the client ID `-2`. This was causing the hook collision line of ghost players to be affected by real players, which is not correct, as ghosts do not interact with other characters.
Closes#8239.
Add optional filename argument to `start_video` command, to start recording to a video file with a specific filename, instead of always using the current timestamp.
Add log messages to `start_video` and `stop_video` commands to indicate success and errors.
Make the `CClient::StartVideo` function non-`static` and reduce duplicate code in the `Con_StartVideo` function.
Determine the video filename outside of the `CVideo` constructor, same as for demos.
Fix game times and prediction not being updated when only exactly two snapshots have been received, due to the conditions `m_aReceivedSnapshots[...] >= 3`. These specific condition are not necessary and replaced with simpler checks whether the current snapshot is set. Some duplicate nested conditions are also removed.
Pump the network first in `CClient::Update` before updating anything else, to ensure that snapshots are received from the network client before the game times and prediction are being updated based on the current snapshots.
Fix current and previous game tick always being `0` on the first call of `IGameClient::OnNewSnapshot` when two snapshot have been received. Now, the game ticks are properly initialized from the two initial snapshots.
Fix old inputs sometimes being used in prediction after changing map because inputs with tick `-1` were not being ignored.
Ensure all snapshots and game times are properly cleared when entering the game.
`GetConsoleMode` can fail with `ERROR_INVALID_HANDLE` when redirecting output to `nul`, which is considered a character file but cannot be used as a console.
The purpose of this condition is to only update the freeze time every 50 ticks so the freeze bar keeps being refilled after one second when standing in freeze, but it incorrectly prevented freeze from being applied during the first 50 ticks after the map has been loaded. Now, freeze is also applied if not currently frozen, so the behavior directly after changing the map is identical to subsequent respawns.
Clear current server info when playing demos to ensure that the score kind (points, time) is detected correctly. Previously, when playing a demo with points score kind and `cl_demo_assume_race 0`, the score was not shown as points when the last server that the client connected to had a race gametype.
Move the implementation for `cl_demo_assume_race` together with the rest of the demo server info initialization in the `CClient::DemoPlayer_Play` function.
The demo player needs to be rendered also when the menu is inactive, to handle the hotkeys for controlling the demo player and to render the play/pause and speed indicators.
Closes#8208.
These conditions are contained in an `if(State() == IClient::STATE_ONLINE)` branch and the state does not change while inside this branch, so these checks are unnecessary.
Previously, when connecting to servers repeatedly, the local tee would appear at the position it had on the previous server for a short time when joining.
This (and potentially other bugs) are fixed by clearing all game related `CGameClient` member variables in the `OnReset` function. Additionally, the `OnReset` function is now used in the `OnInit` function to ensure everything is initialized correctly when starting the client and to avoid duplicating the code.
In particular, this bug was limited to use of `cl_predict 1`, because the predicted gameworlds were not being reset when disconnecting, causing the predicted world and character from the previous server to be used. This bug was introduced in version 15.6, which added the predicted gameworlds in #1620. Closes#4339.
For the internet/favorite tabs, instead of combining the country/type filters of all communities in one view, track the country/type filters separately for these tabs using the new, reserved community name `all`. This should make the filters less confusing to use, as changing the country/type filters in one tab will not influence the other tabs anymore. Though the country/type filters of the internet and favorite tabs are still combined, as this is also the case for the community filter.
However, this made it possible to select country/type filters that exclude all servers, by first excluding some countries/types and then changing the selected communities so all selectable countries/types are excluded. To prevent this, the filters will now include all countries/types, if they would otherwise exclude all selectable countries/types.
To do this more efficiently, the community cache is moved from the menus to the engine serverbrowser. To avoid using the UI page in the engine serverbrowser, the serverbrowser type is instead used to detect if the community cache should be updated. This required additional changes in the menus to ensure that the UI page and the serverbrowser type stay in sync with each other, which would otherwise cause incorrect server entries to be shown for one frame when switching tabs. The serverbrowser type is now refreshed immediately when the menu page is changed with the `CMenus::SetMenuPage` function, which allowed removing duplicate code for the server browser tab buttons. The `CMenus::RefreshBrowserTab` function does not take the page to be refreshed as argument anymore, as it always was only used to refresh the current page. Instead, a `bool` argument is used to specify whether the refresh should be forced even if the server browser type has not changed.
Closes#8158.
Adding the snap to the demo is the last usage of `pTmpBuffer3`
all prior usages of it copy the data if needed.
So we can edit it in place. No need to copy it into a new buffer.
Remove unnecessary, inconsistent margin at the top of all settings menus.
Reserve space for restart message and button only when necessary, so more height is available for settings menus per default.
Improve vertical alignment of restart message and button with settings menus.
Ensure consistent margin on all sides of settings menus.
Use consistent margins for all settings pages and titles.
Fix chat preview overlapping with the restart warning.
Simplify layout code. Remove array of `CButtonContainer`s with arbitrary size and use individual variables instead.
Simply hide the favorite community tabs in the offline server browser with screen resolutions where not enough width is available.
The ingame server browser can always show at least 5 favorite community tabs with all screen resolutions.
Skip rendering various client components (players, ghosts, nameplates, HUD etc.) while not ingame to improve performance. This increases FPS when rendering the start menu by around 300-400 both in debug and release builds.
This also fixes potential crashes when components using the map data where rendered while the client is loading a new map.
The rcon username requirement was not reset correctly when disconnecting from a server while connecting/loading, at which point the `NETMSG_RCONTYPE` message has already been received.
Closes#4170.
Pass `CImageInfo` arguments to various graphics and text render functions instead of passing the components (data pointer, width, height, format/pixel size) of the image info separately.
Pass texture/file name to loading functions when available to improve error/warning messages.
Split menu rendering explicitly by client state. This makes the code more readable by not mixing code for rendering different states together as much and fixes issues where the menu was being rendered inconsistently for one frame when the state is changed, at the cost of some additional duplicated code.
The fullscreen popups shown when in the connecting and loading client states are now hard-coded for these states, instead of being mixed together with the other fullscreen popups, which can be shown when offline, ingame or during demo playback.
As a side effect of rendering the demo controls like the regular menu, the UI color will now also affect the demo controls menu background.
Move `CBackground::ChangePosition` calls inside functions to reduce duplicate code and improve readability.
Remove unnecessary `CMenus::m_ActivePage` variable.
Closes#7834.
The function `fs_makedir_rec_for` for recursively creating folders did not handle paths containing backslashes correctly and only created folders after every occurrence of a regular slash. This could cause the recursive folder creation to fail when a parent folder is not created before the child folder. For example when recursively creating folders for the path `D:\Games/DDNet\downloadedskins`, the `DDNet` folder was not being created because this path segment does not end in a forward slash. Now, backslashes are handled the same as regular slashes, which is consistent with the other filesystem functions.
Additionally, the function tried to create folders for drive letters on Windows (e.g. `C:` and `D:`). Trying to create a system drive as a folder will fail due to access being denied, whereas it seems to work for already existing non-system drives. For example when recursively creating folders for the path `C:/Games/DDNet/downloadedskins`, the `C:` "folder" could not be created which caused the entire operation to fail. Now, the function will not try to create folders for drive letters anymore, i.e. if the name of the to be created folder ends with `:`.
Closes#8148.
m_FreezeStart is now corrected by the ticks the character was paused
Possible physical changes: Until now it was possible if you sit inside freeze to re-freeze instant
after unpause. Now you re-freeze after the second that was dawned before
the pause. I do not excpect that this is used on any map, and it did not
bring any benifit.
Invalid UTF-8 will not be read from config files with `CLineReader` anymore and the local console never allowed entering invalid UTF-8, so this additional mangling of invalid UTF-8 string config variable values is unnecessary.