{"id":28481670,"url":"https://github.com/bigbang1112/tm-essentials","last_synced_at":"2026-02-07T17:05:50.265Z","repository":{"id":39616105,"uuid":"385800437","full_name":"BigBang1112/tm-essentials","owner":"BigBang1112","description":"A super lightweight library that provides formatting features and little additions for any development related to Trackmania.","archived":false,"fork":false,"pushed_at":"2025-03-28T20:17:21.000Z","size":299,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-07T20:08:12.267Z","etag":null,"topics":["csharp","essentials","trackmania"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BigBang1112.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-14T03:18:33.000Z","updated_at":"2025-03-28T20:11:33.000Z","dependencies_parsed_at":"2023-12-18T19:06:55.948Z","dependency_job_id":"e523dcd3-92e7-480a-83d0-4c3f9eff03d8","html_url":"https://github.com/BigBang1112/tm-essentials","commit_stats":{"total_commits":96,"total_committers":1,"mean_commits":96.0,"dds":0.0,"last_synced_commit":"5357d86d96c22c0ac2a4219430ca3484b730b530"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/BigBang1112/tm-essentials","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigBang1112%2Ftm-essentials","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigBang1112%2Ftm-essentials/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigBang1112%2Ftm-essentials/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigBang1112%2Ftm-essentials/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BigBang1112","download_url":"https://codeload.github.com/BigBang1112/tm-essentials/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BigBang1112%2Ftm-essentials/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263614374,"owners_count":23488905,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","essentials","trackmania"],"created_at":"2025-06-07T20:08:11.709Z","updated_at":"2026-02-07T17:05:50.259Z","avatar_url":"https://github.com/BigBang1112.png","language":"C#","readme":"# Trackmania Essentials\n\n[![Nuget](https://img.shields.io/nuget/v/TmEssentials?style=for-the-badge\u0026logo=nuget)](https://www.nuget.org/packages/TmEssentials/)\n[![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/tm-essentials?include_prereleases\u0026style=for-the-badge\u0026logo=github)](https://github.com/BigBang1112/tm-essentials/releases)\n[![Code Coverage](https://img.shields.io/badge/Code%20Coverage-87%25-success?style=for-the-badge)](https://github.com/BigBang1112/tm-essentials)\n\nA super light-weight library that provides formatting features.\n\n## Time formatting\n\n### Two new structs: `TimeInt32` and `TimeSingle`\n\n- Storage size is half smaller than with `TimeSpan`.\n- Reduced floating point errors, previously caused by `double`/`float` casting.\n- Struct methods are nearly the same to `TimeSpan`.\n- Consistency is partially covered by the `ITime` interface.\n- Implicitly modified `ToString()` to use a Trackmania-familiar format.\n- `ToTmString()` extension methods for consistency reasons (due to nullable value types).\n- Parse methods are available.\n- Supports `TypeConverter` for input binding scenarios.\n\nExample usage of `TimeInt32`:\n\n```cs\nTimeInt32 time = new TimeInt32(TotalMilliseconds: 36217);\nstring formattedTime = time.ToTmString(); // ToString() acts the same\nConsole.WriteLine(formattedTime); // Output: 0:36.217\n\nstring formattedTimeUsingHundredths = time.ToTmString(useHundredths: true);\nConsole.WriteLine(formattedTimeUsingHundredths); // Output: 0:36.21\n\nstring formattedTimeUsingApostrophe = time.ToTmString(useApostrophe: true);\nConsole.WriteLine(formattedTimeUsingApostrophe); // Output: 0'36''217\n\nTimeInt32? noTime = null;\nstring formattedNoTime = noTime.ToTmString();\nConsole.WriteLine(formattedNoTime); // Output: -:--.---\n\nstring formattedNoTimeUsingHundredths = noTime.ToTmString(useHundredths: true);\nConsole.WriteLine(formattedNoTimeUsingHundredths); // Output: -:--.--\n\nstring formattedNoTimeUsingApostrophe = noTime.ToTmString(useApostrophe: true);\nConsole.WriteLine(formattedNoTimeUsingApostrophe); // Output: -'--''---\n```\n\nExample usage of `TimeSingle`:\n\n```cs\nTimeSingle time = new TimeSingle(TotalSeconds: 23.51f);\nstring formattedTime = time.ToTmString();\nConsole.WriteLine(formattedTime); // Output: 0:23.510\n\nstring formattedTimeUsingHundredths = time.ToTmString(useHundredths: true);\nConsole.WriteLine(formattedTimeUsingHundredths); // Output: 0:23.51\n\nstring formattedTimeUsingApostrophe = time.ToTmString(useApostrophe: true);\nConsole.WriteLine(formattedTimeUsingApostrophe); // Output: 0'23''510\n\nTimeSingle? noTime = null;\nstring formattedNoTime = noTime.ToTmString();\nConsole.WriteLine(formattedNoTime); // Output: -:--.---\n\nstring formattedNoTimeUsingHundredths = noTime.ToTmString(useHundredths: true);\nConsole.WriteLine(formattedNoTimeUsingHundredths); // Output: -:--.--\n\nstring formattedNoTimeUsingApostrophe = noTime.ToTmString(useApostrophe: true);\nConsole.WriteLine(formattedNoTimeUsingApostrophe); // Output: -'--''---\n```\n\n### Formatting extensions for TimeSpan\n\n- Same formatting features like `TimeInt32`/`TimeSingle` has but on `TimeSpan`.\n- `TimeSpanExtensions.ToMilliseconds()` - Total milliseconds as integer value with truncated ticks.\n\n## Text formatting\n\nCurrently only deformat.\n\nCredits to [Tom](https://github.com/ThaumicTom) and [Stefan Baumann](https://github.com/stefan-baumann) for their effective Regex pattern.\n\n`TextFormatter.Deformat()`\n\n```cs\nvar formatted = \"$F00T$D01M$C13U$A14.$815K$727r$528a$329z$23By$03CC$03Co$04Bl$059o$068r$077s$085 $094v$0A30$0B1.$0C01\";\nvar deformatted = TextFormatter.Deformat(formatted);\nConsole.WriteLine(deformatted);\n\n// Output: TMU.KrazyColors v0.1\n```\n\n## ANSI formatting of Trackmania string\n\nCredits to [reaby](https://github.com/reaby) for the solution.\n\n```cs\nvar formatted = \"$F00T$D01M$C13U$A14.$815K$727r$528a$329z$23By$03CC$03Co$04Bl$059o$068r$077s$085 $094v$0A30$0B1.$0C01\";\nvar ansiFormatted = TextFormatter.FormatAnsi(formatted);\n\n// Rough output: \\\\u001b[1;31mT\\\\u001b[1;31mM\\\\u001b[1;31mU\\\\u001b[0;31m.\\\\u001b[0;35mK\\\\u001b[0;35mr\\\\u001b[0;34ma\\\\u001b[0;34mz\\\\u001b[1;34my\\\\u001b[0;34mC\\\\u001b[0;34mo\\\\u001b[0;34ml\\\\u001b[0;36mo\\\\u001b[0;36mr\\\\u001b[0;36ms\\\\u001b[0;32m \\\\u001b[0;32mv\\\\u001b[0;32m0\\\\u001b[0;32m.\\\\u001b[0;32m1\\\\u001b[39m\\\\u001b[22m\n```\n\n[image soon]\n\n## Accounts formatting\n\nCurrently only has a ***very*** efficient account ID/login converter.\n\n`AccountUtils.ToAccountId()`\n\n```cs\nAccountUtils.ToAccountId(\"v89i_w-eQKq5JBG5xwuKCQ\") // \"bfcf62ff-0f9e-40aa-b924-11b9c70b8a09\"\n```\n\n`AccountUtils.ToLogin()`\n\n```cs\nAccountUtils.ToLogin(Guid.Parse(\"bfcf62ff-0f9e-40aa-b924-11b9c70b8a09\")) // \"v89i_w-eQKq5JBG5xwuKCQ\"\n```\n\n## Map UID generation\n\nAn approximate implementation of 27-character map UID generation.\n\n`MapUtils.GenerateMapUid()`\n\n## .NET Standard 2+\n\n`HttpClientExtensions.HeadAsync(string requestUri, CancellationToken cancellationToken = default)`\n\nImplements the HEAD request into a simple method. HEAD request is useful for getting the last modified date.\n\n## Benchmarks\n\nThe library tries to be as effective as possible to an absurd level with using managed code only.\n\n```\nBenchmarkDotNet v0.13.11, Windows 11 (10.0.22621.2861/22H2/2022Update/SunValley2)\nAMD Ryzen 7 3700X, 1 CPU, 16 logical and 8 physical cores\n.NET SDK 8.0.100\n  [Host]     : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 [AttachedDebugger]\n  DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2\n\n\n| Method                                                   | Mean       | Error     | StdDev    | Median     | Gen0   | Allocated |\n|--------------------------------------------------------- |-----------:|----------:|----------:|-----------:|-------:|----------:|\n| 'Null with hundredths'                                   |  0.2379 ns | 0.0154 ns | 0.0144 ns |  0.2363 ns |      - |         - |\n| 'Null with milliseconds'                                 |  1.9493 ns | 0.0123 ns | 0.0103 ns |  1.9540 ns |      - |         - |\n| 'Seconds and milliseconds only'                          | 30.5358 ns | 0.6123 ns | 1.0884 ns | 29.9976 ns | 0.0048 |      40 B |\n| '1-digit minute, seconds and milliseconds only'          | 30.5601 ns | 0.6134 ns | 0.5122 ns | 30.4337 ns | 0.0048 |      40 B |\n| '2-digit minute, seconds and hundredths only'            | 30.6992 ns | 0.2823 ns | 0.2358 ns | 30.6543 ns | 0.0048 |      40 B |\n| 'Milliseconds only'                                      | 30.9590 ns | 0.6381 ns | 0.8734 ns | 30.9244 ns | 0.0048 |      40 B |\n| 'Hundredths only'                                        | 31.0166 ns | 0.6434 ns | 1.1098 ns | 30.7131 ns | 0.0048 |      40 B |\n| 'Negative seconds and hundredths only'                   | 31.5512 ns | 0.6633 ns | 0.7896 ns | 31.3869 ns | 0.0048 |      40 B |\n| '1-digit minute, seconds and hundredths only'            | 31.6155 ns | 0.5243 ns | 0.5149 ns | 31.6675 ns | 0.0048 |      40 B |\n| 'Seconds and hundredths only'                            | 31.8579 ns | 0.6069 ns | 1.0140 ns | 31.6990 ns | 0.0048 |      40 B |\n| 'Negative milliseconds only'                             | 31.9256 ns | 0.3962 ns | 0.3513 ns | 31.8951 ns | 0.0048 |      40 B |\n| '2-digit minute, seconds and milliseconds only'          | 31.9811 ns | 0.6515 ns | 0.8698 ns | 31.6213 ns | 0.0048 |      40 B |\n| 'Negative hundredths only'                               | 31.9918 ns | 0.6653 ns | 0.7395 ns | 31.8978 ns | 0.0048 |      40 B |\n| 'Negative 1-digit minute, seconds and milliseconds only' | 32.0097 ns | 0.6535 ns | 0.8498 ns | 31.7147 ns | 0.0048 |      40 B |\n| 'Negative 2-digit minute, seconds and milliseconds only' | 32.2230 ns | 0.6680 ns | 0.7424 ns | 32.1323 ns | 0.0057 |      48 B |\n| 'Negative 1-digit minute, seconds and hundredths only'   | 32.3645 ns | 0.6732 ns | 0.8014 ns | 32.2189 ns | 0.0048 |      40 B |\n| 'Negative seconds and milliseconds only'                 | 33.3655 ns | 0.6869 ns | 1.2902 ns | 33.0008 ns | 0.0048 |      40 B |\n| 'Negative 2-digit minute, seconds and hundredths only'   | 33.8375 ns | 0.4832 ns | 0.4284 ns | 33.8595 ns | 0.0048 |      40 B |\n| 'Hours, minutes, seconds and hundredths only'            | 38.0449 ns | 0.7887 ns | 0.6991 ns | 37.9283 ns | 0.0057 |      48 B |\n| 'Hours, minutes, seconds and milliseconds only'          | 38.2250 ns | 0.7767 ns | 0.9822 ns | 38.2305 ns | 0.0057 |      48 B |\n| 'Negative hours, minutes, seconds and milliseconds only' | 38.2533 ns | 0.4994 ns | 0.4170 ns | 38.3381 ns | 0.0057 |      48 B |\n| 'Negative hours, minutes, seconds and hundredths only'   | 38.6611 ns | 0.5701 ns | 0.5333 ns | 38.5405 ns | 0.0057 |      48 B |\n| 'Fully-used TimeSpan with hundredths'                    | 40.3112 ns | 0.4293 ns | 0.3806 ns | 40.2566 ns | 0.0057 |      48 B |\n| 'Fully-used TimeSpan with milliseconds'                  | 40.4784 ns | 0.8199 ns | 0.8052 ns | 40.3464 ns | 0.0067 |      56 B |\n| 'Fully-used negative TimeSpan with milliseconds'         | 40.8930 ns | 0.4993 ns | 0.4670 ns | 40.7865 ns | 0.0067 |      56 B |\n| 'Fully-used negative TimeSpan with hundredths'           | 41.2768 ns | 0.6247 ns | 0.5843 ns | 41.3455 ns | 0.0067 |      56 B |\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigbang1112%2Ftm-essentials","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigbang1112%2Ftm-essentials","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigbang1112%2Ftm-essentials/lists"}