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`.
Fix valgrind errors not being detected as failures when the tests otherwise finish, as the valgrind results are printed to stderr and not to the logfiles. Additionally, valgrind failures were not being detected because the error summary is not printed to stderr immediately but only after some time when valgrind has processed the summary.
Find random unused port to bind to by opening a socket on port 0 and closing it immediately. This gives a port that will very likely be unused because the system cycles through all ports before reusing old ones obtained this way.
Add `wait_for_launch` function to reduce duplicate code. Wait for server to launch before starting clients.
Improve log messages.
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.