Commit graph

5056 commits

Author SHA1 Message Date
furo 9627e7b3a8 Simplify TickSpeed getters 2023-11-23 15:33:30 +01:00
furo b9fd612ef5 Replace 50 with SERVER_TICK_SPEED or TickSpeed() 2023-11-23 14:42:30 +01:00
Robert Müller 61c201c37c Fix string game settings not being reset correctly
Due to swapped `str_copy` arguments, the old value for string game variables was being overridden by the current value instead of the other way around in `CConsole::ResetGameSettings`.

There are currently no string game settings affected by this.
2023-11-22 23:16:57 +01:00
Robert Müller d331bcb496 Fix color game settings not being reset correctly
Handling color settings the same as int settings in `CConsole::ResetGameSettings` is not correct, as this causes the color variable data to be cast to int variable data.

There are currently no color game settings affected by this.
2023-11-22 23:12:56 +01:00
Robert Müller 48bfecc0d3 Ensure debug dummies are not included in server info
Also fix normal clients being disconnected/controlled like debug dummies.

Closes #7523.
2023-11-22 19:23:38 +01:00
heinrich5991 f95b0f163f
Merge pull request #7520 from Robyt3/Packer-Improvements
Minor improvements to `CPacker` and `CUnpacker`
2023-11-22 16:44:30 +00:00
Robert Müller ab4e737a57 Fix misaligned int loads in CUnpacker::GetUncompressedInt
Use `mem_copy` instead of dereferencing potentially misaligned address as `int`.
2023-11-21 21:57:06 +01:00
Robert Müller 51e3c37c03 Use mem_copy instead of for-loop in CPacker::AddRaw
Using `memcpy` is faster, assuming the compiler doesn't already transform the loop to `memcpy` automatically.
2023-11-21 21:49:29 +01:00
Robert Müller 0d8a0d3b1d Dynamically connect/disconnect debug dummies, cleanup
Call expected server callback functions to simulate clients dynamically connecting and disconnecting when changing the `dbg_dummies` variable. This makes the debug dummies more useful for debugging. Previously, the debug dummies were considered invalid clients, whereas they are now considered to be ingame, so they should behave mostly like real clients being connected to the server. The debug dummies also have correct client names now, e.g. "Debug dummy 42".

The game server code is cleaned up by moving all special handling for debug dummies to the engine server function `CServer::UpdateDebugDummies`.

The left/right direction inputs for debug dummies are now properly added to the client input array, so their input handling should be consistent with normal clients, which fixes some inconsistent prediction with debug dummies.
2023-11-21 19:59:20 +01:00
Dennis Felsing 35f071b021
Merge pull request #7513 from Robyt3/ImageLoader-Greyscale-Fix
Handle all color channel counts in image loader, refactoring
2023-11-20 21:55:00 +00:00
Robert Müller 29a32b7acc Use const char * instead of char const * consistently
Both are equivalent. Seems to already be used consistently for all other types.
2023-11-20 22:26:19 +01:00
Robert Müller bcae7da6b4 Handle all color channel counts in image loader
Greyscale images with alpha channel (i.e. channel count = 2) were incorrectly handled as RGBA images, causing the client to crash when loading such images. Now the images can successfully be loaded with the image loader, but the client still only supports loading RGB and RGBA images like before.
2023-11-20 21:58:29 +01:00
Robert Müller f0a17435e6 Ensure freed image buffer is not propagated
The image data is freed when the image format is unsupported, but `CImageInfo::m_pData` would still point to the freed memory, so double-frees were possible.
2023-11-20 21:58:29 +01:00
Robert Müller 82b75ddfe0 Improve error log messages for PNG loading 2023-11-20 21:58:29 +01:00
Robert Müller 0427dfff2e Use bool instead of int 2023-11-20 21:58:29 +01:00
Robert Müller 15e4f9a886 Remove remaining obsolete // ignore_convention comments 2023-11-20 21:58:29 +01:00
Dennis Felsing d11a271f45
Merge pull request #7506 from trml/pr_predmargin_simplify
Make prediction margin take effect instantanously
2023-11-19 21:56:40 +00:00
dobrykafe 904abae6ac replace sizeof x with sizeof(x) 2023-11-19 22:36:47 +01:00
trml 717aad2677 Make prediction margin take effect immediately 2023-11-19 19:52:39 +01:00
heinrich5991 b4567d6e25
Merge pull request #7502 from Robyt3/Browser-CommunityFilter-Fixes
Prevent community filters excluding all elements, fix server browser update on community filter change via console
2023-11-19 16:24:52 +00:00
Robert Müller aba67f46ee Prevent community filters excluding all elements
Ensure that community/country/type filters do not exclude all allowed elements, which can happen when a previously selected community is not available anymore or when arbitrary community filter values are set with the console.
2023-11-19 15:34:33 +01:00
heinrich5991 a5b72fef42 Allow antibot to kick people 2023-11-19 14:59:14 +01:00
heinrich5991 28b00892f6 Allow more complex interaction with the antibot via the console
Allows the antibot to receive arbitrary console commands.
2023-11-19 04:41:56 +01:00
Dennis Felsing 97d64cdfea
Merge pull request #6256 from heinrich5991/pr_ddnet_typesafe_mem_zero
Typesafe `mem_zero` function
2023-11-18 23:00:48 +00:00
heinrich5991 b951734c03 Don't allow mem_zero for nontrivial types
Initialize nontrivial types with a constructor instead. Make the
compiler aware that some of our constructors are indeed trivial.

