babalae/better-genshin-impact · error · InvalidDataException
预期相对鼠标帧,实际为 {frame.PayloadType}。
Error message
预期相对鼠标帧,实际为 {frame.PayloadType}。 What it means
Thrown by InstanceIpcProtocol.ReadRelativeMouseBatch when the frame's PayloadType is not RelativeMouseBatch. The mouse-batch reader was invoked on a frame carrying a different payload type (JSON or RelativeMouseResult), indicating the receive-loop dispatch routed the frame to the wrong reader.
Source
Thrown at BetterGenshinImpact/Service/Instance/InstanceIpcProtocol.cs:197
var offset = RelativeMouseBatchHeaderLength;
foreach (var sample in samples)
{
BinaryPrimitives.WriteInt32LittleEndian(span[offset..], sample.DeltaX);
BinaryPrimitives.WriteInt32LittleEndian(span[(offset + sizeof(int))..], sample.DeltaY);
var offsetMicroseconds = checked((int)((sample.Timestamp.ToUniversalTime().Ticks - baseTicks) / 10));
BinaryPrimitives.WriteInt32LittleEndian(span[(offset + sizeof(int) * 2)..], offsetMicroseconds);
offset += RelativeMouseSampleLength;
}
return payload;
}
internal static (ulong FirstSequence, RelativeMouseSample[] Samples) ReadRelativeMouseBatch(
InstanceIpcFrame frame)
{
if (frame.PayloadType != InstanceIpcPayloadType.RelativeMouseBatch)
{
throw new InvalidDataException($"预期相对鼠标帧,实际为 {frame.PayloadType}。");
}
var span = frame.Payload.AsSpan();
if (span.Length < RelativeMouseBatchHeaderLength)
{
throw new InvalidDataException("相对鼠标帧头不完整。");
}
var count = BinaryPrimitives.ReadUInt16LittleEndian(span);
if (count is 0 or > 64
|| span.Length != RelativeMouseBatchHeaderLength + RelativeMouseSampleLength * count)
{
throw new InvalidDataException("相对鼠标帧长度无效。");
}
var firstSequence = BinaryPrimitives.ReadUInt64LittleEndian(span[sizeof(ushort)..]);
var baseTicks = BinaryPrimitives.ReadInt64LittleEndian(span[(sizeof(ushort) + sizeof(ulong))..]);
var samples = new RelativeMouseSample[count];View on GitHub (pinned to a7cb36712d)
Solutions
- Restart both instances to reset the pipe session.
- Ensure both instances are the same build so mouse-frame dispatch matches.
- If reproducing, log the raw payload-type byte to confirm whether it is corruption or a logic mismatch.
Defensive patterns
Strategy: try-catch
Validate before calling
if (frame.PayloadType != InstanceIpcPayloadType.RelativeMouseBatch)
{
throw new InvalidDataException($"预期相对鼠标帧,实际为 {frame.PayloadType}。");
} Type guard
static bool IsRelativeMouseBatchFrame(InstanceIpcFrame frame) => frame.PayloadType == InstanceIpcPayloadType.RelativeMouseBatch;
Try / catch
try
{
var batch = InstanceIpcProtocol.ReadRelativeMouseBatch(frame.Value);
}
catch (InvalidDataException ex) when (ex.Message.Contains("预期相对鼠标帧"))
{
logger.LogError(ex, "Frame type mismatch in mouse-batch reader; restart instances");
} Prevention
- Run matching builds so mouse-frame dispatch logic is identical on both ends.
- Restart instances on a frame-type mismatch to reset the pipe.
- Trace raw payload-type bytes if the error reproduces to find corruption vs. logic bugs.
When it happens
Trigger: The receive loop in InstanceConnection checked PayloadType == RelativeMouseBatch and called ReadRelativeMouseBatch, but the frame's actual type differs — a dispatch contradiction, typically from protocol version skew or a peer that mutates the type byte.
Common situations: Mixed-version root/child instances with different mouse-frame dispatch logic; stream corruption flipping the payload-type byte; a peer implementation error.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/c45b38a86649d64b.
Report an issue: GitHub.