fix(admin): parse mission_change_time as wire datetime string
Real /load/index captures ship mission_meta.mission_change_time as a "yyyy-MM-dd HH:mm:ss" string (see FriendService.DefaultMissionChangeTime for the canonical game format) but ImportViewerRequest typed it as long? Unix seconds. The FromUnixTimeSeconds branch had never been reachable with a real capture, and any loader dump carrying mission_meta 400d the whole request. Change the DTO field to string? and parse in the controller with DateTime.TryParseExact + invariant culture (AssumeUniversal | AdjustToUniversal); unparseable values skip cleanly instead of poisoning the whole viewer import. Also fix is_received_two_pick_mission: DTO's JsonPropertyName was has_received_pick_two_mission (never matched the wire key), and the wire ships "1" /"0" strings not booleans. Rename to the actual wire key, retype to int?, controller normalizes `hrptm != 0` before assigning to the bool DB property. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -267,11 +267,17 @@ public class AdminController : SVSimController
|
|||||||
{
|
{
|
||||||
viewer.MissionData ??= new ViewerMissionData();
|
viewer.MissionData ??= new ViewerMissionData();
|
||||||
if (meta.HasReceivedPickTwoMission is { } hrptm)
|
if (meta.HasReceivedPickTwoMission is { } hrptm)
|
||||||
viewer.MissionData.HasReceivedPickTwoMission = hrptm;
|
viewer.MissionData.HasReceivedPickTwoMission = hrptm != 0;
|
||||||
if (meta.MissionReceiveType is { } mrt)
|
if (meta.MissionReceiveType is { } mrt)
|
||||||
viewer.MissionData.MissionReceiveType = mrt;
|
viewer.MissionData.MissionReceiveType = mrt;
|
||||||
if (meta.MissionChangeTime is { } mct)
|
if (meta.MissionChangeTime is { } mct
|
||||||
viewer.MissionData.MissionChangeTime = DateTimeOffset.FromUnixTimeSeconds(mct).UtcDateTime;
|
&& DateTime.TryParseExact(mct, "yyyy-MM-dd HH:mm:ss",
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture,
|
||||||
|
System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AdjustToUniversal,
|
||||||
|
out var mctParsed))
|
||||||
|
{
|
||||||
|
viewer.MissionData.MissionChangeTime = mctParsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass B: Missions + ViewerEventCounter
|
// Pass B: Missions + ViewerEventCounter
|
||||||
|
|||||||
@@ -124,12 +124,18 @@ public class ImportStoryProgress
|
|||||||
|
|
||||||
public class ImportMissionMeta
|
public class ImportMissionMeta
|
||||||
{
|
{
|
||||||
[JsonPropertyName("has_received_pick_two_mission")]
|
// Wire key is `is_received_two_pick_mission` (loader-captured verbatim from /load/index
|
||||||
public bool? HasReceivedPickTwoMission { get; set; }
|
// user_info); the field ships as a string "1"/"0" not a bool. Keep the DTO type as int?
|
||||||
|
// so binding matches; the controller normalizes to bool.
|
||||||
|
[JsonPropertyName("is_received_two_pick_mission")]
|
||||||
|
public int? HasReceivedPickTwoMission { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("mission_receive_type")]
|
[JsonPropertyName("mission_receive_type")]
|
||||||
public int? MissionReceiveType { get; set; }
|
public int? MissionReceiveType { get; set; }
|
||||||
|
|
||||||
|
// Wire ships this as a "yyyy-MM-dd HH:mm:ss" string, NOT a Unix long (see
|
||||||
|
// FriendService.DefaultMissionChangeTime for the canonical game format). Controller
|
||||||
|
// parses via DateTime.TryParseExact with invariant culture.
|
||||||
[JsonPropertyName("mission_change_time")]
|
[JsonPropertyName("mission_change_time")]
|
||||||
public long? MissionChangeTime { get; set; }
|
public string? MissionChangeTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user