This allows `mem_zero` calls to actually always zero the memory.
2023-11-18 22:55:17 +01:00
Robert Müller ddf935795d Fix inverted community parsing conditions 2023-11-18 22:55:08 +01:00
Chairn 6e629e1deb Type safe mem_zero function (fixes #5228)
Partially replaces #5690.
POD types are just memset. Other types are either destructed if not
trivial and/or constructed if not trivial. Types need to have a default
constructor.
Virtual classes can be mem_zeroed only if they already have been
constructed, otherwise it is UB.
2023-11-18 22:47:22 +01:00
Robert Müller ee04cd4dda
Merge pull request #7459 from heinrich5991/pr_ddnet_community_json
Add icon URL, remove `servers-key`/`ranks-key` from community JSON
2023-11-18 21:08:23 +00:00
heinrich5991 c7cd281aff Add icon URL, remove servers-key/ranks-key from community JSON
Previously:

```json
{
  "ddnet": {
    "name": "DDraceNetwork",
    "servers-key": "servers",
    "ranks-key": "maps",
    "icon-sha256": "162313eeb954e34495ad03066fee1418ed3c963e76cc83dff993e1c7856c742b"
  }
}
```

Now:
```json
[
  {
    "id": "ddnet",
    "name": "DDraceNetwork",
    "icon": {
      "sha256": "162313eeb954e34495ad03066fee1418ed3c963e76cc83dff993e1c7856c742b",
      "url": "https://info.ddnet.org/icons/ddnet.png"
    },
    "ranks": [
      …
    ],
    "servers": {
      …
    }
  }
]
```

Special case `ddnet` to look for the `servers`, `maps` in the top-level
and `kog` to look for `servers-kog` in the top-level.
2023-11-18 21:52:51 +01:00
Robert Müller fcddc165b2 Remove unnecessary mem_zero of ringbuffer memory
Zeroing the entire ringbuffer memory is unnecessary and inefficient. Only the first item in the ringbuffer has to be initialized properly.

It's unlikely that existing code depends on allocated memory being zeroed, as recycled ringbuffer items where never zeroed.
2023-11-18 17:40:36 +01:00
Robert Müller 5c7bb58457 Ensure filenames are valid UTF-8 on Unix
On Unix, the encoding of filenames is unspecified, although UTF-8 is likely used in most cases. Detecting and converting from several possible encodings to UTF-8 would be too much effort, considering that most systems already use UTF-8 per default. Therefore, any filenames which are not valid UTF-8 will be ignored when listing directories with `fs_listdir(_fileinfo)`, `fs_storage_path` will fail if the storage location is not valid UTF-8 and `fs_getcwd` will fail if the current working directory is not valid UTF-8. Paths specified in `storage.cfg` must also be valid UTF-8.

On Windows, we already ensure that all filenames are converted to UTF-8.
2023-11-17 18:55:28 +01:00
ChillerDragon 9e27a5a107 Fix unused variabled m_WasRecording 2023-11-15 12:11:58 +01:00
Dennis Felsing e74e6770c3
Merge pull request #7325 from Robyt3/Browser-Community-Filter
Add community server filter and icons, remove DDNet and KoG tabs
2023-11-12 00:00:05 +00:00
Dennis Felsing d716210e31
Merge pull request #7408 from Jupeyy/pr_tile_border_shader
Switch to a fragment shader solution for border tile rendering
2023-11-11 23:02:34 +00:00
Dennis Felsing aefa52c6b9
Merge pull request #7432 from Robyt3/Base-Standard-Mutex-Wrapper
Add `CLock` wrapper for `std::mutex` to replace `lock_*` functions, use `CLock` instead of `std::mutex`, add thread-safety annotations
2023-11-11 22:07:02 +00:00
furo 6599b7e14b Save unknown commands from settings_ddnet.cfg 2023-11-11 19:09:13 +01:00
Robert Müller 10470046b7 Use CLock instead of std::mutex, add thread-safety annotations
Use `CLock` and `CLockScope` instead of `std::mutex` and add clang thread-safety analysis annotations everywhere except for usages in engine graphics and video, as those usages also involve `std::condition_variable`.

Fix lock not being unlocked on all code paths in `CFutureLogger::Log`, which is caught by the static analysis.
2023-11-11 00:09:17 +01:00
Robert Müller 3d858c28ee Add CLock wrapper for std::mutex to replace lock_* functions
Replace usages of platform specific `lock_*` functions with `std::mutex` through the wrapper class `CLock`. Move lock classes to `base/lock.h`.

The `CLock` wrapper class is only necessary because the clang thread-safety attributes are not available for `std::mutex` except when explicitly using libc++.
2023-11-11 00:04:57 +01:00
Robert Müller b4423551d4 Fix client not quitting after graphics assertion
After the error message popup is shown for graphics assertions, the client window was destroyed but the process was not terminated properly. Now the graphics assertion error is handled like a normal assertion error, as those are also shown in an error message popup and correctly cause the client to break into the debugger or terminate.

However, calling `dbg_assert` while already owning the lock that `WaitForIdle` waits on will cause a deadlock, so error handling must be delayed until after the lock is released.

The buffer size for assertion messages is increased, as it was not sufficient for some graphics assertions.

The `ICommandProcessor::GetError` and `ICommandProcessor::GetWarning` functions are marked as `const`.
2023-11-06 23:34:05 +01:00
Robert Müller 3e5a2888bc Support writing maps with more items/data
Previously, the client would crash with an assertion when writing more than 1024 items, 1024 data items or 64 extended item types to a map file. This arbitrary limitation is removed by using `std::vector`s, so much larger maps can be written. This was only a limitation when writing map files. Old clients can correctly read the map files having more items/data but will crash when the map is saved in the editor.
2023-11-04 22:54:18 +01:00
Robert Müller d39247f726 Add community server filter and icons, remove DDNet and KoG tabs
Remove the DDNet and KoG tabs and replace them with a community filter, which works like the country and type filters. Community information (ID, name, icon SHA256, countries, types, servers, ranked maps) is loaded dynamically from the DDNet info json.

The official checkmark icon is replaced with community icons. The icons are downloaded to the `communityicons` folder in the config directory from a URL specified in the DDNet info json. The icons are only re-downloaded when their SHA256 has changed.

Per default, the Internet tab with all communities is selected. When starting the client for the first time, only the DDNet community is selected. The community, country and type filters can also be used on the Favorites tab now. The LAN tab remains unchanged.

The country and type filters are refactored. Previously, using these filters changed the total number of servers and players that were displayed, as the filter was implemented as a separate step. Now the community, country and type filters work like the other browser filters. This also has the benefit that the server list and DDNet info json are not reloaded each time these filters are changed, as updating the local filtering/sorting is enough now.

The check for finished maps is made more efficient by using an `std::unordered_set` instead of linear search.

Closes #5654.
2023-11-04 15:32:27 +01:00
Robert Müller 7f694e8fc9 Add IStorage::CalculateHashes
To conveniently calculate the SHA256 and CRC32 hashes of a file without reading the entire file into memory at once.
2023-11-04 15:24:44 +01:00
Jupeyy 639a8c3c8b Switch to a fragment shader solution for border tile rendering 2023-11-04 14:51:39 +01:00
Robert Müller 367c7ba4e7 Fix some textures being loaded without mipmaps
Some calls to `LoadTextureRaw` where passing the image format also in place of the texture load flags. Since the image format would be RGBA most of the time, this was interpreted as the flag `IGraphics::TEXLOAD_NOMIPMAPS` causing various textures (all sprites textures, assets when shown in menus, menu images, menu theme icons) to be loaded without mipmaps.

This is fixed by passing `0` as the texture load flags and by replacing uses of `LoadPNG` and `LoadTextureRaw` with `LoadTexture`.
2023-11-04 12:54:09 +01:00
Robert Müller 82ba8e0bb8 Add CTextureHandle::IsNullTexture, rename InvalidTexture
Rename `InvalidTexture` to `NullTexture` to avoid confusion because the null texture is not invalid. The function `CTextureHandle::IsNullTexture` is added to make it easier to check the result of using `IGraphics::LoadTexture`, which returns the null texture on error instead of an invalid texture handle. An assertion is added to ensure that `IsNullTexture` works correctly.
2023-11-04 12:54:08 +01:00
Robert Müller fdaa343219 Fix check for invalid texture after LoadTextureRaw
The handle returned by `LoadTextureRaw` is either valid or invalid (i.e. `-1`) but never the invalid texture itself.

Additionally, ensure that the `LoadTexture` function returns the invalid texture also when `LoadTextureRaw` fails.
2023-11-04 12:54:08 +01:00
Dennis Felsing 80c4940b7f
Merge pull request #7403 from Robyt3/Datafile-Writer-Refactoring
Add more assertions to datafile writer, refactoring
2023-11-01 22:02:45 +00:00
Robert Müller ebe2ddea9f Add gameclient warnings to queue instead of overriding others
Using `CMenus::PopupWarning` will immediately set the popup and override the current warning, which can hide warnings when multiple are shown at the same time. Now all warnings are added to the queue with `IClient::AddWarning`.
2023-11-01 22:17:01 +01:00
Robert Müller 9b8eb9d6fc Use for- instead of while-loop, improve comments 2023-11-01 14:07:36 +01:00
Robert Müller 7343ca224c Add CDatafileHeader::SizeOffset to replace magic 16 2023-11-01 14:07:36 +01:00
Robert Müller 64716075f9 Add assertion to ensure correct item IDs are written 2023-11-01 14:07:36 +01:00
Robert Müller 284390cc75 Add assertions to ensure correct map item/data sizes are written
Add assertions to prevent map items and data that are too large to be represented by the map format from being written to maps. Additionally, ensure that the size of the whole map file is not too large to be represented by the map header.

Prevent `malloc` of size 0, which is implementation defined and should be avoided, when adding items without data, which happens for example when adding an empty array of envelope points.
2023-11-01 14:06:28 +01:00
Robert Müller f7722eb016 Remove separate CDataFileWriter::Init/OpenFile functions
Simplify usage of datafile writer by removing duplicate functions for opening file.
2023-11-01 12:54:38 +01:00
BurnyLlama c76352cb9f Altered snd_buffer_size description. Fixes #7229 2023-10-29 19:57:03 +01:00
furo e61ed1c3b4 Small fixes for cl_race_ghost_strict_map
- Better description
- Remove redudant map check
2023-10-28 14:54:35 +02:00
Dennis Felsing 28f4739e46
Merge pull request #7375 from furo321/improve-ghosts
Various improvements to ghosts
2023-10-27 22:06:00 +00:00
furo dadb142f4e Add cl_race_ghost_alpha, add title for ghost settings. 2023-10-27 20:56:57 +02:00
furo b90995da06 Add option to always save ghosts, not only personal bests. 2023-10-27 20:55:35 +02:00
furo c79e4c2de5 Add option to disable ghost map hash check. 2023-10-27 20:51:17 +02:00
Dennis Felsing 80cccaaae9
Merge pull request #7362 from furo321/SvRegionalRankings
Add option to disable printing of regional rankings.
2023-10-27 16:42:23 +00:00
Robert Müller 4845639a00 Fix use of closed demo file when playback stopped due to error
Check whether the demo file has been closed due to a playback error when calling `DoTick` in loops, to prevent crashes on operating systems with assertions for correct C library usage. On Windows, `warning: Invalid parameter passed to C runtime function` was printed to the debug console in this case.
2023-10-25 20:10:15 +02:00
Robert Müller a0d154a841 Bump maximum server password length from 128 to 256
Ensure server password can fit username and password separated by colon, so there is no discrepancy where some passwords work in rcon but not for reserved slots.
2023-10-24 21:44:53 +02:00
Robert Müller 3116fb4bcf Fix ec_output_level default/min/max values, update description
To ensure that all `*_output_level` variables have the same default, minimum and maximum values.
2023-10-24 20:17:09 +02:00
Robert Müller f1e8d4bae3 Remove length limitation when packing server/rcon password
There is no need to limit the length of server password, rcon username, rcon password and rcon commands when packing them into their respective messages. The source buffers for these strings are already limited in length and the message packer ensures that the maximum packet size is not exceeded.
2023-10-24 20:10:42 +02:00
Robert Müller bade6f78fb Reduce duplicate code for sending messages for dummy
Add parameter `int Conn` to `SendInfo` and `SendReady` functions and use existing `SendEnterGame` function to reduce duplicate code for sending the same messages for main and dummy connections.
2023-10-24 20:10:18 +02:00
Robert Müller fec7e89b00
Merge pull request #7356 from dobrykafe/pr-editor-stop-sound-preview
Editor: stop/pause sound previews
2023-10-23 16:52:32 +00:00
furo bf98eec518 Add option to disable regional rankings.
Set config to true in tests

Add test for `´sv_regional_rankings`
2023-10-23 14:02:22 +02:00
dobrykafe c304b3eef8 extract CEditor::OnDialogClose 2023-10-23 12:48:53 +02:00
Robert Müller bea7aea431 Encapsulate CHostLookup member variables
The host lookup job is currently only used for the DNSBL lookup on the server-side and in tests.
2023-10-22 13:38:56 +02:00
Robert Müller f8af7542c6 Move CHostLookup to separate compilation unit
The host lookup job and the engine interface are independent so they are moved to separate files.

The include of `engine.h` in `client.h` is therefore unnecessary and other includes also had to be adjusted because of this.

The variable `m_VersionServeraddr` is unused and therefore removed. The host lookup job is currently not used on the client-side.
2023-10-22 13:38:35 +02:00
Robert Müller 0e4f174f78 Check for all file errors in demo player, show demo error popup
Handle the return values of all uses of the `io_read`, `io_skip` and `io_tell` functions in `CDemoPlayer`, to handle truncated demo files and other unexpected file reading and seeking errors during demo playback.

Show more detailed error message popups when demos cannot be loaded due to errors and when demo playback is stopped unexpectedly due to errors. Previously, only a generic message "Error loading demo" was shown when loading failed and no error message was shown when demo playback is stopped due to errors.
2023-10-19 21:48:04 +02:00
Robert Müller 92e2e17f0f Validate ticks when reading demo chunk headers
Add checks to ensure that the ticks read from demo chunk headers are in the valid range (cf. `MIN_TICK` and `MAX_TICK` constants). Playing demos with invalid ticks is prevented entirely, as the invalid ticks would cause issues in other places. The server never uses ticks outside the valid range, so invalid ticks should never occur in correctly recorded demos.

Additionally, checks are added to detect if a tickmarker chunk with a tick delta occurs before a tickmarker chunk defining an initial tick. The tick delta is only meaningful when an initial tick has already been defined, so if this is not the case the demo is also considered invalid.
2023-10-19 21:41:20 +02:00
Robert Müller 6951795619 Add title to engine warnings and make auto-hiding optional
Make the title of warnings adjustable, with the default title being "Warning" to preserve existing code.

Make auto-hiding configurable, so the automatic closing of warning popups after 10 seconds can be toggled.
2023-10-19 21:40:55 +02:00
dobrykafe aafee689ca stop/pause sound previews 2023-10-18 13:27:31 +02:00
Robert Müller 8fea5998aa Mark functions as const when possible 2023-10-17 20:27:58 +02:00
Robert Müller 59b5fd2793 Fix graphs initially rendering incorrect values
Ensure only valid graph entries are used to render curve line segments.
2023-10-17 20:27:31 +02:00
Robert Müller 11423b88b1 Use full graph width for rendering curve
Previously, roughly one percent of the graph width was not used for the curve values.
2023-10-17 20:25:35 +02:00
Robert Müller 1a01d7657f Remove unused m_Graph member of CSmoothTime 2023-10-17 20:25:32 +02:00
Robert Müller e187bda620 Use bool instead of int 2023-10-17 20:24:45 +02:00
Robert Müller d92b7b5c5f Add enum for CSmoothTime adjust direction 2023-10-17 20:24:38 +02:00
Robert Müller fb96217147 Fix first value in graphs being incorrect
As the index was incremented before setting the value, the value at index 0 was not set correctly until the ringbuffer wraps around.
2023-10-17 20:23:35 +02:00
Robert Müller dc7fa1fbb2 Use ColorRGBA for CGraph entry color 2023-10-17 20:23:16 +02:00
Robert Müller 912355f9ec Move CSmoothTime class to separate compilation unit 2023-10-17 20:23:07 +02:00
Robert Müller ee51cac9e6 Move CGraph class to separate compilation unit 2023-10-17 20:22:48 +02:00
Robert Müller f1e74c12e9 Remove unused IDemoPlayer::GetDemoType and enum literals
We only show the string value directly in the UI instead of using the demotype enum literals. There also should not be any reason to change any logic depending on whether the current demo is a server- or client-demo.
2023-10-16 22:06:28 +02:00
Robert Müller af4b1c9c97 Remove tick error debug message
This is shown every time demo playback ends when reaching the end of the file and it does not really help debugging.
2023-10-16 22:06:19 +02:00
Robert Müller ed92a9e8c7 Remove redundant checks for missing SHA256 when recording demo
The SHA256 was effectively not optional anymore when recording demos, as it and the SHA256 extension UUID were always written to the demo file without checking for `nullptr`. Therefore the SHA256 is now passed by const reference instead of by pointer and redundant checks for `nullptr` are removed.
2023-10-16 21:53:37 +02:00
Robert Müller f7b8738f91 Remove obsolete TODO about improving demo player map checking
We already use `CClient::LoadMapSearch` to load maps for demo playback, so maps in the `maps` folder are already considered. Using the map CRC is deprecated, we do not want to check it.
2023-10-16 21:53:37 +02:00
Robert Müller dbbae72ca7 Move variable declarations closer to usages 2023-10-16 21:53:37 +02:00
Robert Müller 9b68b9deef Use bool instead of int 2023-10-16 21:53:36 +02:00
Robert Müller 1333ac34f4 Use nullptr instead of 0 and NULL 2023-10-16 21:53:36 +02:00
Robert Müller 568177114f Remove unnecessary parentheses 2023-10-16 21:53:36 +02:00
Robert Müller 82d94faf28 Refactor GetDemoName using IStorage::StripPathAndExtension
The functions were effectively identical already.
2023-10-16 21:53:32 +02:00
Robert Müller c3b8c94212 Use std::vector for demo player keyframes
Using an `std::vector` is simpler and more readable than first allocating a linked list on a heap and later copying the list to an array.

The variable `m_SeekablePoints` is removed from `CPlaybackInfo`, as it does not need to be exposed outside of `CDemoPlayer` and can be replaced with the size of the vector.
2023-10-16 21:53:29 +02:00
Robert Müller cd4a13e74c Remove unnecessary check for open file in ReadChunkHeader
The function is only used internally and never called when the file is not open.
2023-10-16 20:50:43 +02:00
Dennis Felsing 042a04d610
Merge pull request #7353 from Robyt3/Engine-Jobpool-Refactoring
Minor refactoring of engine jobpool
2023-10-15 22:29:33 +00:00
Robert Müller 22352316d8 Give jobpool worker threads different names based on index 2023-10-15 22:10:50 +02:00
Robert Müller ba5a974353 Increase jobpool thread count based on hardware concurrency
The client/server jobpools were previously only using a fixed number of 2 threads. Now the pools use `2 * hardware-concurrency + 2` threads, which should provide better performance overall, as we expect threads to often wait on I/O.
2023-10-15 22:10:49 +02:00
Robert Müller 2dcec6496f Use std::vector for jobpool threads
To simplify the usage and to support an arbitrary number of threads.
2023-10-15 22:00:25 +02:00
Robert Müller 9cbbc0aca6 Replace static variables in MouseRelative with member variable
Avoid using a global variable for last mouse position on Android.
2023-10-15 20:36:59 +02:00