Commit graph

1778 commits

Author SHA1 Message Date
bors[bot] 54e56b0048
Merge #6302
6302: Use OpenGL 3.3 on macOS by default r=Jupeyy a=def-

Otherwise falls back to OpenGL 1.5, since 3.0 is not supported

<!-- 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

- [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>
2023-01-23 11:15:46 +00:00
Dennis Felsing ec30fc7043 Use OpenGL 3.3 on macOS by default
Otherwise falls back to OpenGL 1.5, since 3.0 is not supported
2023-01-23 12:06:04 +01:00
bors[bot] 3ffd4205ef
Merge #6295
6295: Implement FIFO on Windows using Named Pipes r=def- a=Robyt3

Reimplement the Linux FIFO file server and client controls on Windows by using Named Pipes.

The DDNet server/client acts as a named pipe server and receives messages.
Messages can be posted to the named pipe server by connecting to it as a client.
The named pipe client can for instance be controlled from the command line with PowerShell.

The PowerShell script `scripts/send_named_pipe.ps1` is added for this purpose.
For example the PowerShell command `./send_named_pipe.ps1 "testpipe" "echo a"` sends the command `echo a` to the pipe named `testpipe`.
Multiple commands can be sent at the same time by separating them with semicolons or newlines.

## 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>
2023-01-22 21:40:17 +00:00
Robert Müller f80e962888 Add IStorage::FileExists and IStorage::FolderExists
As wrappers around `fs_is_file` and `fs_is_dir`.
2023-01-22 17:22:11 +01:00
Robert Müller 7eb5966f6f Implement FIFO on Windows using Named Pipes
Reimplement the Linux FIFO file server and client controls on Windows by using Named Pipes.

The DDNet server/client acts as a named pipe server and receives messages.
Messages can be posted to the named pipe server by connecting to it as a client.
The named pipe client can for instance be controlled from the command line with PowerShell.

The PowerShell script `scripts/send_named_pipe.ps1` is added for this purpose.
For example the PowerShell command `./send_named_pipe.ps1 "testpipe" "echo a"` sends the command `echo a` to the pipe named `testpipe`.
Multiple commands can be sent at the same time by separating them with semicolons or newlines.
2023-01-21 11:13:02 +01:00
Robert Müller f78fd6bda1 Minor refactoring of CFifo
- Remove unused include.
- Instead of quitting entirely, only disable the fifo component when file cannot be used.
- Return early to reduce indentation.
2023-01-20 22:52:55 +01:00
heinrich5991 e06052292e CMsgPacker doesn't know about message ID encoding
CC #6289
2023-01-20 21:09:58 +01:00
bors[bot] 4a4d6c5483
Merge #6284
6284: Ensure integer wrapping instead of preventing overflow/underflow r=heinrich5991 a=Robyt3

As the integer overflow/underflow in `UndiffItem` can happen during normal gameplay, we should in this case neither ignore the snapshot delta nor show an error message.

Instead of depending on the particular compiler doing integer wrapping, when integer overflows or underflows occur, we make it part of the design, by casting to `unsigned`, which ensures that integer wrapping is being used.

## 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>
2023-01-18 22:46:52 +00:00
Robert Müller 1a9357b961 Fix sv_vanilla_antispoof for vanilla 0.6.5 clients
This fixes issues that prevented vanilla 0.6.5 clients from joining DDNet servers with `sv_vanilla_antispoof 1` (closes #2074).

The dummy map was not valid. The size of the tiles and game layers was calculated incorrectly. The last member variable included in `CMapItemLayerTilemap` version 2 should be `m_Data`. Previously only the size of the member `m_aName` was subtracted from the total size, which was resulting in an incorrect item size, as the size of the following 5 members also needs to be subtracted.

The handshake messages were packed incorrectly. The message ID and the system flag were not added to the six packers that are passed to `SendMsgs`. The lines that are removed in this function seemed to assume that the message ID was already added but not packed, which was no longer the case. Presumable at some point `CMsgPacker` was changed without adapting the vanilla antispoof feature. Now, the message ID and system flag are properly packed when initially creating the message packers.

The `dummy_map` tool is improved to also print the generated map file's hashes and data as a C style array, so the data can immediately be copied to `network_server.cpp`.
2023-01-18 20:21:12 +01:00
Robert Müller 65cb2ed7de Ensure integer wrapping instead of preventing overflow/underflow
As the integer overflow/underflow in `UndiffItem` can happen during normal gameplay, we should in this case neither ignore the snapshot delta nor show an error message.

Instead of depending on the particular compiler doing integer wrapping, when integer overflows or underflows occur, we make it part of the design, by casting to `unsigned`, which ensures that integer wrapping is being used.
2023-01-16 18:12:28 +01:00
Dennis Felsing 43e994a002 Fix announcement feature, don't depend on buffer staying consistent
There is a change in behavior: The file is now only reread if the
filename changed, previously it was reread every time.
2023-01-13 16:22:22 +01:00
Dennis Felsing b62e7f1299 Quick fix for old client on new server
Introduced in https://github.com/ddnet/ddnet/pull/6214/
Not a proper solution yet
2023-01-13 14:46:01 +01:00
heinrich5991 a0221c3038 Fix ddnet.org change in UUIDs
One case was a ddnet.tw UUID's string being changed (but the UUID was
not), and the other case is a ddnet.tw UUID's string being changed in
one place but not in another in documentation.

Fixes the commit c479230d71.

CC #5312
2023-01-12 15:38:17 +01:00
Robert Müller 066768cf70 Use distinct error return codes for CSnapshotDelta::UnpackDelta
Use a different error code for every return statement, so it's easier to determine why unpacking a delta failed.

The codes are grouped by the first digit of the error code:

- `-1xx`: not enough data to read
- `-2xx`: value is invalid
- `-3xx`: could not build snapshot item
2023-01-08 14:31:07 +01:00
bors[bot] 69931336fc
Merge #6242
6242: Add skin to serverbrowser's scoreboard r=def- a=Jupeyy

with #6240 we might get few more pixels for either flag or margin

![image](https://user-images.githubusercontent.com/6654924/211063976-4acb60ca-9a49-4d1b-b556-a82f88b28303.png)


## 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: Jupeyy <jupjopjap@gmail.com>
2023-01-07 10:29:22 +00:00
Jupeyy 1182180e23 Add skin to serverbrowser player list 2023-01-07 09:20:25 +01:00
Adrian Bunk abb1979d20 src/engine/shared/datafile.cpp: Re-add #include <base/math.h> for big endian 2023-01-07 04:38:06 +02:00
Robert Müller 9ea665cd69 Fix undefined demo timeline markers when recording is not stopped
When the demo recording is not stopped properly (e.g. client crashes during recording), the timeline markers and the demo length are not updated.
The length is always set to zero when starting the recording, but uninitialized memory is written for the timeline markers, which causes these demos to likely show the maximum number of markers with some markers possibly being outside the ticks that the demo contains.
This is fixed by initially setting all timeline marker data to zero when starting the recording.
2023-01-03 15:38:54 +01:00
Robert Müller 706eb0d015 Remove unnecessary include in protocol, move definitions to cpp file
The include of `base/system.h` in `src/engine/shared/protocol.h` is not required and only used transitively in `teamscore.h` for `dbg_assert`.

To avoid adding back the include in `teamscore.h`, the function definitions are moved to the cpp file. Both definitions are moved for consistency.
2023-01-03 14:10:58 +01:00
Robert Müller e4b1db1b6d Fix spelling of NETMSG_AUTH_CHALLENGE constant 2023-01-03 14:10:57 +01:00
Robert Müller 25e01eb762 Add constants for minimum and maximum tick values 2023-01-03 14:10:57 +01:00
Robert Müller 6e28ca6fe4 Extract method IStorage::GetBinaryPathAbsolute 2023-01-02 15:29:43 +01:00
Robert Müller 4118074768 Fix signed integer overflow when unpacking snapshot delta
```
src/engine/shared/snapshot.cpp:219:18: runtime error: signed integer overflow: -2011501152 + -1594687485 cannot be represented in type 'int'
    0 0x5593cbc3534c in CSnapshotDelta::UndiffItem(int const*, int*, int*, int, int*) src/engine/shared/snapshot.cpp:219
    1 0x5593cbc3852d in CSnapshotDelta::UnpackDelta(CSnapshot*, CSnapshot*, void const*, int) src/engine/shared/snapshot.cpp:442
    2 0x5593cbb881a6 in CDemoPlayer::DoTick() src/engine/shared/demo.cpp:624
    3 0x5593cbb9a907 in CDemoPlayer::Update(bool) src/engine/shared/demo.cpp:1016
    4 0x5593ca9f44da in CClient::Update() src/engine/client/client.cpp:2628
    5 0x5593caa199dd in CClient::Run() src/engine/client/client.cpp:3220
    6 0x5593caa970f3 in main src/engine/client/client.cpp:4717
    7 0x7fe086d04d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    8 0x7fe086d04e3f in __libc_start_main_impl ../csu/libc-start.c:392
    9 0x5593ca55e6f4 in _start (build-demofuzz/DDNet+0x24936f4)
```
2022-12-31 12:06:31 +01:00
Robert Müller d63a7a3c84 Fix left shift of negative value when unpacking snapshot delta
```
src/engine/shared/snapshot.cpp:693:28: runtime error: left shift of negative value -1
    0 0x55cae1608071 in CSnapshotBuilder::NewItem(int, int, int) src/engine/shared/snapshot.cpp:686
    1 0x55cae1603fe0 in CSnapshotDelta::UnpackDelta(CSnapshot*, CSnapshot*, void const*, int) src/engine/shared/snapshot.cpp:390
    2 0x55cae15544c6 in CDemoPlayer::DoTick() src/engine/shared/demo.cpp:624
    3 0x55cae1566c27 in CDemoPlayer::Update(bool) src/engine/shared/demo.cpp:1016
    4 0x55cae03c07fa in CClient::Update() src/engine/client/client.cpp:2628
    5 0x55cae03e5cfd in CClient::Run() src/engine/client/client.cpp:3220
    6 0x55cae0463413 in main src/engine/client/client.cpp:4717
    7 0x7fbc7d855d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    8 0x7fbc7d855e3f in __libc_start_main_impl ../csu/libc-start.c:392
    9 0x55cadff2aa14 in _start (build-demofuzz/DDNet+0x2493a14)
```
2022-12-31 12:06:31 +01:00
Robert Müller 6800bd90a4 Fix edge cases where demo tick seeking did not work
Instead of using hardcoded tick offsets, use the current/previous/next tick values from the demo info.

This fixes seeking the next tick not working for demos where the difference between the current and the next tick was greater than 3.
2022-12-30 21:05:46 +01:00
Robert Müller a3e48bef27 Prevent temporary demo file from being deleted multiple times
Each time the client disconnected or stopped a demo, it tried to delete the previous temporary replay file, which causes an error message "could not delete file" to be shown in the console.

This is prevented by clearing the current filename of the demo recorder after deleting the file.
2022-12-30 14:20:42 +01:00
def c3909d7cdb Just quiet curl warnings for now 2022-12-25 19:34:19 +01:00
Jupeyy 5341fc37fd Minimal changes to default to Vulkan 2022-12-13 19:37:03 +01:00
Jupeyy dff876d58c Add Localizable hint 2022-12-13 17:53:32 +01:00
Robert Müller 7958b999a3 Copy the demo timeline markers when slicing a demo
When slicing a demo, also copy the demo markers that are within the sliced segment to the new demo.

This also fixes timeline markers not being added to replay demos, as the replay demos are always created by slicing.

Closes #6116.
2022-12-11 14:34:21 +01:00
bors[bot] 3438e272af
Merge #6101
6101: Remove check for `pResponseToken`, which isn't used on this code path r=def- a=Robyt3

Closes #6100.

## 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>
2022-12-06 20:01:41 +00:00
Robert Müller 9bc0028b94 Remove check for pResponseToken, which isn't used on this code path
Closes #6100.
2022-12-06 20:37:59 +01:00
Robert Müller 7e1fc0344e Reduce duplicate code by extracting CNetBan::CBanPool::InsertUsed 2022-12-06 20:18:08 +01:00
bors[bot] cf6e89c319
Merge #6035
6035: Fix various issues reported by cppcheck static analyser r=def- a=Robyt3

After generating `compile_commands.json` with cmake, I ran [cppcheck](https://cppcheck.sourceforge.io/) like this:

```
cppcheck --project=compile_commands.json -DWIN64 --suppressions-list=cppcheck.supp --enable=all 2>cppcheck.log
```

With these suppressions in `cppcheck.supp`:

```
cstyleCast
useStlAlgorithm
unusedFunction
variableScope
noExplicitConstructor
useInitializationList
noConstructor
uninitMemberVar
uninitMemberVarPrivate
uninitDerivedMemberVar
uninitStructMember
uninitvar
shadowFunction
memleakOnRealloc
internalAstError
virtualCallInConstructor
unknownMacro
noOperatorEq
noCopyConstructor
```

Many of these occur too often or are false positives. 

Here is a list of all remaining non-suppressed issues reported by cppcheck: [cppcheck.log](https://github.com/ddnet/ddnet/files/9997663/cppcheck.log)

And here is a list of all remaining issues including the suppressed ones: [cppcheck_all.log](https://github.com/ddnet/ddnet/files/9997662/cppcheck_all.log)

I couldn't get cppcheck's command line argument to ignore the external folders to work correctly, so I manually removed those entries from the files.

## 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: Robert Müller <robytemueller@gmail.com>
2022-12-05 20:00:07 +00:00
Robert Müller 9cba213310 Consistently use static const instead of const static 2022-11-29 23:32:32 +01:00
Robert Müller 98706d79d4 Mark parameters as const when possible
According to cppchecker's `constParameter` error:

```
src\engine\gfx\image_manipulation.cpp:7:58: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void Dilate(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest, unsigned char AlphaThreshold = TW_DILATE_ALPHA_THRESHOLD)
                                                         ^
src\engine\gfx\image_manipulation.cpp:58:67: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void CopyColorValues(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest)
                                                                  ^

src\engine\shared\network_conn.cpp:241:42: style: Parameter 'Addr' can be declared as reference to const [constParameter]
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup)
                                         ^

src\base\system.cpp:4060:71: style: Parameter 'random' can be declared as pointer to const [constParameter]
void generate_password(char *buffer, unsigned length, unsigned short *random, unsigned random_length)
                                                                      ^

src\engine\client\backend\vulkan\backend_vulkan.cpp:263:38: style: Parameter 'AllocatedMemory' can be declared as reference to const [constParameter]
  void Free(SMemoryHeapQueueElement &AllocatedMemory)
                                     ^
src\engine\client\backend\vulkan\backend_vulkan.cpp:1708:47: style: Parameter 'ImgExtent' can be declared as reference to const [constParameter]
 static size_t ImageMipLevelCount(VkExtent3D &ImgExtent)
                                              ^
src\engine\client\backend\vulkan\backend_vulkan.cpp:2801:29: style: Parameter 'Image' can be declared as reference to const [constParameter]
 void ImageBarrier(VkImage &Image, size_t MipMapBase, size_t MipMapCount, size_t LayerBase, size_t LayerCount, VkFormat Format, VkImageLayout OldLayout, VkImageLayout NewLayout)
                            ^
src\engine\client\backend\vulkan\backend_vulkan.cpp:6495:46: style: Parameter 'ExecBuffer' can be declared as reference to const [constParameter]
 void Cmd_Clear(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand)
                                             ^

src\game\client\components\skins.cpp:83:72: style: Parameter 'pImg' can be declared as pointer to const [constParameter]
static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int ImgWidth, int ImgX, int ImgY, int CheckWidth, int CheckHeight)
                                                                       ^

src\game\client\prediction\entities\character.h:106:37: style: Parameter 'pNewInput' can be declared as pointer to const [constParameter]
 void SetInput(CNetObj_PlayerInput *pNewInput)
                                    ^

src\game\client\prediction\gameworld.cpp:245:106: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
                                                                                                         ^
src\game\client\prediction\gameworld.cpp:245:151: style: Parameter 'pThisOnly' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
                                                                                                                                                      ^
src\game\client\prediction\gameworld.cpp:283:116: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
std::list<class CCharacter *> CGameWorld::IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, class CEntity *pNotThis)
                                                                                                                   ^

src\game\client\ui.cpp:522:180: style: Parameter 'pReadCursor' can be declared as pointer to const [constParameter]
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, CTextCursor *pReadCursor)
                                                                                                                                                                                   ^

src\game\client\ui_scrollregion.cpp:23:86: style: Parameter 'pParams' can be declared as pointer to const [constParameter]
void CScrollRegion::Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams)
                                                                                     ^

src\game\server\scoreworker.h:239:29: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
 void Set(float Time, float aTimeCp[NUM_CHECKPOINTS])
                            ^

src\game\server\score.cpp:135:80: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void CScore::SaveScore(int ClientID, float Time, const char *pTimestamp, float aTimeCp[NUM_CHECKPOINTS], bool NotEligible)
                                                                               ^

src\game\server\teeinfo.cpp:40:57: style: Parameter 'pUseCustomColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
                                                        ^
src\game\server\teeinfo.cpp:40:80: style: Parameter 'pSkinPartColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
                                                                               ^
```
2022-11-29 23:32:31 +01:00
Robert Müller ca58bba82f Remove redundant bitwise operand
According to cppcheck's `badBitmaskCheck` error:

```
src\engine\client\client.cpp:422:26: style: Operator '|' with one operand equal to zero is redundant. [badBitmaskCheck]
  Packer.AddInt((0 << 1) | (pMsg->m_System ? 1 : 0)); // NETMSG_EX, NETMSGTYPE_EX
                         ^

src\engine\shared\snapshot.cpp:40:45: style: Operator '|' with one operand equal to zero is redundant. [badBitmaskCheck]
 int TypeItemIndex = GetItemIndex((0 << 16) | InternalType); // NETOBJTYPE_EX
                                            ^

src\engine\server\server.cpp:777:26: style: Operator '|' with one operand equal to zero is redundant. [badBitmaskCheck]
  Packer.AddInt((0 << 1) | (pMsg->m_System ? 1 : 0)); // NETMSG_EX, NETMSGTYPE_EX
                         ^
```
2022-11-29 23:32:28 +01:00
Robert Müller 54a13b1c12 Remove check for negative unsigned expression
According to cppcheck's `unsignedLessThanZero` error:

```
src\engine\shared\datafile.cpp:129:13: style: Checking if unsigned expression 'Bytes' is less than zero. [unsignedLessThanZero]
   if(Bytes <= 0)
            ^
```
2022-11-29 23:32:27 +01:00
Robert Müller fd208eaa1a Remove redundant variable assignments
The assigned values are never used, so the assignments can be removed or variable scopes can be reduced.

According to cppcheck's `unreadVariable` error.
2022-11-29 23:32:26 +01:00
Robert Müller 94678ef3a3 Remove unused struct CDatafileData 2022-11-29 23:28:36 +01:00
Robert Müller e07bd45e27 Fix stored commands using original callback instead of the chain
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.
2022-11-29 23:06:50 +01:00
Robert Müller 0e77be2166 Fix client crash when unpacking a sixup packet
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)
```
2022-11-24 21:12:40 +01:00
Robert Müller 26e35d3a56 Fix choppy demo seeking when start/end ticks are very large
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`.
2022-11-21 00:22:46 +01:00
Robert Müller 7ae5b1474a Add TYPE_ALL_OR_ABSOLUTE and TYPE_SAVE_OR_ABSOLUTE storage types
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.
2022-11-20 16:07:40 +01:00
bors[bot] b21ba35225
Merge #5599
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>
2022-11-06 21:40:48 +00:00
Robert Müller 896dd4ecd4 Add IStorage::FindFiles to find all files with a specific name
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.
2022-11-05 15:42:39 +01:00
bors[bot] 571b0b36de
Merge #5770
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>
2022-11-01 10:29:53 +00:00
Jupeyy 3b2dd73614 Rename config var to no weak only 2022-10-27 17:51:30 +02:00
Rafael Fontenelle cd14660307 Fix misspellings 2022-10-25 13:51:56 -03:00
Robert Müller 326a0a576d Fix slicing a demo opened with absolute path not working
Slicing a demo opened from command line with an absolute path did not work, as the game only tried to load the source demo from storage instead of using the given absolute path.
2022-10-24 20:15:49 +02:00
Dennis Felsing eb27b26d8d Also ignore min value 2022-10-21 00:34:44 +02:00
Dennis Felsing 26a08360f8 Don't print max value when there is none (fixes #5953) 2022-10-21 00:09:30 +02:00
heinrich5991 623a8935fb Add client_score_kind field to serverinfo
It specifies whether the scores are to be interpreted as times (string
value starting with "time") or as points (string value starting with
"points").
2022-10-20 00:43:38 +02:00
heinrich5991 dcd76fd3e1 Add support for Rust code in DDNet
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
```
2022-10-19 23:46:06 +02:00
heinrich5991 ea17fc753e Enable antispoof for vanilla by default
Having it disabled opens up the server for attacks.
2022-10-13 09:55:39 +02:00
ChillerDragon 9982a7bad3 Constify snap more (inspired by upstream)
Incorporate const added in those upstream commits:
d86d576217
e6b8518b49
2022-10-09 15:12:12 +02:00
def 317b2df7c0 Support multiple values to search/exclude (fixes #4119) 2022-10-07 18:21:14 +02:00
Robert Müller 3c5a9f7672 Print the operating system version on client/server launch 2022-10-03 13:19:31 +02:00
def 55ff665894 Less logging when loading maps on expected path 2022-10-01 22:46:39 +02:00
Robert Müller 9d1f393c55 Fix unknown command handler for filenames containing spaces
Pass the original string to the unknown command callback instead of the parsed command, as the latter ends at the first whitespace, which breaks for unknown commands (filenames) containing spaces.

Closes #5902.
2022-10-01 20:10:59 +02:00
Robert Müller f97067738e Use CreateFolder instead of fs_makedir + GetPath
As the former method is a wrapper for the latter two with additional log messages on errors.
2022-09-27 16:33:24 +02:00
Robert Müller 5482571c69 Add assertions for invalid storage arguments 2022-09-27 16:33:24 +02:00
Robert Müller a3f5d1b924 Use TYPE_SAVE instead of 0 2022-09-27 16:33:24 +02:00
Robert Müller 4fd983dc03 Add missing error handling for RenameBinaryFile 2022-09-27 16:33:24 +02:00
Robert Müller 481fb33efa Show log message when a storage path cannot be added 2022-09-27 15:25:04 +02:00
Robert Müller 2db41124b5 Use for-each loop for array apDirs 2022-09-27 15:25:04 +02:00
Robert Müller e21f9c609b Remove unnecessary virtual of GetPath method 2022-09-27 15:25:04 +02:00
Robert Müller 6fbcfb6fd9 Move variable declarations 2022-09-27 15:25:04 +02:00
Robert Müller c5d96eb0f6 Rename variable p to pStorage 2022-09-27 15:25:04 +02:00
Dennis Felsing e290a407d6 Fix other occurences of DDNet.tw 2022-09-23 10:59:36 +02:00
heinrich5991 884cf75cb8 Stop server if started with old curl and incompatible sv_register
This prevents accidentally falling victim to the bug #5858.
2022-09-22 00:09:02 +02:00
heinrich5991 28359fb23d Also print the CURLcode on failed requests
This should help debugging the empty error messages we sometimes get on
servers.
2022-09-19 15:06:27 +02:00
bors[bot] 069e5a7c9d
Merge #5848 #5851
5848: Remove cl_http_map_download r=heinrich5991 a=def-

![screenshot-20220918@010406](https://user-images.githubusercontent.com/2335377/190879092-3ca64914-15c5-4835-9fe6-fd9fe75aa57d.png)
Causes problems with GER3
## 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
- [ ] 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)


5851: Respect reserved slots in old serverinfo r=heinrich5991 a=def-

Noticed in https://github.com/ddnet/ddnet/pull/5850 that reserved slots were not respected

<!-- 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: def <dennis@felsin9.de>
2022-09-18 11:40:11 +00:00
def 9f4e883906 Remove cl_http_map_download 2022-09-18 01:03:15 +02:00
bors[bot] e61b850364
Merge #5843
5843: Laser menu tweaks; Changed some default colors r=def- a=VoxelDoesCode

fixes #5841 

![image](https://user-images.githubusercontent.com/95713843/190824834-a48913ec-360a-40a8-8b48-d278f5916493.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>
2022-09-17 22:16:26 +00:00
VoxelDoesCode 71b073a45f New SG Laser default, Reset to defaults 2022-09-17 17:11:53 -04:00
VoxelDoesCode 5915d5531d Laser menu tweaks; Changed Freeze laser color 2022-09-16 18:28:36 -04:00
Learath f91a3069c3 Let CKernel clean-up. Use unused CSound::Shutdown 2022-09-16 16:50:19 +02:00
bors[bot] 55703c971c
Merge #5829
5829: Add HTTPS map download URL field for game servers r=def- a=heinrich5991

This allows every game server to provide its own HTTPS server for map
downloads. Since the ingame protocol for downloading map data is very
inefficient, this is desirable. Previously, only servers hosted by DDNet
could benefit from this.

Security concerns:
- Attackers can find out whether a given HTTPS GET request matches a
  known answer.

  This isn't deemed to be problematic as no cookies for authentication
  are sent and only the whole response can be matched.

- Sending requests to honeypot URLs to get people in legal trouble.

  This seems to be already possible with HTML image embeds, so it can't
  be that bad™.

- Downloading huge files, filling up a player's disk. The players might
  cancel when seeing huge files.

  There's a generous limit of 1 GiB per map file.

- Downloading huge files transparently compressed with gzip. See above.

Fixes #5812.

## 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: heinrich5991 <heinrich5991@gmail.com>
2022-09-15 08:54:46 +00:00
heinrich5991 0bf941e6c9 Add MaxResponseSize to limit HTTP response sizes 2022-09-15 02:08:35 +02:00
heinrich5991 9f1dd0d3c4 Disallow HTTP (without S) requests by default
Add a non-saved config variable `http_allow_insecure` to re-enable HTTP
support; this is mostly useful for testing stuff.

Disallowing HTTP by default allows fewer insecure data to be sent and
received by the DDNet client.
2022-09-15 01:29:13 +02:00
fokkonaut 5deeb299fa Add DDNetLaser to have more info about a laser shot 2022-09-15 01:01:32 +02:00
VoxelDoesCode 03b90f4f3d Added new cl colors and tweaked the settings menu
Merging of DoLaserPreview and static int fix

Replace if else statement with switch function

Adjusted RenderDropDown header to match

static int cbuttoncontainer fix, potential bugs
2022-09-15 01:01:04 +02:00
Dennis Felsing b26dd29a23 Use bindaddr for curl too (fixes #5831) 2022-09-13 19:45:17 +02:00
Dennis Felsing a67e30647e Add sv_sql_bindaddr (fixes #5830) 2022-09-13 17:09:53 +02:00
heinrich5991 94446f65bd Ignore server info with control characters
This simply treats server info as invalid if it contains control
characters in any string.

Fixes #5826.
2022-09-11 23:42:05 +02:00
heinrich5991 5028423a0a Fix close messages not being shown when connecting
Previously, close messages were entirely ignored during the connection
process, this meant that ban messages weren't shown to players. Instead,
they'd see the standard "no answer from server yet" message.

Fixes #5792.
2022-09-03 20:25:22 +02:00
Robert Müller fe38caa7b4 Handle path/link arguments using the console argument parser
Add `IConsole::SetUnknownCommandCallback` to set a callback for unknown commands. The callback is used to handle connect links, .demo and .map files when parsing command line arguments.

This will allow paths/links to be passed at any argument position instead of only the first one.

And this fixes the command `play xyz.demo` not working due to `play ` being considered part of the path.
2022-08-30 22:17:04 +02:00
def c479230d71 Use new ddnet.org domain 2022-08-30 10:09:06 +02:00
Robert Müller c6cc45471a Allow spectator mode to be changed while demo is paused
By updating and rendering the current tick again when changing the spectator mode while the demo playback is paused.

Refactoring: Extract `IDemoPlayer::ETickOffset`, `IDemoPlayer::SeekTick` and `CMenus::DemoSeekTick`.
2022-08-28 17:52:49 +02:00
Robert Müller 76cefa1c85 Faster and more precise demo skipping
- Approximate index of wanted keyframe to decrease linear search time.
- Only apply the magic `-5` to the Keyframe calculation, to make seeking with the mouse more accurate.
- After the method returns, the specified tick will be the _next_ tick being played instead of being the current tick.
2022-08-27 12:49:32 +02:00
Robert Müller 334bdad922 Fix demo intratick times not being updated when paused 2022-08-27 12:49:32 +02:00
Robert Müller 3ec4075ddb Move variable declarations closer to usages 2022-08-27 12:49:32 +02:00
Robert Müller 6f101f54af Rename method CDemoPlayer::time to Time 2022-08-27 12:49:32 +02:00
Robert Müller 64f326d626 Remove unused CDemoPlayer::NextFrame method 2022-08-27 11:39:03 +02:00
Robert Müller 3f1b702b90 Fix demos recorded without mapdata not being loadable
As the demo player skips the map data when loading the demo, the size of the map specified in the demo must be zero when no map data is embedded.
2022-08-25 17:57:04 +02:00
Dennis Felsing 2ccca3a50a Fix memset compilation
/home/deen/isos/ddnet/ddnet-source/src/tools/map_create_pixelart.cpp: In function ‘int InsertPixelArtQuads(CQuad*, int&, const CImageInfo&, const int*, const int*, const bool*)’:
/home/deen/isos/ddnet/ddnet-source/src/tools/map_create_pixelart.cpp:110:9: error: ‘memset’ was not declared in this scope
  110 |         memset(aVisitedPixels, 0, sizeof(bool) * Img.m_Height * Img.m_Width);
      |         ^~~~~~
/home/deen/isos/ddnet/ddnet-source/src/tools/map_create_pixelart.cpp:8:1: note: ‘memset’ is defined in header ‘<cstring>’; did you forget to ‘#include <cstring>’?
    7 | #include <game/mapitems.h>
  +++ |+#include <cstring>
    8 |
2022-08-25 14:07:49 +02:00
bors[bot] 49bed71932
Merge #5696
5696: Add option for parallax-aware zoom r=def- a=Fireball-Teeworlds

## How this works

Currently we have parallax X and Y parameters that control how far away a layer feels. Currently it's only taken into account for camera moving sideways.

This pull request makes zoom behave as if the camera was moving closer or further away, taking into account the distance to the layer.

In order to provide flexibility, this behaviour is using a separate parallax value, similar to how we have separate values for X and Y. Para Zoom will default to the minimum of parallax X, Y, clamped to be between 0 and 100. This seems to look well on most maps.

This pull request also introduces two new features to the Editor:
* Controls for configuring per-group Para Zoom value. If Custom Zoom is set to No, Para Zoom will automatically keep following to the default value described above, so that people new to the feature don't have to figure out how it works.
* Zoom button that previews the zoom behavior (next to Proof at the top).

## Editor Screenshots

### Para Zoom controls

![screenshot_2022-08-22_21-38-04](https://user-images.githubusercontent.com/68162181/186014490-f7b91245-460f-405f-8d5c-3f91db2a1b9a.png)

![screenshot_2022-08-22_21-37-58](https://user-images.githubusercontent.com/68162181/186014522-03b6e814-4dd9-4d07-9af9-7db5fb434a56.png)

### Zoom Button

![screenshot_2022-08-22_21-40-46](https://user-images.githubusercontent.com/68162181/186014856-2d1d499d-9011-439c-b217-536957e0c1e3.png)

![screenshot_2022-08-22_21-40-50](https://user-images.githubusercontent.com/68162181/186014874-6d2939d3-00ff-4327-a790-414b5151ba31.png)

## In-Game Screenshots

Video: https://youtu.be/W7eXQN0gRFI

This is an older version of the pull request that had an option to disable the new behaviour. The current version can only be disabled in map editor for a particular map.

### Springlobe 3

With new feature:
![screenshot_2022-08-02_04-28-19](https://user-images.githubusercontent.com/68162181/182286371-b67cee1c-73d8-4a24-a9c3-1b28340a3b42.png)

Without:
![screenshot_2022-08-02_04-28-25](https://user-images.githubusercontent.com/68162181/182286367-24555381-1700-4ff1-80c7-39e5dce63820.png)

### Beyond Dreams

With new feature:
![screenshot_2022-08-02_04-28-59](https://user-images.githubusercontent.com/68162181/182286322-114ecb90-0860-462c-9012-bb2f3ff848fb.png)

Without:
![screenshot_2022-08-02_04-28-55](https://user-images.githubusercontent.com/68162181/182286654-f34da72b-7991-4f42-89ad-679279fcb83e.png)

## Checklist

- [X] Tested the change ingame
- [X] Provided screenshots if it is a visual change
- [X] 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
- [ ] 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: Fireball <fireball.teeworlds@gmail.com>
2022-08-22 21:15:41 +00:00
Robert Müller f3eb93b83a Extend IConsole::PossibleCommands, add index to callback
`PossibleCommands` now passes the item index to the callback and returns the total number of items.

Add `EmptyPossibleCommandCallback` as default parameter.
2022-08-11 10:08:06 +02:00
bors[bot] f8fca99e62
Merge #5642
5642: Option to remove weak hook & bounce r=def- a=Jupeyy

Fixes #5641 
server side only

## 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: Jupeyy <jupjopjap@gmail.com>
2022-08-09 13:59:21 +00:00