According to cppcheck's `nullPointerRedundantCheck` check:
```
src\game\client\components\menus_settings.cpp:729:8: warning: Either the condition 'pSkinToBeSelected==0' is redundant or there is possible null pointer dereference: pSkinToBeSelected. [nullPointerRedundantCheck]
if((pSkinToBeSelected->GetName()[0] == 'x' && pSkinToBeSelected->GetName()[1] == '_'))
^
src\game\client\components\menus_settings.cpp:732:25: note: Assuming that condition 'pSkinToBeSelected==0' is not redundant
if(pSkinToBeSelected == 0)
^
src\game\client\components\menus_settings.cpp:729:8: note: Null pointer dereference
if((pSkinToBeSelected->GetName()[0] == 'x' && pSkinToBeSelected->GetName()[1] == '_'))
^
src\game\editor\editor.cpp:5034:19: warning: Either the condition 'pEnvelope' is redundant or there is possible null pointer dereference: pEnvelope. [nullPointerRedundantCheck]
float EndTime = pEnvelope->EndTime();
^
src\game\editor\editor.cpp:5056:7: note: Assuming that condition 'pEnvelope' is not redundant
if(pEnvelope)
^
src\game\editor\editor.cpp:5034:19: note: Null pointer dereference
float EndTime = pEnvelope->EndTime();
^
src\game\editor\editor.cpp:5038:3: warning: Either the condition 'pEnvelope' is redundant or there is possible null pointer dereference: pEnvelope. [nullPointerRedundantCheck]
pEnvelope->FindTopBottom(s_ActiveChannels);
^
src\game\editor\editor.cpp:5056:7: note: Assuming that condition 'pEnvelope' is not redundant
if(pEnvelope)
^
src\game\editor\editor.cpp:5038:3: note: Null pointer dereference
pEnvelope->FindTopBottom(s_ActiveChannels);
^
src\game\editor\editor.cpp:5039:15: warning: Either the condition 'pEnvelope' is redundant or there is possible null pointer dereference: pEnvelope. [nullPointerRedundantCheck]
float Top = pEnvelope->m_Top;
^
src\game\editor\editor.cpp:5056:7: note: Assuming that condition 'pEnvelope' is not redundant
if(pEnvelope)
^
src\game\editor\editor.cpp:5039:15: note: Null pointer dereference
float Top = pEnvelope->m_Top;
^
src\game\editor\editor.cpp:5040:18: warning: Either the condition 'pEnvelope' is redundant or there is possible null pointer dereference: pEnvelope. [nullPointerRedundantCheck]
float Bottom = pEnvelope->m_Bottom;
^
src\game\editor\editor.cpp:5056:7: note: Assuming that condition 'pEnvelope' is not redundant
if(pEnvelope)
^
src\game\editor\editor.cpp:5040:18: note: Null pointer dereference
float Bottom = pEnvelope->m_Bottom;
^
src\game\editor\editor.cpp:5081:23: warning: Either the condition 'pEnvelope' is redundant or there is possible null pointer dereference: pEnvelope. [nullPointerRedundantCheck]
for(int c = 0; c < pEnvelope->m_Channels; c++)
^
src\game\editor\editor.cpp:5056:7: note: Assuming that condition 'pEnvelope' is not redundant
if(pEnvelope)
^
src\game\editor\editor.cpp:5081:23: note: Null pointer dereference
for(int c = 0; c < pEnvelope->m_Channels; c++)
^
```
The assigned values are never used, so the assignments can be removed or variable scopes can be reduced.
According to cppcheck's `unreadVariable` error.
The client crashes when launching with `screenshot` in the command line, as the graphics are not available when the command is executed.
This is fixed by storing the command, so it's executed when everything is ready.
When stored commands (`CFGFLAG_STORE`) were executed with `CConsole::StoreCommands(false)`, the associated chained commands were not properly executed, if they were chained after the command has been stored (e.g. in `CMenus::OnInit`).
Storing the command saves the current callback and userdata, which were overridden by the chain callback and userdata, but the stored callback and userdata were not updated.
This is fixed by storing a pointer to the command itself, which will be updated when it is chained.
From teeworlds/teeworlds#2572.
The key reader was displaying the old key for a frame. It now shows the new key immediately without flashing the old one after changing a bind.
Refactoring:
- The if-branches are restructured to be the same as on upstream.
- The function `GetKeyBindModifiersName` can be called without an additional check, because it returns an empty string when no modifier is pressed.
- The unused parameter `Checked` of the `DoButton_KeySelect` function is removed.
From teeworlds/teeworlds#2877.
The state of teams was not reset when restarting a round with `restart`, which led to various issues (#5144):
- Switchers kept their previous state instead of being reset to the initial state after restarting.
- Teams that started racing sometimes could not be joined after restarting.
- Sometimes teams cannot finish a race after restarting. I cannot reproduce this issue, so I don't know if it's fixed by these changes.
The client crashes when trying to unpack a packet that has the sixup flag set, as `CNetClient` does not pass pointers for the output parameters `pSecurityToken` and `pResponseToken` to `CNetBase::UnpackPacket`.
Since the client does not handle sixup packets, checks are added to return an error and ignore the packet instead of crashing due to a null pointer access.
This was found by fuzzing the data returned by `net_udp_recv` with radamsa.
```
==6200==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f8d0fb8ba56 bp 0x7ffcbf67c7f0 sp 0x7ffcbf67c7a8 T0)
==6200==The signal is caused by a WRITE memory access.
==6200==Hint: address points to the zero page.
0 0x7f8d0fb8ba56 (/lib/x86_64-linux-gnu/libc.so.6+0xc4a56)
1 0x563a7e250fbe in mem_copy src/base/system.cpp:208
2 0x563a7e1bc6b6 in CNetBase::UnpackPacket(unsigned char*, int, CNetPacketConstruct*, bool&, int*, int*) src/engine/shared/network.cpp:263
3 0x563a7e1bf57e in CNetClient::Recv(CNetChunk*) src/engine/shared/network_client.cpp:100
4 0x563a7cfa76a2 in CClient::PumpNetwork() src/engine/client/client.cpp:2546
5 0x563a7cfb7cf6 in CClient::Update() src/engine/client/client.cpp:2838
6 0x563a7cfcfe47 in CClient::Run() src/engine/client/client.cpp:3214
7 0x563a7d04c631 in main src/engine/client/client.cpp:4702
8 0x7f8d0faf0d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
9 0x7f8d0faf0e3f in __libc_start_main_impl ../csu/libc-start.c:392
10 0x563a7cb28754 in _start (build-asan/DDNet+0x2472754)
==8315==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f4accfe5a56 bp 0x7ffcf1318530 sp 0x7ffcf13184e8 T0)
==8315==The signal is caused by a WRITE memory access.
==8315==Hint: address points to the zero page.
0 0x7f4accfe5a56 (/lib/x86_64-linux-gnu/libc.so.6+0xc4a56)
1 0x560413603200 in mem_copy src/base/system.cpp:208
2 0x56041356d9c7 in CNetBase::UnpackPacket(unsigned char*, int, CNetPacketConstruct*, bool&, int*, int*) src/engine/shared/network.cpp:224
3 0x5604135717c0 in CNetClient::Recv(CNetChunk*) src/engine/shared/network_client.cpp:104
4 0x5604123597e2 in CClient::PumpNetwork() src/engine/client/client.cpp:2546
5 0x560412369e36 in CClient::Update() src/engine/client/client.cpp:2838
6 0x560412381f87 in CClient::Run() src/engine/client/client.cpp:3214
7 0x5604123fe771 in main src/engine/client/client.cpp:4702
8 0x7f4accf4ad8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
9 0x7f4accf4ae3f in __libc_start_main_impl ../csu/libc-start.c:392
10 0x560411eda894 in _start (build-asan/DDNet+0x2472894)
```
Port the smooth zoom code from the ingame camera to the editor with some minor adjustments.
The smooth zoom animation time can be adjusted with the existing `cl_smooth_zoom_time` config variable.
Closes#2525.
6058: Fix invalid demo cutting, Add slice highlighting r=Chairn a=VoxelDoesCode
Before, you could place an end slice before the beginning, creating a "zero second" demo, which doesn't play in client, and renders a corrupt file. I implemented a check where if the playhead is before the beginning slice, it won't place an end slice, and vice versa.
I also added highlighting in between the slices, so that it's easier to see.
![image](https://user-images.githubusercontent.com/95713843/202870840-216df4d7-975e-496d-b122-c819ce7ae6ee.png)
## Checklist
- [x] Tested the change ingame
- [x] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: VoxelDoesCode <bluheadcat@gmail.com>
Demo seeking for percent positions and relative time was choppy, when the first and last ticks of the demo are very large but close together (e.g. with 1308908156 to 1308905658, which are close to integer limit).
During the calculation of `WantedTick` both operands were promoted to `float`s, which caused the information of the smaller operand, i.e. the seeked percentage or relative time, to be mostly lost, so seeking was very inaccurate.
This is fixed by rounding the `float` operand to `int` before adding it to another `int`.
6061: Add friend counter + Change alignment of player count text r=def- a=l-ouis
Added friend counter, changed the alignment of player count indicator to better accommodate friend counter + line up with the "Players" text at the top of the tab
![image](https://user-images.githubusercontent.com/69405348/202891241-b76899cf-e65a-4085-804b-0a6877468fbc.png)
Fixes#5911
## Checklist
- [x] Tested the change ingame
- [x] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: louis <louisaltgeer@gmail.com>
The types are translated to `TYPE_ALL`/`TYPE_SAVE` respectively if a given path is relative and to `TYPE_ABSOLUTE` if a path is absolute.
These types are only supported with the `OpenFile`, `ReadFile`, `ReadFileStr` and `GetCompletePath` methods.
This reduces duplicate code when calling the methods.
6054: Fix editor crash when shifting left/right, fix wrong up/down shifting r=heinrich5991 a=Robyt3
Shifting left/right with a shift value greater than the layer's width crashed the game due to a heap-buffer-overflow.
Shifting up/down with a shift value greater or equal to half the layer's height did not correctly shift the entire layer.
The values of the enum constants `DIRECTION_*` are changed to consecutive numbers instead of exponents of two, as the directions cannot be combined together as flags.
Closes#6036.
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [X] Considered possible null pointers and out of bounds array indexing
- [X] Changed no physics that affect existing maps
- [X] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
Shifting left/right with a shift value greater than the layer's width crashed the game due to a heap-buffer-overflow.
Shifting up/down with a shift value greater or equal to half the layer's height did not correctly shift the entire layer.
The values of the enum constants `DIRECTION_*` are changed to consecutive numbers instead of exponents of two, as the directions cannot be combined together as flags.
Closes#6036.
Handle both shift keys in some cases where only the left shift key was previously supported.
The `CChat::m_ReverseTAB` variable is removed because it's unnecessary.
This condition cannot be true, as `pGroup` is a `CLayerGroup *` but the layers are `CLayer *`/`CLayerTiles *`/`CLayerGame *` etc., which are not part of the same inheritance hierarchy.
The method `CLayerGroup::Render` already ensures that game layers are not rendered below other layers.
5917: report extra player info to master http r=def- a=edg-l
couldn't test yet
this doesnt show extra info on the client server list yet, just makes the server report it
<!-- What is the motivation for the changes of this pull request? -->
<!-- Note that builds and other checks will be run for your change. Don't feel intimidated by failures in some of the checks. If you can't resolve them yourself, experienced devs can also resolve them before merging your pull request. -->
## Checklist
- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Edgar Luque <git@edgarluque.com>
6033: Add more tests for hashing, `CSemaphore` and utf8 confusables r=heinrich5991 a=Robyt3
## Checklist
- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [X] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
The functions `str_utf8_skeleton_begin` and `str_utf8_skeleton_next` and the `struct SKELETON` are only used internally, so they don't need to be exported.
Fix warnings with `-fstrict-aliasing` and `-Wstrict-aliasing=2` by using char array instead of array of char pointers:
```
src/engine/client/client.cpp: In member function 'virtual const char* CClient::DemoPlayer_Play(const char*, int)':
src/engine/client/client.cpp:3858:123: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
3858 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_CURRENT][0];
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
src/engine/client/client.cpp:3859:126: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
3859 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pAltSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_CURRENT][1];
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
src/engine/client/client.cpp:3864:117: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
3864 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_PREV][0];
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
src/engine/client/client.cpp:3865:120: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
3865 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pAltSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_PREV][1];
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
```
Snapshot data during demo playback was being stored in an array of `char *` instead of an array of `char`, which caused above aliasing warnings and used 8 times more memory for the snapshot storage than being necessary.
Fix warnings with `-fstrict-aliasing` and `-Wstrict-aliasing=2` by not casting the map reader data to `int *`:
```
src/game/server/gamecontext.cpp: In member function 'virtual void CGameContext::OnMapChange(char*, int)':
src/game/server/gamecontext.cpp:3623:56: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
3623 | pData = (int *)&MapInfo;
| ^~~~~~~~
src/game/server/gamecontext.cpp:3631:48: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
3631 | pData = (int *)&MapInfo;
| ^~~~~~~~
```
As the map reader data is return as `void *` and never used as `int *`, the redundant cast is removed to fix the warnings.
Also improve readability by moving `pInfo` variable declaration.
6024: Fix CGun::Fire server crash (fixes#6023) r=Learath2 a=def-
<!-- What is the motivation for the changes of this pull request? -->
<!-- Note that builds and other checks will be run for your change. Don't feel intimidated by failures in some of the checks. If you can't resolve them yourself, experienced devs can also resolve them before merging your pull request. -->
## Checklist
- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Dennis Felsing <dennis@felsin9.de>
I think at the point where you use (CEntity **) apPlayersInRange the
compiler says this is a totally different value than apPlayersInRange
since they have a different type. And then it reorders the inlined
FindEntities code to be run afterwards, thus leading to undefined
behavior and crashes.
6017: Minor refactoring of demo related code r=def- a=Robyt3
Extracted from #6016.
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
5599: Add support for Rust code in DDNet r=def- a=heinrich5991
The glue is done using the [cxx crate](https://cxx.rs/) on the Rust side.
As a proof-of-concept, only a small console command (`rust_version`) printing the currently used Rust version was added.
You can generate and open the Rust documentation using `DDNET_TEST_NO_LINK=1 cargo doc --open`.
You can run the Rust tests using `cmake --build <build dir> --target run_rust_tests`, they're automatically included in the `run_tests` target as well.
Rust tests don't work on Windows in debug mode on Windows because Rust cannot currently link with the debug version of the C stdlib on Windows: https://github.com/rust-lang/rust/issues/39016.
---
The stuff in `src/rust-bridge` is generated using
```
cxxbridge src/engine/shared/rust_version.rs --output src/rust-bridge/engine/shared/rust_version.cpp --output src/rust-bridge/engine/shared/rust_version.h
cxxbridge src/engine/console.rs --output src/rust-bridge/cpp/console.cpp --output src/rust-bridge/cpp/console.h
```
Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
When readding a sound/image and multiple files with the name exist, a popup is shown that allows the user to choose the wanted file.
If exactly one file is found, it is used without showing a dialog.
As before, if no file is found, an error message popup is shown.
Add `CEditor::ShowPopupSelection` to show a generic selection popup.
This popups shows a message and buttons for all entries in a `std::set`. Exactly one entry can be selected and the selection will be available to the caller in the given `SSelectionPopupContext`.
This function searches in all subfolder of the given folder and fills the given `std::vector` with all files with the given filename.
A `std::set` is used to prevent duplicate entries when a file with the same path is present in multiple storage locations. In that case we only need the path once, as we only use it against the highest priority storage location anyway.
Use `FindFile` to search for the image/sound file in all subfolders of the mapres folder when using the "Readd" button in the editor.
Show an error message popup when readding fails, i.e. when the file could not be found.
Add `CEditor::ShowPopupMessage` function to show a generic message in a popup.
The message text and color are configurable with the `SMessagePopupContext` argument object.
Instances of this class must have a static memory location, as the message needs to be available after the `ShowPopupMessage` function returns, and the address of this object is used to uniquely identify it in the UI.
6002: Explain -DANTIBOT=ON a bit better (fixes#6001) r=heinrich5991 a=def-
<!-- What is the motivation for the changes of this pull request? -->
<!-- Note that builds and other checks will be run for your change. Don't feel intimidated by failures in some of the checks. If you can't resolve them yourself, experienced devs can also resolve them before merging your pull request. -->
## Checklist
- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
6003: Fix height and margin of sound and image popups r=def- a=Robyt3
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Dennis Felsing <dennis@felsin9.de>
Co-authored-by: Robert Müller <robytemueller@gmail.com>
The `Append` method was returning `0` on success while `Load` and `Save` were returning `1`.
Now all three methods use a `bool` as return value and return `true` on success.
The call `SortImages()` is moved inside the `Append` method, as it should always be called when appending succeeded.
The height of the sound popup was too small, as it was not updated when the "Readd" button was added.
The additional `2.0f` margin at the top of the popups is removed, as all popup menus already have default `5.0f` margins on all sides.
The height of the image popup for external images was not including this margin to begin with, so it was slightly too small but is correct now.
The height of the image popup for embedded images is adjusted to no longer include this margin.
Pass `nullptr` instead of calculating unused `CUIRect` values.
Since the vulkan loader drops support for useful extensions (or the extension loading process changed between 1.0 & 1.1, not sure)
Which causes OBS not to work
5998: Fix Ctrl+F hotkey not checking for Ctrl key, minor improvement to tile details popup layout r=def- a=Robyt3
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
The hotkey for the "Find empty slot" button was not correctly checking for a pressed modifier, so it was already being trigger by just the key F instead of the desired Ctrl+F.
The height is calculated based on the number of rows and the row height instead of being entirely hardcoded, which makes maintenance easier.
The total height of the speedup popup was slightly too large, which is also fixed by this.
Variable names and their declaration positions are also refactored.
Some of the CUIRects were calculated but never used.
The height of the "Find empty slot" button is made consistent with the height of the properties shifters.
This reverts part of #5993 to allow switch number 0 to be selected again.
Switch number 0 is permanently enabled, so it useful for tiles that should always be switched on.
Eventually tiles that don't work with switch 0 (e.g. switch open/close tiles) should be made unplaceable and the switch number should be hidden for tiles where it doesn't have any effect (e.g. jump tiles). See #5995.
5994: Change editor hotkey Ctrl+A to Ctrl+T for layer/tile details r=def- a=Robyt3
The hotkey Ctrl+A is already active universally in the editor to open and append a map to the current one. This collides with the hotkeys for opening the layer/tile details popup for tune, tele, speedup and switch layers, which is only active when a layer of said type is select. Pressing the hotkey in this context opens the popup and the append dialog at the same time, which is undesirable. Therefore the hotkey to open the layer/tile details is changed to Ctrl+T instead. This combination is currently unused and seems approriate, as the T could stand for "Tile details".
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
The hotkey Ctrl+A is already active universally in the editor to open and append a map to the current one.
This collides with the hotkeys for opening the layer/tile details popup for tune, tele, speedup and switch layers, which is only active when a layer of said type is select.
Pressing the hotkey in this context opens the popup and the append dialog at the same time, which is undesirable.
Therefore the hotkey to open the layer/tile details is changed to Ctrl+T instead. This combination is currently unused and seems approriate, as the T could stand for "Tile details".
It was possible to select tele number 0, speedup force 0 and switch number 0 in the layer details in the editor, because some of the bounds checks or calculations were not excluding the value 0.
As placing those tiles with the value 0 in the editor is not possible and the tiles with this value are ignored by server and client, it also shouldn't be possible to select those values in the first place.
5770: Fix physics change by weak hook fix (fixes#5769) r=def- a=fokkonaut
<!-- What is the motivation for the changes of this pull request -->
fixes#5769
## Checklist
- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: fokkonaut <35420825+fokkonaut@users.noreply.github.com>
Co-authored-by: Jupeyy <jupjopjap@gmail.com>
5991: Handle all `MultiByteToWideChar` and `WideCharToMultiByte` return values r=def- a=Robyt3
Closes#5970.
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [X] Considered possible null pointers and out of bounds array indexing
- [X] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>
Converting wide-char (UTF-16) to multi-byte (UTF-8) takes 1-2 wide-chars from the input and transforms them to 1-4 bytes, so having `char` and `WCHAR` buffers with equal static lengths means that this function can fail due to insufficient buffer sizes when the user has folder or files with very long names (many unicode codepoints).
Therefore checks are added that allow only the error `ERROR_INSUFFICIENT_BUFFER` when `WideCharToMultiByte` fails, which is expected on very long paths, as these would also lead to further errors later in the code. The respective functions will now fail with a return and ignore files that have too long names.
This could only completely be fixed using dynamically sized buffers for all paths, which seems like too much work and overhead.
Other errors are not expected and hence caught by the assertions, as those would indicate programming errors like wrong arguments being passed.
Reference: https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
The second buffer was previously used when calling `fs_is_dir` explicity, but it has become from obsolete from #4657 by using the flag `FILE_ATTRIBUTE_DIRECTORY` instead.
Extract `windows_format_system_message` and allocate appropriate buffer for the formatted system error messages, so messages of any length can be displayed.
The flag `FORMAT_MESSAGE_ALLOCATE_BUFFER` is used so `FormatMessageW` allocates the buffer which must later be freed with `LocalFree`.
The flag `FORMAT_MESSAGE_MAX_WIDTH_MASK` is also added so the formatted message will not contain any line breaks at the end, which would make log messages less readable.
Reference: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagew
Converting multi-byte (UTF-8) to wide-char (UTF-16) take 1-4 bytes from the input and transforms them to 1-2 wide-chars, so having `char` and `WCHAR` buffers with equal lengths should mean that this function can't fail due to insufficient buffer sizes, unless a path that's already too long for Windows is being used internally.
Other errors are also not expected, as those would indicate programming errors like wrong arguments being passed.
The maximum length for paths in the Win32 API is 260 characters. This limitation can be lifted in Windows 10, but it must be done explicitly (opt-in) both in the Windows Registry by the user and in the application's manifest by us.
References:
- https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
- https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
Make sure the Windows debugger logger does not fail when log messages are too long.
The first call to `MultiByteToWideChar` gets the required size of the wide-char buffer, which should be at least one for the null termination. The second call is expected to produce exactly the same number of characters.
The function `MultiByteToWideChar` can't fail unless wrong arguments are passed, when the buffer size is set correctly by calling the function twice. The returned buffer size on the second call should always match the buffer size determined with the first call.
Using `str_format(aBuf, sizeof(aBuf), "%s", pStr)` is equivalent to `str_copy(aBuf, pStr, sizeof(aBuf))`. Using `str_copy` is more readable and also more efficient as there is no overhead from parsing the format string and from passing varargs.
5985: Fix large editor popups being outside of screen, add margin r=def- a=Robyt3
Large editor popups could be positioned outside of the screen area, when they could not be positioned below or to the right of the cursor without overflowing. This is fixed by making sure the popup does not overflow the top or left side of the screen after adjusting its position.
A small margin is also added so popups don't start or end immediately at the screen border.
Closes#5982.
## Checklist
- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)
Co-authored-by: Robert Müller <robytemueller@gmail.com>