Bug fixes

This commit is contained in:
jheaps
2025-10-17 11:41:50 -06:00
parent 69e1e8450d
commit 93bdb3518a
5 changed files with 68 additions and 39 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ public class ChessController(
private static readonly ConcurrentDictionary<Guid, CancellationTokenSource> _gameRemovalCancellationTokens = []; private static readonly ConcurrentDictionary<Guid, CancellationTokenSource> _gameRemovalCancellationTokens = [];
private static readonly TimeSpan _computerGameTimeout = TimeSpan.FromHours(1); 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); private static readonly TimeSpan _gameCleanupTimeout = TimeSpan.FromMinutes(1);
/// <summary> /// <summary>
+1
View File
@@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>53ed685c-bdff-4306-8cc2-9fbe55c85713</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -8,31 +8,23 @@ public class AutoIpUpdateService(
ILogger<AutoIpUpdateService> log) ILogger<AutoIpUpdateService> log)
: BackgroundService : BackgroundService
{ {
private static readonly TimeSpan CheckInterval = TimeSpan.FromMinutes(5);
private static readonly HttpClient httpClient = new();
public static bool IsEnabled { get; private set; } = false; 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) protected override async Task ExecuteAsync(CancellationToken stop)
{ {
IsEnabled = true; IsEnabled = true;
var timer = new PeriodicTimer(CheckInterval); var timer = new PeriodicTimer(_checkInterval);
AAAARecord dnsRecord = await GetDnsRecordAsync();
string lastKnownIp = dnsRecord.Content;
while (await timer.WaitForNextTickAsync(stop)) while (await timer.WaitForNextTickAsync(stop))
{ {
try try
{ {
string currentIp = await GetPublicIpAsync() ?? ""; await UpdateIpAddressIfChanged();
if (lastKnownIp != currentIp)
{
await UpdateDnsIpAsync(config, dnsRecord, currentIp);
lastKnownIp = currentIp;
} }
} catch (OperationCanceledException) { break; }
catch (OperationCanceledException) { /* shutting down */ }
catch (Exception ex) catch (Exception ex)
{ {
log.LogError(ex, "Error while attempting ip update"); 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<string> GetPublicIpAsync() private static async Task<string> GetPublicIpAsync()
{ {
try try
{ {
return await httpClient.GetStringAsync(@"https://api.ipify.org/"); return await _httpClient.GetStringAsync(@"https://api.ipify.org/");
} }
catch catch
{ {
@@ -55,7 +69,7 @@ public class AutoIpUpdateService(
} }
} }
private async Task<AAAARecord> GetDnsRecordAsync() private async Task<RecordList> GetDnsRecordAsync()
{ {
try try
{ {
@@ -64,8 +78,8 @@ public class AutoIpUpdateService(
cfClient.DefaultRequestHeaders.Add("X-Auth-Key", config["cfKey"]); cfClient.DefaultRequestHeaders.Add("X-Auth-Key", config["cfKey"]);
var result = await cfClient.GetAsync(@$"https://api.cloudflare.com/client/v4/zones/{config["zoneId"]}/dns_records"); var result = await cfClient.GetAsync(@$"https://api.cloudflare.com/client/v4/zones/{config["zoneId"]}/dns_records");
Console.WriteLine(await result.Content.ReadAsStringAsync()); Console.WriteLine(await result.Content.ReadAsStringAsync());
var records = System.Text.Json.JsonSerializer.Deserialize<RecordList>(await result.Content.ReadAsStringAsync()); var records = JsonSerializer.Deserialize<RecordList>(await result.Content.ReadAsStringAsync());
return records!.Result[0]; return records!;
} }
catch 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(); HttpClient cfClient = new();
cfClient.DefaultRequestHeaders.Add("X-Auth-Email", config["cfEmail"]); cfClient.DefaultRequestHeaders.Add("X-Auth-Email", config["cfEmail"]);
cfClient.DefaultRequestHeaders.Add("X-Auth-Key", config["cfKey"]); 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, content = ip,
name = "@", proxied = record.Proxied,
proxied = true,
ttl = 3600,
type = "AAAA"
}; };
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) 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("comment")] string Comment,
[property: JsonPropertyName("content")] string Content, [property: JsonPropertyName("content")] string Content,
[property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("proxied")] bool Proxied,
[property: JsonPropertyName("id")] string Id); [property: JsonPropertyName("id")] string Id);
record RecordList([property: JsonPropertyName("result")] List<AAAARecord> Result); record RecordList([property: JsonPropertyName("result")] List<DnsRecord> Records)
{
public DnsRecord this[int index]
{
get
{
return Records[index];
}
}
}
} }
+1 -1
View File
@@ -3,5 +3,5 @@
element.style.display = "none"; // Trigger reflow element.style.display = "none"; // Trigger reflow
element.offsetHeight; // Force reflow element.offsetHeight; // Force reflow
element.style.display = ""; // Restore the original display 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?");
} }
+8 -7
View File
@@ -12,18 +12,19 @@
let intervalId; let intervalId;
let index = 0; let index = 0;
const punctuation = ['.', '!', '?']; const punctuation = ['.', '!', '?'];
const punctuationDict = {
'.': 150,
'!': 200,
'?': 200,
',': 100,
'`': 25,
};
let currentText = ""; let currentText = "";
function changeIntervalTime(element, text) { function changeIntervalTime(element, text) {
if (punctuation.includes(text.charAt(index))) {
clearInterval(intervalId); clearInterval(intervalId);
simulateTyping(element, text, 200); simulateTyping(element, text, punctuationDict[text.charAt(index)] ?? 50);
}
else {
clearInterval(intervalId);
simulateTyping(element, text);
}
} }
function simulateTyping(element, text, speed = 50) { function simulateTyping(element, text, speed = 50) {