Favorite skin names were previously not escaped as intended when saving, as the variable `aNameEscaped` was unused so the original skin name was saved instead of the escaped one. Escaping is not really necessary, as skins should not contain `\` and `"` anyway and it was only possible to add such favorites through the console or config files. Instead of escaping the favorite skin names when saving, now favorite skin names are validated when they are added so no escaping is necessary. Skins names are considered valid when they have a length of 1-23 bytes and don't contain the characters `/`, `\` and `"`.
All `map_*` tools were crashing with the assertion `Invalid type` when used on maps that contain unknown UUID-based map items. When the UUID cannot be resolved, the type `-1` is returned by the `GetItem` function. The assertion predates UUID map items, so this crash has likely existed since the introduction of UUID map items. The editor was not affected and has instead always discarded map items that it does not support. The tools will now also discard map items with unknown UUIDs.
See #7669.
The current mouse-based console selection was not being adjusted anymore when new lines are added to the console, as the `m_NewLineCounter` variable was decremented to `0` before the relevant check for `m_NewLineCounter > 0`.
The selection is only cleared because it would be incorrect after scrolling, but it doesn't need to be cleared if the scroll position does not change, e.g. when pressing Home while already at the top of the backlog.
Do not use the `CMapItemSound::m_SoundDataSize` value as it is redundant. This value could also be incorrect because it can be freely set by the map creator (tool).
Instead, use the map/datafile function `GetDataSize` to get the true size of the sound data in the file.
The `m_SoundDataSize` value is still written to map files for compatibility with old versions.
Replace unnecessary `gameclient.h` include with more specific includes.
Fix storage creation error message not being logged as the logger was initialized after checking for the failed storage creation. However, in this case we want to avoid non-error log messages so the tool's output is only the extracted demo chat, except in error cases.
Rename `Process` function to `ExtractDemoChat` and make it `static` to avoid exporting it.
Use `log_error` instead of `dbg_msg`.
Add a proper kernel interface `INotifications` for the notifications component instead of using a C style interface.
Add parameter for the application name when initializing notifications to avoid hardcoding the application name.
The implementation for macOS is kept in Objective-C and a TODO is added, as the API we are currently using appears to be deprecated.
Fix Ctrl+C not working to copy text in console when the command input already contains text, as the changed flag was never reset properly.
Fix scroll position of UI editboxes not being updated when moving cursor without changing text.
Fix lineinput selection change being detected as content change, causing the editor modified state to be set incorrectly.
Fix cursor blinking not being disabled correctly after changing text without changing cursor position.
/home/deen/isos/ddnet/ddnet-source/src/engine/client/discord.cpp: In member function ‘bool CDiscord::Init(FDiscordCreate)’:
/home/deen/isos/ddnet/ddnet-source/src/engine/client/discord.cpp:39:17: error: ‘mem_zero’ was not declared in this scope
39 | mem_zero(&m_ActivityEvents, sizeof(m_ActivityEvents));
| ^~~~~~~~
Now `CGameContext` no longer assumes the `IGameController`
declined the team join due to slots.
This enables custom gametypes to disallow joining the game if the player
died, an active tournament is running or the player is not logged in
yet. And then the controller can print the correct error message
accordingly.
Show localized text "Press a key…" instead of "???" while waiting for a key to be pressed.
Render button with green background while waiting for a key to be pressed.
Inline unnecessary `DoButton_KeySelect` function.
Fix names of static variables.
Prevent potential dead lock when using `/map` chat command in combination with Teehistorian. Closes#7619. I could not reproduce the issue on Windows though.
This also means resetting game settings should actually be efficient now, because it only involves iterating over all game settings and directly resetting their value.
Previously, only one buffer was allocated to store each snapshot holder structure, the snapshot data and alternative snapshot data. This prevents tools like ASAN from detecting some invalid accesses, e.g. to the snapshot holder structure by underflowing the snapshot data pointer. Now three separate allocations are used instead. This hopefully helps debugging #2677.
We support little and big endian but not PDP endian (Middle-endian).
Define endianness as string `CONF_ARCH_ENDIAN_STRING` to avoid conditional compilation when printing endianness.
On Windows the function `setsockopt` does not set `errno` on errors but instead `WSAGetLastError` must be used. This is encapsulated in the `net_errno` function.
The variable `Id` is translated for old clients and is not guranteed to
be the real id. While `m_ClientID` is the real ID. That can also be used
to index the CServer::m_aClients[] array to get the authed state.
closed#7599
Fixes
```
valgrind ./DDNet-Server "dbg_dummies 1"
[..]
2023-12-07 18:01:33 I chat: *** 'Debug dummy 1' entered and joined the
game
==75634== Conditional jump or move depends on uninitialised value(s)
==75634== at 0x2DAA83: CVariableInt::Pack(unsigned char*, int, int)
(compression.cpp:17)
==75634== by 0x2DAD79: CVariableInt::Compress(void const*, int,
void*, int) (compression.cpp:98)
==75634== by 0x23EC50: CServer::DoSnapshot() (server.cpp:1046)
==75634== by 0x247D2D: CServer::Run() (server.cpp:2994)
==75634== by 0x230173: main (main.cpp:193)
==75634==
==75634== Conditional jump or move depends on uninitialised value(s)
==75634== at 0x2DAAF7: CVariableInt::Pack(unsigned char*, int, int)
(compression.cpp:25)
==75634== by 0x2DAD79: CVariableInt::Compress(void const*, int,
void*, int) (compression.cpp:98)
==75634== by 0x23EC50: CServer::DoSnapshot() (server.cpp:1046)
==75634== by 0x247D2D: CServer::Run() (server.cpp:2994)
==75634== by 0x230173: main (main.cpp:193)
==75634==
==75634== Conditional jump or move depends on uninitialised value(s)
==75634== at 0x2DAA83: CVariableInt::Pack(unsigned char*, int, int)
(compression.cpp:17)
==75634== by 0x32E812: CPacker::AddInt(int) (packer.cpp:20)
==75634== by 0x23ED51: CServer::DoSnapshot() (server.cpp:1059)
==75634== by 0x247D2D: CServer::Run() (server.cpp:2994)
==75634== by 0x230173: main (main.cpp:193)
==75634==
==75634== Conditional jump or move depends on uninitialised value(s)
==75634== at 0x2DAAF7: CVariableInt::Pack(unsigned char*, int, int)
(compression.cpp:25)
==75634== by 0x32E812: CPacker::AddInt(int) (packer.cpp:20)
==75634== by 0x23ED51: CServer::DoSnapshot() (server.cpp:1059)
==75634== by 0x247D2D: CServer::Run() (server.cpp:2994)
==75634== by 0x230173: main (main.cpp:193)
==75634==
```
Which is using ID 0 as index in the m_aClients array but only ID 63 was
ever initialized.
The `LoadMapSearch` function returns an error message or `nullptr` on success but the condition was incorrectly changed in #7580 so the opposite was checked instead.
Closes#7597.
Setting a vote timeout longer than 60 seconds with `sv_vote_time` caused the vote network messages to be discarded with the error message `weird message 'Sv_VoteSet' (15), failed on 'm_Timeout'` by the client, as the protocol did not allow longer vote timeouts.
This changes the protocol so the vote timeout can be any positive integer although for now the maximum `sv_vote_time` value is changed back to 60 again to preserve compatibility with old clients.
Closes#7583.
The invalid sound index is `-1` but the check in the editor for the sound preview assumed it was `0`. We should use a type-safe wrapper to avoid this in the future, like for texture handles.
The popup menu render function can open/close other popups, which may resize the vector of popup menus and thus invalidate the current popup menu variable before the popup is closed. We therefore store the popup UI element ID in a separate variable to avoid the access to the potentially invalidated popup menu variable after the popup menu is rendered.
Also prevent invalidated popup menu from being rendered for one frame after it is closed by clicking outside.
Closes#7565.
Support registering arbitrary number of interfaces with `IKernel` instead at most 32.
Assert when incorrect arguments are passed to `IKernel` functions instead of returning a `bool`, which was not being handled in all cases. These functions are not expected to fail expect on programming errors.
Consistently order and format creation and registration of kernel interfaces in client and server.
Additionally, ensure snapshots are cleared and dummy is disconnected when disconnecting programatically with `DisconnectWithReason`.
Add `NETADDR_ZEROED` and `UUID_ZEROED` for more convenient initialization without using `mem_zero`.
Add stricter error handling when converting between UTF-16 (wide characters) and UTF-8 (multi-byte) on Windows.
The `windows_wide_to_utf8` function now returns an `std::optional`, which will be empty if the argument contains invalid UTF-16. Files/folders with names containing invalid UTF-16 are now ignored on Windows. It was previously not possible to use these files either, as converting their names to UTF-8 changed the invalid codepoints to unicode replacement characters.
The `windows_utf8_to_wide` function now fails with an assertion error if the argument contains invalid UTF-8, as this should never happen.
Closes#7486.
Add `CHttpRequest::ExpectSha256` function to specify expected SHA256 for HTTP downloads. If the download completes with a different SHA256 hash than expected, then the download fails and the file is deleted.
Closes#7485.
Move all code for handling of config variables from console to config manager. The console no longer depends on the config manager, instead the config manager now depends on the console.
Add `struct`s to manage config variables of different types (int, color and string). The config manager now keeps a list of all config variables, so usage of the preprocessor can be avoided except for code to initially create all config variables. Additionally, a separate list of just the game config variables (config variables with `CFGFLAG_GAME`) is kept to optimize the `ResetGameSettings` function, as this function is called whenever connecting to a server and should be fast. Previously, this function was even less efficient because it preformed a linear search for every individual game config variable to find the respective command data.
Move console commands that opperate only on config variables (`reset`, `toggle` and `+toggle`) to config manager. Ensure that these commands only opperate on the desired config variables (client or server, respectively) by checking `IConsole::FlagMask`.
Add `IConfigManager::SetReadOnly` function to set/unset config variables as read-only instead of manually overriding the command handlers for the `sv_rescue` and `sv_test_cmds` config variables. This also fixes that read-only config variables could still be changed by using the `reset` command. A console message is now printed when trying to change a read-only config variable. Removing the special handling for these two config variables is additionally useful so the console does not need to keep a pointer to config values and manager.
Use a `CHeap` for the config variables, their help texts and the previous values of string config variables to avoid many separate allocations as well usage of static variables. Also use the heap to store the unknown commands instead of using `std::string`s.
Properly trigger command chain when resetting config variables with the `reset` command and when resetting game settings on map loading. Closes#7461.
Format default value for color variables as RGB/RGBA hex with dollar sign prefix. Closes#5523.
Add log message when using `reset` with a variable that does not exist. Use `log_error` instead of `dbg_msg` when saving config file fails.
Support unlimited number of config save callbacks instead of at most 16. The code also becomes more readable by using an `std::vector` instead of a fixed-size array and a separate num variable.
Consistently name `MACRO_CONFIG_*` parameters when declaring the macros.
Add `IConsole::CMDLINE_LENGTH` constant to represent the maximum length of the console input and thereby reduce usage of magic numbers for buffer sizes.