You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现非JSON游戏存档手动映射转JSON及技术咨询

C#处理非标准游戏存档的实现方案

核心结论

不需要手动用StringBuilder构建JSON,直接构建DTO对象是更高效、更可靠的方案;如果确实需要JSON作为中间格式,也可以直接通过序列化DTO生成,无需手动拼接。


具体实现步骤

1. 定义匹配存档结构的DTO类

直接对应你期望的结构定义C#类,覆盖固定字节段和可修改属性:

public class SaveFileDto
{
    public string HeaderBytes { get; set; }
    public List<ItemDto> Items { get; set; }
    public string FooterBytes { get; set; }
}

public class ItemDto
{
    public string HeaderBytes { get; set; }
    public PositionDto Position { get; set; }
    public string BytesBetweenPositionAndRotation { get; set; }
    public RotationDto Rotation { get; set; }
    public string FooterBytes { get; set; }
}

public class PositionDto
{
    public string X { get; set; }
    public string Y { get; set; }
    public string Z { get; set; }
}

public class RotationDto
{
    public string X { get; set; }
    public string Y { get; set; }
    public string Z { get; set; }
}

2. 从原始字节流直接构建DTO

使用BinaryReader读取存档文件,根据你分析出的字节映射规则,将固定字节段转为十六进制字符串(借助BitConverter.ToString()),拆分可变属性字节段赋值给DTO:

using (var reader = new BinaryReader(File.OpenRead("game_save")))
{
    var saveDto = new SaveFileDto();
    // 读取文件头固定字节并转十六进制字符串
    var headerBytes = reader.ReadBytes(/* 替换为实际文件头字节长度 */);
    saveDto.HeaderBytes = BitConverter.ToString(headerBytes);

    saveDto.Items = new List<ItemDto>();
    while (/* 替换为判断是否还有物品数据的逻辑 */)
    {
        var itemDto = new ItemDto();
        // 读取物品头固定字节
        var itemHeader = reader.ReadBytes(/* 替换为实际物品头长度 */);
        itemDto.HeaderBytes = BitConverter.ToString(itemHeader);

        // 验证Position标识字节(80-3F)
        var posMarker = reader.ReadBytes(2);
        if (BitConverter.ToString(posMarker) != "80-3F")
        {
            // 处理异常或跳过当前物品
            continue;
        }
        // 读取X/Y/Z各4字节
        itemDto.Position = new PositionDto
        {
            X = BitConverter.ToString(reader.ReadBytes(4)),
            Y = BitConverter.ToString(reader.ReadBytes(4)),
            Z = BitConverter.ToString(reader.ReadBytes(4))
        };

        // 读取Position与Rotation之间的固定字节
        var betweenBytes = reader.ReadBytes(/* 替换为实际中间字节长度 */);
        itemDto.BytesBetweenPositionAndRotation = BitConverter.ToString(betweenBytes);

        // 读取Rotation数据(参照Position的逻辑实现)
        // ...

        // 读取物品尾固定字节
        var itemFooter = reader.ReadBytes(/* 替换为实际物品尾长度 */);
        itemDto.FooterBytes = BitConverter.ToString(itemFooter);

        saveDto.Items.Add(itemDto);
    }

    // 读取文件尾固定字节
    var footerBytes = reader.ReadBytes(/* 替换为实际文件尾长度 */);
    saveDto.FooterBytes = BitConverter.ToString(footerBytes);
}

3. 修改DTO后还原为原始存档

使用BinaryWriter将DTO中的十六进制字符串转回字节数组,按原始结构写入文件:

using (var writer = new BinaryWriter(File.OpenWrite("modified_game_save")))
{
    // 写入文件头
    writer.Write(ConvertHexToBytes(saveDto.HeaderBytes));

    foreach (var item in saveDto.Items)
    {
        // 写入物品头
        writer.Write(ConvertHexToBytes(item.HeaderBytes));
        // 写入Position标识字节
        writer.Write(new byte[] { 0x80, 0x3F });
        // 写入Position的X/Y/Z
        writer.Write(ConvertHexToBytes(item.Position.X));
        writer.Write(ConvertHexToBytes(item.Position.Y));
        writer.Write(ConvertHexToBytes(item.Position.Z));
        // 写入中间固定字节
        writer.Write(ConvertHexToBytes(item.BytesBetweenPositionAndRotation));
        // 写入Rotation数据
        // ...
        // 写入物品尾
        writer.Write(ConvertHexToBytes(item.FooterBytes));
    }

    // 写入文件尾
    writer.Write(ConvertHexToBytes(saveDto.FooterBytes));
}

// 辅助方法:十六进制字符串转字节数组(去除连字符)
private static byte[] ConvertHexToBytes(string hexString)
{
    hexString = hexString.Replace("-", string.Empty);
    byte[] bytes = new byte[hexString.Length / 2];
    for (int i = 0; i < bytes.Length; i++)
    {
        bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
    }
    return bytes;
}

4. 关于JSON中间格式的选择

如果需要JSON作为中间层(比如存档配置、跨系统交互),可以直接用System.Text.Json或Newtonsoft.Json序列化/反序列化DTO,示例:

// DTO转JSON
string json = JsonSerializer.Serialize(saveDto, new JsonSerializerOptions { WriteIndented = true });

// JSON转DTO
SaveFileDto saveDtoFromJson = JsonSerializer.Deserialize<SaveFileDto>(json);

但直接操作DTO比经过JSON中间步骤更高效,减少了序列化开销,也避免了手动拼接JSON的错误。


内容的提问来源于stack exchange,提问作者Tyler Mason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:09:51