diff --git a/JoshHeaps.Net/Controllers/ChessController.cs b/JoshHeaps.Net/Controllers/ChessController.cs index 157cdd7..1181008 100644 --- a/JoshHeaps.Net/Controllers/ChessController.cs +++ b/JoshHeaps.Net/Controllers/ChessController.cs @@ -22,7 +22,7 @@ public class ChessController( private static readonly ConcurrentDictionary _gameRemovalCancellationTokens = []; private static readonly TimeSpan _computerGameTimeout = TimeSpan.FromHours(1); - private static readonly TimeSpan _multiplayerGameTimeout = TimeSpan.FromSeconds(5); + private static readonly TimeSpan _multiplayerGameTimeout = TimeSpan.FromDays(1); private static readonly TimeSpan _gameCleanupTimeout = TimeSpan.FromMinutes(1); /// diff --git a/JoshHeaps.Net/JoshHeaps.Net.csproj b/JoshHeaps.Net/JoshHeaps.Net.csproj index 52e2186..51f7fd2 100644 --- a/JoshHeaps.Net/JoshHeaps.Net.csproj +++ b/JoshHeaps.Net/JoshHeaps.Net.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + 53ed685c-bdff-4306-8cc2-9fbe55c85713 diff --git a/JoshHeaps.Net/Services/Implementations/AutoIpUpdateService.cs b/JoshHeaps.Net/Services/Implementations/AutoIpUpdateService.cs index 81b2c8d..7630aed 100644 --- a/JoshHeaps.Net/Services/Implementations/AutoIpUpdateService.cs +++ b/JoshHeaps.Net/Services/Implementations/AutoIpUpdateService.cs @@ -8,31 +8,23 @@ public class AutoIpUpdateService( ILogger log) : BackgroundService { - private static readonly TimeSpan CheckInterval = TimeSpan.FromMinutes(5); - private static readonly HttpClient httpClient = new(); public static bool IsEnabled { get; private set; } = false; + private static readonly TimeSpan _checkInterval = TimeSpan.FromMinutes(1); + private static readonly HttpClient _httpClient = new(); + protected override async Task ExecuteAsync(CancellationToken stop) { IsEnabled = true; - var timer = new PeriodicTimer(CheckInterval); - AAAARecord dnsRecord = await GetDnsRecordAsync(); - string lastKnownIp = dnsRecord.Content; + var timer = new PeriodicTimer(_checkInterval); while (await timer.WaitForNextTickAsync(stop)) { try { - string currentIp = await GetPublicIpAsync() ?? ""; - - if (lastKnownIp != currentIp) - { - await UpdateDnsIpAsync(config, dnsRecord, currentIp); - - lastKnownIp = currentIp; - } + await UpdateIpAddressIfChanged(); } - catch (OperationCanceledException) { /* shutting down */ } + catch (OperationCanceledException) { break; } catch (Exception ex) { log.LogError(ex, "Error while attempting ip update"); @@ -40,11 +32,33 @@ public class AutoIpUpdateService( } } + private async Task UpdateIpAddressIfChanged() + { + var dnsRecords = await GetDnsRecordAsync(); + string dnsRecordIp = dnsRecords[0].Content; + + if (!dnsRecords.Records.All(x => x.Content == dnsRecords[0].Content)) + dnsRecordIp = string.Empty; + + string publicIp = await GetPublicIpAsync() ?? string.Empty; + + if (string.IsNullOrWhiteSpace(publicIp) || dnsRecordIp == publicIp) + return; + + foreach (var dnsRecord in dnsRecords.Records) + { + if (dnsRecord.Content == publicIp) + continue; + + await UpdateDnsIpAsync(config, dnsRecord, publicIp); + } + } + private static async Task GetPublicIpAsync() { try { - return await httpClient.GetStringAsync(@"https://api.ipify.org/"); + return await _httpClient.GetStringAsync(@"https://api.ipify.org/"); } catch { @@ -55,7 +69,7 @@ public class AutoIpUpdateService( } } - private async Task GetDnsRecordAsync() + private async Task GetDnsRecordAsync() { try { @@ -64,8 +78,8 @@ public class AutoIpUpdateService( cfClient.DefaultRequestHeaders.Add("X-Auth-Key", config["cfKey"]); var result = await cfClient.GetAsync(@$"https://api.cloudflare.com/client/v4/zones/{config["zoneId"]}/dns_records"); Console.WriteLine(await result.Content.ReadAsStringAsync()); - var records = System.Text.Json.JsonSerializer.Deserialize(await result.Content.ReadAsStringAsync()); - return records!.Result[0]; + var records = JsonSerializer.Deserialize(await result.Content.ReadAsStringAsync()); + return records!; } catch { @@ -76,22 +90,23 @@ public class AutoIpUpdateService( } } - private static async Task UpdateDnsIpAsync(IConfiguration config, AAAARecord record, string ip) + private static async Task UpdateDnsIpAsync(IConfiguration config, DnsRecord record, string ip) { HttpClient cfClient = new(); cfClient.DefaultRequestHeaders.Add("X-Auth-Email", config["cfEmail"]); cfClient.DefaultRequestHeaders.Add("X-Auth-Key", config["cfKey"]); - object content = new + + object updateRequestBody = new { - comment = "Update as needed", + name = record.Name, + ttl = record.Ttl, + type = record.Type, + comment = record.Comment, content = ip, - name = "@", - proxied = true, - ttl = 3600, - type = "AAAA" + proxied = record.Proxied, }; - var result = await cfClient.PutAsJsonAsync(@$"https://api.cloudflare.com/client/v4/zones/{config["zoneId"]}/dns_records{record.Id}", content); + var result = await cfClient.PatchAsJsonAsync(@$"https://api.cloudflare.com/client/v4/zones/{config["zoneId"]}/dns_records/{record.Id}", updateRequestBody); if (!result.IsSuccessStatusCode) { @@ -102,11 +117,23 @@ public class AutoIpUpdateService( } } - record AAAARecord( + record DnsRecord( + [property: JsonPropertyName("name")] string Name, + [property: JsonPropertyName("ttl")] int Ttl, + [property: JsonPropertyName("type")] string Type, [property: JsonPropertyName("comment")] string Comment, [property: JsonPropertyName("content")] string Content, - [property: JsonPropertyName("name")] string Name, + [property: JsonPropertyName("proxied")] bool Proxied, [property: JsonPropertyName("id")] string Id); - record RecordList([property: JsonPropertyName("result")] List Result); + record RecordList([property: JsonPropertyName("result")] List Records) + { + public DnsRecord this[int index] + { + get + { + return Records[index]; + } + } + } } diff --git a/JoshHeaps.Net/wwwroot/js/site.js b/JoshHeaps.Net/wwwroot/js/site.js index 398b0be..9ca0115 100644 --- a/JoshHeaps.Net/wwwroot/js/site.js +++ b/JoshHeaps.Net/wwwroot/js/site.js @@ -3,5 +3,5 @@ element.style.display = "none"; // Trigger reflow element.offsetHeight; // Force reflow element.style.display = ""; // Restore the original display - typeText("#WelcomeMessage", "Hey, you found me...!?``````````````````````No that's stupid````````````````Just````uhhhh`````Hello! My name is Josh. I'm a software engineer, and I try to have a lot of fun with what I do. While I have your attention, why don't I tell you more about myself?"); + typeText("#WelcomeMessage", "Hey, you found me...!?``````````````````````No that's stupid...```````````````````Just...```````uhhhh...````````Hello! My name is Josh. I'm a software engineer, and I try to have a lot of fun with what I do. While I have your attention, why don't I tell you more about myself?"); } \ No newline at end of file diff --git a/JoshHeaps.Net/wwwroot/js/utils.js b/JoshHeaps.Net/wwwroot/js/utils.js index fb14302..2479ff1 100644 --- a/JoshHeaps.Net/wwwroot/js/utils.js +++ b/JoshHeaps.Net/wwwroot/js/utils.js @@ -12,18 +12,19 @@ let intervalId; let index = 0; const punctuation = ['.', '!', '?']; +const punctuationDict = { + '.': 150, + '!': 200, + '?': 200, + ',': 100, + '`': 25, +}; let currentText = ""; function changeIntervalTime(element, text) { - if (punctuation.includes(text.charAt(index))) { - clearInterval(intervalId); - simulateTyping(element, text, 200); - } - else { - clearInterval(intervalId); - simulateTyping(element, text); - } + clearInterval(intervalId); + simulateTyping(element, text, punctuationDict[text.charAt(index)] ?? 50); } function simulateTyping(element, text, speed = 50) {