diff --git a/.editorconfig b/.editorconfig index e3bb3eb..a028add 100644 --- a/.editorconfig +++ b/.editorconfig @@ -175,7 +175,7 @@ csharp_style_prefer_index_operator = false:silent csharp_style_prefer_range_operator = false:silent csharp_style_prefer_switch_expression = false:none -csharp_style_namespace_declarations = block_scoped:warning +csharp_style_namespace_declarations = file_scoped:warning #Style - C# 12 features csharp_style_prefer_primary_constructors = false diff --git a/.github/godot_version.txt b/.github/godot_version.txt new file mode 100644 index 0000000..f4fa8fc --- /dev/null +++ b/.github/godot_version.txt @@ -0,0 +1 @@ +4.6.1 \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1dabb0a..df16e71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,17 +2,68 @@ name: CI on: pull_request: - types: [opened, reopened] + types: + - opened workflow_dispatch: jobs: - dotnet-format: + godot-project-check: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Verify xllint + shell: bash + run: | + command -v xmllint >/dev/null 2>&1 || { + sudo apt-get update + sudo apt-get install -y --no-install-recommends libxml2-utils + } + + - name: Verify project + shell: bash + env: + CSPROJ_PATH: "Rhythia.csproj" + VERSION_FILE: ".github/godot_version.txt" + run: | + if compgen -G "${CSPROJ_PATH}.old*" > /dev/null; then + echo "::error file=${CSPROJ_PATH}.old::${CSPROJ_PATH}.old migration exists" + exit 1 + fi + + if [ ! -f "$CSPROJ_PATH" ]; then + echo "::error::$CSPROJ_PATH not found" + exit 1 + fi + + if [ ! -f "$VERSION_FILE" ]; then + echo "::error::$VERSION_FILE not found" + exit 1 + fi + + EXPECTED_VERSION=$(tr -d '[:space:]' < "$VERSION_FILE") + EXPECTED_SDK="Godot.NET.Sdk/${EXPECTED_VERSION}" + ACTUAL_SDK=$(xmllint --xpath 'string(/Project/@Sdk)' "$CSPROJ_PATH") + + if [ -z "$ACTUAL_SDK" ]; then + echo "::error file=$CSPROJ_PATH::no attribute found" + exit 1 + fi + + if [ "$ACTUAL_SDK" != "$EXPECTED_SDK" ]; then + echo "::error file=$CSPROJ_PATH::expected Sdk=\"$EXPECTED_SDK\" but found Sdk=\"$ACTUAL_SDK\"" + exit 1 + fi + + echo "Godot SDK OK: $ACTUAL_SDK" + + dotnet-format: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # Checkout v4 - name: Setup - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # Dotnet 4.0.2 with: dotnet-version: 10.0.x diff --git a/.gitignore b/.gitignore index 627caa6..89c55c6 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ export_presets.cfg *.translation # Mono-specific ignores +*.csproj.user .mono/ data_*/ mono_crash.*.json diff --git a/Rhythia.csproj.old b/Rhythia.csproj.old deleted file mode 100644 index 22d143c..0000000 --- a/Rhythia.csproj.old +++ /dev/null @@ -1,18 +0,0 @@ - - - net10.0 - net10.0 - true - preview - - - - - - - - - 5.0.21 - - - \ No newline at end of file diff --git a/Rhythia.csproj.old.1 b/Rhythia.csproj.old.1 deleted file mode 100644 index 2f5f48d..0000000 --- a/Rhythia.csproj.old.1 +++ /dev/null @@ -1,18 +0,0 @@ - - - net10.0 - net10.0 - true - preview - - - - - - - - - 5.0.21 - - - \ No newline at end of file diff --git a/Rhythia.csproj.user b/Rhythia.csproj.user deleted file mode 100644 index cf2629f..0000000 --- a/Rhythia.csproj.user +++ /dev/null @@ -1,9 +0,0 @@ - - - - ProjectDebugger - - - Pheonyx Debug - - \ No newline at end of file diff --git a/scripts/game/LegacyRenderer.cs b/scripts/game/LegacyRenderer.cs index 1298738..e39c339 100644 --- a/scripts/game/LegacyRenderer.cs +++ b/scripts/game/LegacyRenderer.cs @@ -35,7 +35,7 @@ public override void _Process(double delta) } noteOpacity = Math.Clamp(noteOpacity, 0, 1); - + float noteSize = (float)(LegacyRunner.CurrentAttempt.IsReplay ? LegacyRunner.CurrentAttempt.Replays[0].NoteSize : settings.NoteSize.Value) / 4; Transform3D transform = new(Vector3.Right * noteSize, Vector3.Up * noteSize, Vector3.Back * noteSize, Vector3.Zero); diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index e925338..e37beb6 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -113,10 +113,10 @@ public static void Delete(Map map) Maps.RemoveAll(x => x.Id == map.Id); - Callable.From(() => - { - _ = ToastNotification.Notify($"Deleted {map.PrettyTitle}!"); - }).CallDeferred(); + Callable.From(() => + { + _ = ToastNotification.Notify($"Deleted {map.PrettyTitle}!"); + }).CallDeferred(); Callable.From(() => MapDeleted?.Invoke(map)).CallDeferred(); } catch (Exception e) diff --git a/scripts/scenes/LegacyRunner.cs b/scripts/scenes/LegacyRunner.cs index 6b2f682..cfc28c1 100644 --- a/scripts/scenes/LegacyRunner.cs +++ b/scripts/scenes/LegacyRunner.cs @@ -930,7 +930,7 @@ public override void _Process(double delta) else { double audioDelay = CurrentAttempt.Progress - 1000 * (SoundManager.Song.GetPlaybackPosition() + AudioServer.GetTimeSinceLastMix()); - + if (Math.Abs(audioDelay) > 25 && CurrentAttempt.Progress > 0) { SoundManager.Song.PitchScale = Math.Max(Mathf.Epsilon, (float)CurrentAttempt.Speed + (float)audioDelay / 1000); @@ -1041,7 +1041,7 @@ public override void _Process(double delta) CurrentAttempt.Skippable = false; startGameplayMediaAtExpected(isPauseRampActive() ? SoundManager.Song.VolumeDb : getTargetMusicVolumeDb()); - + int nextNoteMillisecond = CurrentAttempt.PassedNotes >= CurrentAttempt.Map.Notes.Length ? (int)MapLength + 5000 : CurrentAttempt.Map.Notes[CurrentAttempt.PassedNotes].Millisecond; int lastNoteMillisecond = CurrentAttempt.PassedNotes > 0 ? CurrentAttempt.Map.Notes[CurrentAttempt.PassedNotes - 1].Millisecond : 0; @@ -1638,7 +1638,7 @@ private static void updatePauseStateEachFrame(double delta) pauseHoldTime += (float)delta; pauseState = Math.Max(0, pauseState - (float)(delta / pauseHoldDuration)); pauseHudControl.SetProgress(Math.Clamp(1f - pauseState, 0f, 1f)); - + if (CurrentAttempt.Map.AudioBuffer != null && musicStarted && SoundManager.Song.Playing) { SoundManager.Song.VolumeDb = Mathf.Lerp(getTargetMusicVolumeDb() - 60, getTargetMusicVolumeDb(), 1 - pauseState); diff --git a/scripts/scenes/PauseHud.cs b/scripts/scenes/PauseHud.cs index 66f498a..503bd85 100644 --- a/scripts/scenes/PauseHud.cs +++ b/scripts/scenes/PauseHud.cs @@ -2,24 +2,24 @@ public partial class PauseHud : Control { - private Control progressMask; + private Control progressMask; - public override void _Ready() - { - progressMask = GetNode("ProgressMask"); - SetProgress(0); - } + public override void _Ready() + { + progressMask = GetNode("ProgressMask"); + SetProgress(0); + } - public void SetProgress(float percent) - { - if (progressMask == null) - { - return; - } + public void SetProgress(float percent) + { + if (progressMask == null) + { + return; + } - float clamped = Mathf.Clamp(percent, 0f, 1f); - float width = 320f * clamped; - progressMask.OffsetRight = width / 2; - progressMask.OffsetLeft = -width / 2; - } -} \ No newline at end of file + float clamped = Mathf.Clamp(percent, 0f, 1f); + float width = 320f * clamped; + progressMask.OffsetRight = width / 2; + progressMask.OffsetLeft = -width / 2; + } +} diff --git a/scripts/spaces/Galaxy.cs b/scripts/spaces/Galaxy.cs index 900a09e..14750d1 100644 --- a/scripts/spaces/Galaxy.cs +++ b/scripts/spaces/Galaxy.cs @@ -4,39 +4,39 @@ namespace Spaces; public partial class Galaxy : BaseSpace { - private SettingsProfile settings; - private Environment environment; - // private Node3D planet; - // private Vector3 planetStartPos; - private StandardMaterial3D tileMaterial; - private Color fogReset = new(0, 0, 0); - - public override void _Ready() - { - base._Ready(); - - settings = SettingsManager.Instance.Settings; - environment = WorldEnvironment.Environment; - tileMaterial = (GetNode("Road").Mesh as PlaneMesh).Material as StandardMaterial3D; - - // planet = GetNode("Planet"); - // planetStartPos = planet.Position; - } - - public override void _Process(double delta) - { - base._Process(delta); - - // sky rotation - environment.SkyRotation += (Vector3.Down + Vector3.Right) * (float)delta / 100; - - // tile movement - tileMaterial.Uv1Offset += Vector3.Up * (float)delta / 2; - - // planet floating - //planet.Position = planetStartPos + Vector3.Up * (float)Math.Sin(Time.GetTicksMsec() / 1000f ); - - // fog - environment.FogLightColor = settings.SpaceHitEffects ? NoteHitColor : fogReset; - } + private SettingsProfile settings; + private Environment environment; + // private Node3D planet; + // private Vector3 planetStartPos; + private StandardMaterial3D tileMaterial; + private Color fogReset = new(0, 0, 0); + + public override void _Ready() + { + base._Ready(); + + settings = SettingsManager.Instance.Settings; + environment = WorldEnvironment.Environment; + tileMaterial = (GetNode("Road").Mesh as PlaneMesh).Material as StandardMaterial3D; + + // planet = GetNode("Planet"); + // planetStartPos = planet.Position; + } + + public override void _Process(double delta) + { + base._Process(delta); + + // sky rotation + environment.SkyRotation += (Vector3.Down + Vector3.Right) * (float)delta / 100; + + // tile movement + tileMaterial.Uv1Offset += Vector3.Up * (float)delta / 2; + + // planet floating + //planet.Position = planetStartPos + Vector3.Up * (float)Math.Sin(Time.GetTicksMsec() / 1000f ); + + // fog + environment.FogLightColor = settings.SpaceHitEffects ? NoteHitColor : fogReset; + } } diff --git a/scripts/spaces/Grid.cs b/scripts/spaces/Grid.cs index e2ed600..be0b2b4 100644 --- a/scripts/spaces/Grid.cs +++ b/scripts/spaces/Grid.cs @@ -20,4 +20,4 @@ public override void _Process(double delta) tileMaterial.AlbedoColor = NoteHitColor; tileMaterial.Uv1Offset += Vector3.Up * (float)delta * 3; } -} \ No newline at end of file +} diff --git a/scripts/spaces/Squircles.cs b/scripts/spaces/Squircles.cs index f4a7dc9..13c25c4 100644 --- a/scripts/spaces/Squircles.cs +++ b/scripts/spaces/Squircles.cs @@ -87,4 +87,4 @@ private void updateColor(Color color) particlesNear.Color = color.Lightened(0.1f); particlesFar.Color = particlesNear.Color; } -} \ No newline at end of file +} diff --git a/scripts/spaces/Waves.cs b/scripts/spaces/Waves.cs index a6d9117..9774d54 100644 --- a/scripts/spaces/Waves.cs +++ b/scripts/spaces/Waves.cs @@ -76,4 +76,4 @@ public override void UpdateState(bool playing) skyMaterial.SetShaderParameter("image_lerp", 0.0); } } -} \ No newline at end of file +} diff --git a/scripts/ui/SettingsMenu.cs b/scripts/ui/SettingsMenu.cs index 1d69e05..b681896 100644 --- a/scripts/ui/SettingsMenu.cs +++ b/scripts/ui/SettingsMenu.cs @@ -254,12 +254,12 @@ private void updateProfileSelection() string current = SettingsManager.GetCurrentProfile(); string[] profiles = Directory.GetFiles($"{Constants.USER_FOLDER}/profiles"); - + // add custom profiles to item list for (int i = 0; i < profiles.Length; i++) { string name = profiles[i].GetFile().GetBaseName(); - + if (name != "default") { profilesButton.AddItem(name); @@ -338,7 +338,7 @@ private void updateSlider(HSlider slider, LineEdit lineEdit, double value) { lineEdit.ReleaseFocus(); } - + slider.SetValueNoSignal(value); } diff --git a/scripts/util/Audio.cs b/scripts/util/Audio.cs index 80848af..96bb84d 100644 --- a/scripts/util/Audio.cs +++ b/scripts/util/Audio.cs @@ -1,55 +1,54 @@ using System.Text; using Godot; -namespace Util +namespace Util; + +public class Audio { - public class Audio + public static AudioStream LoadStream(byte[] buffer) { - public static AudioStream LoadStream(byte[] buffer) + AudioStream stream; + + if (buffer == null || buffer.Length < 4) { - AudioStream stream; + FileAccess file = FileAccess.Open("res://sounds/quiet.mp3", FileAccess.ModeFlags.Read); + byte[] quietBuffer = file.GetBuffer((long)file.GetLength()); - if (buffer == null || buffer.Length < 4) - { - FileAccess file = FileAccess.Open("res://sounds/quiet.mp3", FileAccess.ModeFlags.Read); - byte[] quietBuffer = file.GetBuffer((long)file.GetLength()); + file.Close(); - file.Close(); + return new AudioStreamMP3() { Data = quietBuffer }; + } - return new AudioStreamMP3() { Data = quietBuffer }; - } + if (Encoding.UTF8.GetString(buffer[0..4]) == "OggS") + { + stream = AudioStreamOggVorbis.LoadFromBuffer(buffer); + } + else + { + stream = new AudioStreamMP3() { Data = buffer }; + } - if (Encoding.UTF8.GetString(buffer[0..4]) == "OggS") - { - stream = AudioStreamOggVorbis.LoadFromBuffer(buffer); - } - else - { - stream = new AudioStreamMP3() { Data = buffer }; - } + return stream; + } - return stream; - } + public static AudioStream LoadFromFile(string path) + { + AudioStream stream; - public static AudioStream LoadFromFile(string path) + if (!System.IO.File.Exists(path)) { - AudioStream stream; - - if (!System.IO.File.Exists(path)) - { - AudioStreamMP3.LoadFromFile("res://sounds/quiet.mp3"); - } + AudioStreamMP3.LoadFromFile("res://sounds/quiet.mp3"); + } - string ext = System.IO.Path.GetExtension(path); + string ext = System.IO.Path.GetExtension(path); - stream = ext.ToLower() switch - { - ".mp3" => AudioStreamMP3.LoadFromFile(path), - ".ogg" => AudioStreamOggVorbis.LoadFromFile(path), - _ => AudioStreamMP3.LoadFromFile("res://sounds/quiet.mp3"), - }; + stream = ext.ToLower() switch + { + ".mp3" => AudioStreamMP3.LoadFromFile(path), + ".ogg" => AudioStreamOggVorbis.LoadFromFile(path), + _ => AudioStreamMP3.LoadFromFile("res://sounds/quiet.mp3"), + }; - return stream; - } + return stream; } } diff --git a/scripts/util/FileParser.cs b/scripts/util/FileParser.cs index ec896a4..554163b 100644 --- a/scripts/util/FileParser.cs +++ b/scripts/util/FileParser.cs @@ -34,7 +34,7 @@ public FileParser(byte[] buffer) Pointer = 0; } - private void CheckBounds(int amount) + private void checkBounds(int amount) { if (Pointer + amount > Length) { @@ -44,7 +44,7 @@ private void CheckBounds(int amount) public byte[] Get(int length) { - CheckBounds(length); + checkBounds(length); Pointer += length; return Buffer[(Pointer - length)..Pointer]; } @@ -85,21 +85,21 @@ public string GetLine() public bool GetBool() { - CheckBounds(1); + checkBounds(1); Pointer += 1; return BitConverter.ToBoolean(Buffer, Pointer - 1); } public float GetFloat() { - CheckBounds(4); + checkBounds(4); Pointer += 4; return BitConverter.ToSingle(Buffer, Pointer - 4); } public double GetDouble() { - CheckBounds(8); + checkBounds(8); Pointer += 8; return BitConverter.ToDouble(Buffer, Pointer - 8); } @@ -111,21 +111,21 @@ public ushort GetUInt8() public ushort GetUInt16() { - CheckBounds(2); + checkBounds(2); Pointer += 2; return BitConverter.ToUInt16(Buffer, Pointer - 2); } public uint GetUInt32() { - CheckBounds(4); + checkBounds(4); Pointer += 4; return BitConverter.ToUInt32(Buffer, Pointer - 4); } public ulong GetUInt64() { - CheckBounds(8); + checkBounds(8); Pointer += 8; return BitConverter.ToUInt64(Buffer, Pointer - 8); } diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index d6789dd..bfa0a9f 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -4,121 +4,120 @@ using System.IO; using Godot; -namespace Util +namespace Util; + +public class Misc { - public class Misc + public static GodotObject OBJParser = (GodotObject)GD.Load("res://scripts/util/OBJParser.gd").New(); + + public static ImageTexture GetModIcon(string mod) { - public static GodotObject OBJParser = (GodotObject)GD.Load("res://scripts/util/OBJParser.gd").New(); + ImageTexture tex; + + switch (mod) + { + case "NoFail": + tex = SkinManager.Instance.Skin.ModNoFailImage; + break; + case "Ghost": + tex = SkinManager.Instance.Skin.ModGhostImage; + break; + default: + tex = new(); + break; + } + + return tex; + } - public static ImageTexture GetModIcon(string mod) + public static void CopyProperties(Node node, Node reference) + { + foreach (Godot.Collections.Dictionary property in reference.GetPropertyList()) { - ImageTexture tex; + string key = (string)property["name"]; - switch (mod) + if (key == "size" || key == "script") { - case "NoFail": - tex = SkinManager.Instance.Skin.ModNoFailImage; - break; - case "Ghost": - tex = SkinManager.Instance.Skin.ModGhostImage; - break; - default: - tex = new(); - break; + continue; } - return tex; + node.Set(key, reference.Get(key)); } + } - public static void CopyProperties(Node node, Node reference) - { - foreach (Godot.Collections.Dictionary property in reference.GetPropertyList()) - { - string key = (string)property["name"]; + public static void CopyReference(Node node, Node reference) + { + Util.Misc.CopyProperties(node, reference); - if (key == "size" || key == "script") - { - continue; - } + reference.ReplaceBy(node); + reference.QueueFree(); + } - node.Set(key, reference.Get(key)); - } + public static Image LoadImageFromBuffer(byte[] buffer) + { + if (buffer == null || buffer.Length < 4) + { + return null; } - public static void CopyReference(Node node, Node reference) - { - Util.Misc.CopyProperties(node, reference); + Image img = new Image(); - reference.ReplaceBy(node); - reference.QueueFree(); + bool isPng = buffer[0] == 137 && buffer[1] == 80 && buffer[2] == 78 && buffer[3] == 71; + if (isPng && img.LoadPngFromBuffer(buffer) == Error.Ok) + { + return img; } - public static Image LoadImageFromBuffer(byte[] buffer) + bool isJpeg = buffer.Length >= 3 && buffer[0] == 0xFF && buffer[1] == 0xD8 && buffer[2] == 0xFF; + if (isJpeg && img.LoadJpgFromBuffer(buffer) == Error.Ok) { - if (buffer == null || buffer.Length < 4) - { - return null; - } - - Image img = new Image(); - - bool isPng = buffer[0] == 137 && buffer[1] == 80 && buffer[2] == 78 && buffer[3] == 71; - if (isPng && img.LoadPngFromBuffer(buffer) == Error.Ok) - { - return img; - } + return img; + } - bool isJpeg = buffer.Length >= 3 && buffer[0] == 0xFF && buffer[1] == 0xD8 && buffer[2] == 0xFF; - if (isJpeg && img.LoadJpgFromBuffer(buffer) == Error.Ok) - { - return img; - } + bool isBmp = buffer.Length >= 2 && buffer[0] == 0x42 && buffer[1] == 0x4D; + if (isBmp && img.LoadBmpFromBuffer(buffer) == Error.Ok) + { + return img; + } - bool isBmp = buffer.Length >= 2 && buffer[0] == 0x42 && buffer[1] == 0x4D; - if (isBmp && img.LoadBmpFromBuffer(buffer) == Error.Ok) - { - return img; - } + bool isWebp = buffer.Length >= 12 + && buffer[0] == 0x52 && buffer[1] == 0x49 && buffer[2] == 0x46 && buffer[3] == 0x46 + && buffer[8] == 0x57 && buffer[9] == 0x45 && buffer[10] == 0x42 && buffer[11] == 0x50; + if (isWebp && img.LoadWebpFromBuffer(buffer) == Error.Ok) + { + return img; + } - bool isWebp = buffer.Length >= 12 - && buffer[0] == 0x52 && buffer[1] == 0x49 && buffer[2] == 0x46 && buffer[3] == 0x46 - && buffer[8] == 0x57 && buffer[9] == 0x45 && buffer[10] == 0x42 && buffer[11] == 0x50; - if (isWebp && img.LoadWebpFromBuffer(buffer) == Error.Ok) - { - return img; - } + return null; + } - return null; - } + public static Color ParseColor(string hex, Color fallback) + { + if (string.IsNullOrWhiteSpace(hex)) { return fallback; } - public static Color ParseColor(string hex, Color fallback) + try { - if (string.IsNullOrWhiteSpace(hex)) { return fallback; } - - try - { - hex = hex.Trim(); - if (!hex.StartsWith('#')) { hex = "#" + hex; } - return Color.FromHtml(hex); - } - catch - { - Logger.Log($"Invalid color: {hex} (reset to default value)"); - return fallback; - } + hex = hex.Trim(); + if (!hex.StartsWith('#')) { hex = "#" + hex; } + return Color.FromHtml(hex); } - - public static float ParseFloatInput(string input, float fallback = 0f) + catch { - if (string.IsNullOrWhiteSpace(input)) { return fallback; } + Logger.Log($"Invalid color: {hex} (reset to default value)"); + return fallback; + } + } - string normalized = input.Replace(',', '.'); - if (float.TryParse(normalized, NumberStyles.Any, CultureInfo.InvariantCulture, out float result)) - { - return result; - } + public static float ParseFloatInput(string input, float fallback = 0f) + { + if (string.IsNullOrWhiteSpace(input)) { return fallback; } - return fallback; + string normalized = input.Replace(',', '.'); + if (float.TryParse(normalized, NumberStyles.Any, CultureInfo.InvariantCulture, out float result)) + { + return result; } + + return fallback; } } diff --git a/scripts/util/Networking.cs b/scripts/util/Networking.cs index 27f859d..e51f149 100644 --- a/scripts/util/Networking.cs +++ b/scripts/util/Networking.cs @@ -1,38 +1,37 @@ using System; using Godot; -namespace Util +namespace Util; + +public static class Networking { - public static class Networking - { - public static string DefaultIP = "127.0.0.1"; - public static int DefaultPort = 44220; + public static string DefaultIP = "127.0.0.1"; + public static int DefaultPort = 44220; - public static string ValidateIP(string ip) + public static string ValidateIP(string ip) + { + if (ip != "") { - if (ip != "") - { - return ip; - } - - return DefaultIP; + return ip; } - public static int ValidatePort(string port) + return DefaultIP; + } + + public static int ValidatePort(string port) + { + try { - try - { - if (port != "") - { - return Math.Clamp(port.ToInt(), 0, 65535); - } - } - catch + if (port != "") { - ToastNotification.Notify($"Could not set port, defaulting to {DefaultPort}", 1); + return Math.Clamp(port.ToInt(), 0, 65535); } - - return DefaultPort; } + catch + { + ToastNotification.Notify($"Could not set port, defaulting to {DefaultPort}", 1); + } + + return DefaultPort; } } diff --git a/scripts/util/String.cs b/scripts/util/String.cs index e0bf194..09ebf00 100644 --- a/scripts/util/String.cs +++ b/scripts/util/String.cs @@ -1,75 +1,74 @@ using System; using Godot; -namespace Util +namespace Util; + +public class String { - public class String + public static string FormatTime(double seconds, bool padMinutes = false) { - public static string FormatTime(double seconds, bool padMinutes = false) - { - int minutes = (int)Mathf.Floor(seconds / (seconds > 0 ? 60 : -60)); + int minutes = (int)Mathf.Floor(seconds / (seconds > 0 ? 60 : -60)); - seconds -= minutes * 60; - seconds = Math.Floor(seconds); + seconds -= minutes * 60; + seconds = Math.Floor(seconds); - return $"{(seconds < 0 ? "-" : "")}{(padMinutes ? minutes.ToString().PadZeros(2) : minutes)}:{Math.Abs(seconds).ToString().PadZeros(2)}"; - } - - public static string FormatUnixTimePretty(double now, double time) - { - string formatted; - double seconds, minutes, hours, days; - double difference = now - time; - string prefix = difference < 0 ? "in " : ""; - string suffix = difference > 0 ? " ago" : ""; + return $"{(seconds < 0 ? "-" : "")}{(padMinutes ? minutes.ToString().PadZeros(2) : minutes)}:{Math.Abs(seconds).ToString().PadZeros(2)}"; + } - seconds = Math.Floor(difference); - minutes = Math.Floor(seconds / 60); - hours = Math.Floor(minutes / 60); - days = Math.Floor(hours / 24); + public static string FormatUnixTimePretty(double now, double time) + { + string formatted; + double seconds, minutes, hours, days; + double difference = now - time; + string prefix = difference < 0 ? "in " : ""; + string suffix = difference > 0 ? " ago" : ""; - if (days > 0) - { - formatted = $"{PadMagnitude(days.ToString())} day" + (days > 1 ? "s" : ""); - } - else if (hours > 0) - { - formatted = $"{PadMagnitude(hours.ToString())} hour" + (hours > 1 ? "s" : ""); - } - else if (minutes > 0) - { - formatted = $"{PadMagnitude(minutes.ToString())} minute" + (minutes > 1 ? "s" : ""); - } - else if (seconds > 0) - { - formatted = $"{PadMagnitude(seconds.ToString())} second" + (seconds > 1 ? "s" : ""); - } - else - { - formatted = "just now"; - } + seconds = Math.Floor(difference); + minutes = Math.Floor(seconds / 60); + hours = Math.Floor(minutes / 60); + days = Math.Floor(hours / 24); - return $"{prefix}{formatted}{suffix}"; + if (days > 0) + { + formatted = $"{PadMagnitude(days.ToString())} day" + (days > 1 ? "s" : ""); + } + else if (hours > 0) + { + formatted = $"{PadMagnitude(hours.ToString())} hour" + (hours > 1 ? "s" : ""); + } + else if (minutes > 0) + { + formatted = $"{PadMagnitude(minutes.ToString())} minute" + (minutes > 1 ? "s" : ""); + } + else if (seconds > 0) + { + formatted = $"{PadMagnitude(seconds.ToString())} second" + (seconds > 1 ? "s" : ""); + } + else + { + formatted = "just now"; } - public static string PadMagnitude(string str, string pad = ",") + return $"{prefix}{formatted}{suffix}"; + } + + public static string PadMagnitude(string str, string pad = ",") + { + string formatted = ""; + string[] split = str.Split("."); + string whole = split[0]; + string decimals = split.Length > 1 ? "." + split[1] : ""; + + for (int i = 0; i < whole.Length; i++) { - string formatted = ""; - string[] split = str.Split("."); - string whole = split[0]; - string decimals = split.Length > 1 ? "." + split[1] : ""; + formatted += whole[i]; - for (int i = 0; i < whole.Length; i++) + if ((whole.Length - i - 1) % 3 == 0) { - formatted += whole[i]; - - if ((whole.Length - i - 1) % 3 == 0) - { - formatted += pad; - } + formatted += pad; } - - return formatted.TrimSuffix(pad) + decimals; } + + return formatted.TrimSuffix(pad) + decimals; } }