Skip to content

Commit

Permalink
Merge pull request #2393 from erri120/fix-events
Browse files Browse the repository at this point in the history
Fix URL encoding for events
  • Loading branch information
erri120 authored Jan 6, 2025
2 parents b681e15 + b08691f commit d6775ea
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
14 changes: 13 additions & 1 deletion src/NexusMods.Telemetry/EventDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Net;
using System.Text;
using JetBrains.Annotations;

namespace NexusMods.Telemetry;
Expand All @@ -8,4 +10,14 @@ namespace NexusMods.Telemetry;
/// <param name="Category">The event category</param>
/// <param name="Action">The event action</param>
[PublicAPI]
public record EventDefinition(string Category, string Action);
public record EventDefinition(string Category, string Action)
{
internal byte[] SafeCategory { get; } = Encode(Category);
internal byte[] SafeAction { get; } = Encode(Action);

private static byte[] Encode(string value)
{
var bytes = Encoding.UTF8.GetBytes(value);
return WebUtility.UrlEncodeToBytes(bytes, offset: 0, count: bytes.Length);
}
};
10 changes: 10 additions & 0 deletions src/NexusMods.Telemetry/EventMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics;
using System.Net;
using System.Text;
using JetBrains.Annotations;

namespace NexusMods.Telemetry;
Expand Down Expand Up @@ -41,4 +43,12 @@ public EventMetadata(string? name, TimeProvider? timeProvider = null)
/// Checks whether the struct wasn't default initialized.
/// </summary>
public bool IsValid() => Name is not null || CurrentTime != default(TimeOnly);

internal byte[] SafeName => Name is null ? [] : Encode(Name);

private static byte[] Encode(string value)
{
var bytes = Encoding.UTF8.GetBytes(value);
return WebUtility.UrlEncodeToBytes(bytes, offset: 0, count: bytes.Length);
}
}
21 changes: 18 additions & 3 deletions src/NexusMods.Telemetry/EventSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,29 @@ private static void SerializeEvent(IBufferWriter<byte> writer, ValueTuple<EventD
}

sb.Append("&e_c="); // Event category
sb.Append(definition.Category);
{
var input = definition.SafeCategory.AsSpan();
var destination = sb.GetSpan(sizeHint: input.Length);
input.CopyTo(destination);
sb.Advance(input.Length);
}

sb.Append("&e_a="); // Event action
sb.Append(definition.Action);
{
var input = definition.SafeAction.AsSpan();
var destination = sb.GetSpan(sizeHint: input.Length);
input.CopyTo(destination);
sb.Advance(input.Length);

}

if (metadata.Name is not null)
{
sb.Append("&e_n="); // Event name
sb.Append(metadata.Name);
var input = metadata.SafeName.AsSpan();
var destination = sb.GetSpan(sizeHint: input.Length);
input.CopyTo(destination);
sb.Advance(input.Length);
}

sb.Append("&h="); // The current hour (local time)
Expand Down
6 changes: 3 additions & 3 deletions tests/NexusMods.Telemetry.Tests/EventSenderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ public async Task Test()
using var stream = content!.ReadAsStream();
using var textReader = new StreamReader(stream, Encoding.UTF8);
var res = textReader.ReadToEnd();
ExpectJson("""{ "requests": ["?idsite=7&rec=1&apiv=1&send_image=0&ca=1&uid=1337&e_c=Game&e_a=Add Game&e_n=stardewvalley&h=0&m=0&s=0","?idsite=7&rec=1&apiv=1&send_image=0&ca=1&uid=1337&e_c=Loadout&e_a=Create Loadout&e_n=stardewvalley&h=0&m=0&s=1"] }""", res);
ExpectJson("""{ "requests": ["?idsite=7&rec=1&apiv=1&send_image=0&ca=1&uid=1337&e_c=Game&e_a=Add+Game&e_n=Mount+%26+Blade&h=0&m=0&s=0","?idsite=7&rec=1&apiv=1&send_image=0&ca=1&uid=1337&e_c=Loadout&e_a=Create+Loadout&e_n=Mount+%26+Blade&h=0&m=0&s=1"] }""", res);
});

var sender = new EventSender(loginManager, new HttpClient(messageHandler));

var timeProvider = new FakeTimeProvider();
sender.AddEvent(definition: Events.Game.AddGame, metadata: new EventMetadata(name: "stardewvalley", timeProvider: timeProvider));
sender.AddEvent(definition: Events.Game.AddGame, metadata: new EventMetadata(name: "Mount & Blade", timeProvider: timeProvider));

timeProvider.Advance(delta: TimeSpan.FromSeconds(1));
sender.AddEvent(definition: Events.Loadout.CreateLoadout, metadata: new EventMetadata(name: "stardewvalley", timeProvider: timeProvider));
sender.AddEvent(definition: Events.Loadout.CreateLoadout, metadata: new EventMetadata(name: "Mount & Blade", timeProvider: timeProvider));

await sender.Run();
}
Expand Down

0 comments on commit d6775ea

Please sign in to comment.