Put the context name in quotation marks in the warning message.
Rename parameter `pFileName` to `pContextName`, as this name does not necessarily describe a file.
Rename parameter `Img` to `Image` for consistency.
The function is unused and because the message is not flushed it would also not have worked correctly. The `NETMSG_INPUT` message is already packed and flushed in the `CClient::SendInput` function.
Closes#8408.
Track whether the dummy is currently connecting separately so the dummy being disconnected due to errors can be detected. Show an error message as echo in the chat when the dummy could not be connected, e.g. when the server is full.
Use the global time for limiting the dummy connecting delay instead of using game ticks, so the delay also works correctly when having connection problems (i.e., when ticks do not advance). Handle the dummy connecting being delayed separately from the dummy currently connecting.
Add tooltips for the "Connect dummy"-button when it's disable due to dummy not being allow on the server or when connecting is delayed.
Add console error messages for `dummy_connect` command.
The image data was not being freed when `IGraphics::LoadTextureRawMove` is used with images that are not in RGBA format as this falls back to using `IGraphics::LoadTextureRaw` which requires manually freeing the image data.
Also consistently clear all image info in `LoadTextureRawMove`. This makes it necessary to store the size of the preview image in the editor separately, as previously the width and height of the unloaded image info were being used to render the preview image.
Previously, IME composition strings were limited to at most 32 bytes, e.g. 10 Hiragana characters. Now, `SDL_TextEditingExtEvent` (`SDL_TEXTEDITING_EXT`) is supported, which uses heap-allocated composition strings of arbitrary length.
On the other hand, the buffer for input event text was larger than necessary, as SDL text events only contain at most 32 bytes (`SDL_TEXTINPUTEVENT_TEXT_SIZE` is not used directly to avoid the include). With the hint for extended IME handling enabled, long composition text will be sent as multiple text events (without breaking UTF-8).
Add constants for BPP and alpha threshold during Dilate, as dilating only works for RGBA images and we only use a fixed alpha threshold.
Move local variable declarations closer to their usages.
Use `mem_copy` instead of for-loop.
Use `nullptr` instead of `NULL`.
Only ban DNSBL blacklisted players once when joining immediately after the DNSBL result is available, to prevent current players from having their runs ended when the `sv_dnsbl_ban` setting is enabled.
Note that enabling `sv_dnsbl` and `sv_dnsbl_ban` at the same time will still cause the players to be banned immediately. To prevent this, first enable `sv_dnsbl` for at least one tick, then enable `sv_dnsbl_ban`.
Closes#2640.
* Refactors the previous code segment
* Fixes 'auto' GPU identification and display in DDNet Graphics tab of
the settings. The 'auto' GPU is the best one encountered in the VK
physical device enumeration array until we encounter one that is
at least "integrated" when accessing them in increasing order
* Selects the first GPU that matches a name when using one by user
specified name
Add support for touch input to the engine, UI and console. Ingame touch controls require more discussion and will be delivered separately based on this engine implementation.
Engine
------
The state of all currently pressed touch fingers is aggregated based on the SDL touch events and can be retrieved with the `IInput::TouchFingerStates` function. This design is less complex than an event-based system where the touch events are delivered to the individual client components, as each system would then have to keep track of the finger states individually. However, this means that only one component can handle touch fingers at any given time, which seems like a reasonable assumption for our use cases.
Obsolete code for relative mouse handling on Android is removed. Connecting a mouse to an Android device should now also work as expected, as more recent SDL/Android versions support relative mouse input natively.
User Interface
--------------
Support absolute mouse positioning and clicking in the user interfaces (menus, editor, demo player) with touch presses.
Support right clicking by pressing and holding one finger at roughly the same position for 0.5 seconds.
Support scrolling scroll regions up and down with a two finger swiping gesture. Fast scrolling via a two finger flinging gesture is not yet supported and would be a useful future extension.
The menus and demo player are fully usable with touch inputs. The editor is only fully usable with an external keyboard and/or mouse, as panning the map is not currently possible with only touch inputs, which is also left as a possible future extension.
Console
-------
The touch input logic for the user interface is reused for the console. Thereby, text selection in the console with touch input works, although the text can only be copied by pressing Ctrl+C with an external keyboard at the moment. In the future, we could add buttons to the console to activate the search and copy functionalities with touch inputs.
Support scrolling the console history up and down with a two finger swiping gesture.
The local/remote consoles can currently only be opened with an external keyboard. The ingame touch controls will also include buttons to open the consoles.
The `in_channel_count` and `out_channel_count` properties of the `SwrContext` were already deprecated and have been removed in the most recent ffmpeg library version, hence rendering demos was causing an assertion error when these properties were set.
For newer ffmpeg versions, we now set the channel layout with the `in_chlayout` and `out_chlayout` properties instead of setting the number of channels.
Restarting the client previously did not work, as the `shell_execute` function on Android uses `fork` which is not supported.
Now, the client is restarted by using an Android intent to restart the main activity. This is triggered by sending a user-defined message from the native code to the SDL main activity thread.
Changing the `sv_max_clients` config variable while the server is running does not change the maximum number of clients that can connect, as this is determined only once when the `CNetServer` is initialized. The reserved slot check and the calculation of the number of player slots for the `protocol7::CNetMsg_Sv_ServerSettings` message were using the `sv_max_clients` config variable directly, which was causing them to be out-of-sync with the real number of maximum clients.
Existing uses of the `sv_max_clients` config variable, except for the `CNetServer` initialization, are replaced with `MaxClients()`. The config variable `sv_max_clients` is now marked as read-only after reading the initial config and command line argument, so changing it via the remote console is not possible and shows an error message. The unnecessary conchain for `sv_max_clients` is removed.
Use the real number of maximum clients returned by the `MaxClients()` function instead of the `MAX_CLIENTS` constant to calculate the debug dummy client IDs to fix a crash when `sv_max_clients` is below `MAX_CLIENTS`.
Ensure the `dbg_dummies` value does not exceed the maximum number of clients.
The item data size is already returned by the `IClient::SnapGetItem` function and getting only the size is not currently useful, so the additional `IClient::SnapItemSize` function is unnecessary.
Let the `IClient::SnapGetItem` function return an `IClient::CSnapItem` directly instead of passing it as a pointer. Add the item data pointer as a member variable to `IClient::CSnapItem` instead of returning it separately. Therefore, the separate data pointer of the class `CSnapEntities` is also not necessary anymore.
Consistently mark the snapshot items and data as `const`. The C-style cast to `void *` in the `IClient::SnapGetItem` function was previously implicitly casting away the `const` of the snapshot pointers.
Opening links and files with the `open_link` and `open_file` functions does not work on Android, as the `open_link` function uses `fork` which is not supported on Android. This also seems to cause a strange bug where client networking partially breaks. Currently, after trying to open any link, connecting to servers is not possible anymore but the server browser still works, with the connection getting stuck randomly in the connecting/loading state.
SDL implements URL opening, including of file URIs, with the `SDL_OpenURL` function for most systems including Android. However, using `SDL_OpenURL` for all systems has several downsides:
1. The `SDL_OpenURL` function is only available since SDL 2.0.14, in particular not for the Ubuntu 20 CI runner. Hence, we would either have to conditionally compile the link opening function to a null-implementation or fallback to using the existing `open_link` function.
2. We would be undoing some additional fixes in the `open_link` function for Windows, which are not included in the Windows implementation of `SDL_OpenURL`.
3. This would also replace the use of `open` on UNIX with `xdg-open`.
4. This would move the functionality to open links and files from the base to the engine client, so we could not have tools or the server potentially making use of this functionality in the future (e.g. open a folder for convenience).
Implementing link and file opening for Android ourselves is too much effort and potentially made even harder by SDL already managing all the unique JVM resources in the `SDLActivity`.
Therefore, the `SDL_OpenURL` function is only used for Android, which is always based on the latest SDL2 version. The original `open_link` functionality is kept for the other systems. For this purpose, the `IClient::ViewLink` and `ViewFile` functions are added to wrap `open_link` and `open_file` for the client and also reduce some duplicate code for error logging.
Unfortunately, testing also revealed that `SDL_OpenURL` does not currently support opening file URIs, at least not of files the internal storage location, which all the DDNet client's files would be located in. At least opening URLs works and neither breaks networking anymore.
Read the entire file into memory immediately when the line reader is initialized instead of using a fixed size buffer of size 32769, which leads to broken line reading for larger files (closes#8431).
Replace the `CLineReader::Init` function with the `CLineReader::OpenFile` function, which additionally checks whether the file contains any null bytes (indicates that the file is likely not a text file).
As the file will be read into memory entirely in the `OpenFile` function, is can also be closed immediately, since using the `io_read_all_str` function should ensure that nothing more can be read from the file. This also simplifies the usage of the `CLineReader` class, as manually closing the file is inconvenient and error-prone. In fact, the file handle for the `ddnet-serverlist-urls.cfg` file was previously not closed properly.
Benchmarking on Windows did not show any noticeable performance impact of this change both for smaller files (config and language files) and larger files (synthetic ~10 MiB files).
Let the `CLineReader::Get` function return `const char *` instead of `char *`, since users of this class should not modify the internal buffer. Also, since the entire file is read into memory now, the returned strings are now valid until the respective line reader object is destructed, instead of only until the `Get` function is called again. This simplifies the usage in some cases where all lines are handled, since additional temporary buffers are now unnecessary.
Remove the `IOFLAG_SKIP_BOM` flag from the `io_open` function, as this flag was only used together with the line reader. This was inconvenient to use, as any use of the `io_open` function specifically for line readers had to be used with `IOFLAG_SKIP_BOM`. Now, the line reader transparently skips the UTF-8 BOM internally. Skipping the UTF-8 BOM never worked with the `IStorage::ReadFileStr` function, because `io_length` is used in the `io_read_all` function, which rewinds the file position to before the UTF-8 BOM that was skipped by using `IOFLAG_SKIP_BOM`. In any case, as the `ReadFileStr` function is currently unused, this has/had no further effect. The respective test cases for `IOFLAG_SKIP_BOM` are removed.
Add more test cases for the `CLineReader` class. All test cases are checked both with and without the UTF-8 BOM. Additional tests with mixed new lines, empty lines with different new lines, and internal null bytes are added.
Consistently use the construct `while(const char *pLine = LineReader.Get())` to iterate over all lines of a line reader. In this case, the assignment inside the `while`-loop seems acceptable over the alternatives, e.g. `while(true)` with `break` or adding a function `CLineReader::ForAll(std::function<const char *> Consumer)`.
Add `sv_dnsbl_ban_reason` config variable with size 128 to specify the ban reason for `sv_dnsbl_ban`.
Increase the maximum size for ban reasons on the server from 64 to 128 to support this new config variable. Adjust buffer sizes for formatting ban messages accordingly.
Additionally, increase the size of the buffer for unpacking the connection closed message from 128 to 256. Due to this limitation, old clients will see truncated disconnect messages if the entire message is longer than 127, which can now happen with long ban reasons as the ban message additionally contains the duration (e.g. `You have been banned for 10 minutes (Reason)`).
Closes#8518.
The assertion of #8262 can be reproduced when sound is disabled or failed to be initialized, as the sample indices where not being initialized properly in these cases. It is still necessary to initialized them so sounds can be loaded in the editor also when sound is disabled.
The potential thread-safety issues of the `CSound::AllocSample` function are not yet resolved so the issue remains open.
Instead of relying on SDL to determine when a click is a double-click, implement double-click handling specifically for the UI, as double-clicks are only supposed to be used there. This allows us to ensure that double-clicks only activate UI elements if both clicks were performed on the same UI element. Previously, only the position of the second click was considered, so UI element would incorrectly activate when double-clicking close to them as long as the second click starts and ends on them.
Implementing double-clicking handling separately is also necessary to support double-clicking in the UI with touch events, as SDL does not provide the double-click information for touch events.
The newly added `CUi::DoDoubleClickLogic` function should be called after a UI element has been clicked. It will return `true` if the current click should be interpreted as a double-click, i.e. if the same UI element was clicked, the click was within 0.5 seconds of the previous click (the default duration for SDL and Windows) and the distance from the previous click is within 32 screen pixels (the default distance for SDL).
Add `IInput::ConsumeEvents` function accepting a consumer `std::function` to replace the duplicate usage of the `IInput::NumEvents`, `IInput::GetEvent` and `IInput::IsEventValid` functions.
Use an `std::vector` to store the current input events to support any number of input events per client update instead of at most 32.
Use full `uint32_t` range for input counter instead of only using the range 0..0xFFFF. If the range is artificially reduced, then this can result in inputs being handled multiple times with high refresh rates, so the increased range should add future proofing for extremely fast devices.
Split `CInput::AddEvent` function into `CInput::AddKeyEvent` and `CInput::AddTextEvent` functions for readability and to make it easier to add additional input events (i.e. touch events).
Ensure double-click state is cleared at the end of each frame to prevent the double-click from being stored when no UI element consumes it.
Move member variables from `IInput` interface to `CInput` implementation.
Remove separate `CEditor::DispatchInputEvents` function.