Unity使用反射进行Protobuf(CS/SC)协议,json格式

protobuf生成的协议,有挺多协议的.利用反射生成dto进行伪协议的响应 和 发送请求

应用场景:

请求(CS)_后端先写完了,前端还搞完时,可使用此请求,可自测

响应(SC)_可自行构建一个响应,对数据进行测试

csharp 复制代码
// 请求 使用物品  CS
message ReqUseItem{
    optional Opcodes MessageID=1[default = CG_MSG_REQ_USE_ITEM];
    optional uint32 itemId = 2;
    optional uint32 num = 3;
    optional string strparam = 4;  //buff{"castBuff":"1"}        {"rewardIdx":"1"} 礼包选择,从1开始     
}
//响应 使用物品 SC
message RetUseItem{
    optional Opcodes MessageID=1[default = GC_MSG_RET_USE_ITEM];
    optional uint32 errorCode = 2;
    optional uint32 itemId = 3;
    optional uint32 num = 4;
    repeated ItemInfo rewards = 5;
    optional string strparam = 6;
}

Unity使用Odin,写的页面,Json格式 dtoName{json内容}

csharp 复制代码
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.Reflection;
using QQu;
using Sirenix.OdinInspector;
using UnityEditor;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;

/// <summary> 协议 辅助工具  一般用来 1.测试请求   2.自己给自己下发数据</summary>
public class EditorSendReceiveNet : OdinEditorWindow
{
    [MenuItem("Tools/辅助工具/协议工具_请求_伪收到 &#%N", priority = 199)]
    public static void ShowNetTool()
    {
        var win = GetWindow<EditorSendReceiveNet>("协议___C2S___S2C(伪)");
        win.position = GUIHelper.GetEditorWindowRect().AlignCenter(680, 520);
    }

    private  Dictionary<string, Type> mEntityPbClass;

    public EditorSendReceiveNet()
    {
        Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); // 获取当前应用程序域中所有已加载的程序集
        mEntityPbClass = new Dictionary<string, Type>();
        foreach (var assembly in assemblies)
        {
            Type[] types = assembly.GetTypes(); // 筛选出所有 Pb 命名空间中的公共类
            var entityValues = types.Where(t => t.IsClass && t.IsPublic && t.Namespace == "Pb").ToList();
            foreach (var itemClass in entityValues)
            {
                var key = itemClass.FullName.Replace("Pb.", "");
                mEntityPbClass[key] = itemClass;
            }
        }
        Debug.LogError($"初始化_Pb_总条数{mEntityPbClass.Count}");
    }

    [LabelText("只知道dto名字"), HorizontalGroup("module"), PropertyOrder(Order = 1), Space(5)]
    public string mDtoNameTxt = "ReqUseItem";

    [Button("先 生成一个Json_Dto,然后手动自行修改赋值", ButtonSizes.Medium, ButtonHeight = 30), HorizontalGroup("module"), PropertyOrder(Order = 2)]
    public void GenOneDto()
    {
        if (mEntityPbClass.TryGetValue(mDtoNameTxt, out var itemClass))
        {
            var properties = itemClass.GetProperties();
            var defaultValues = new Dictionary<string, object>();
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(int) || property.PropertyType == typeof(uint))
                {
                    defaultValues[property.Name] = 0;
                }
                else if (property.PropertyType == typeof(string))
                {
                    defaultValues[property.Name] = "string_null";
                }
                else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(float))
                {
                    defaultValues[property.Name] = 0;
                }
                else if (property.PropertyType == typeof(bool))
                {
                    defaultValues[property.Name] = false;
                }
                else if (property.PropertyType.IsClass)
                {
                    defaultValues[property.Name] = null;
                }
            }
            var jsonContent = Newtonsoft.Json.JsonConvert.SerializeObject(defaultValues);
            mDtoJsonTxt = itemClass.Name.ToString() + "\n" + jsonContent.ToString();
        }
        else
        {
            Debug.LogError("确定左边 输入正确了?");
        }
    }

    [TextArea(20, 50), HideLabel, Space(30), PropertyOrder(Order = 3), InfoBox("应用场景: \r\n请求(CS)_后端先写完了,前端还搞完时,可使用此请求,可自测\r\n响应(SC)_可自行构建一个响应,对数据进行测试\r\nPS:Console面板的Log可以直接copy内容,再对内容进行小修改")]
    public string mDtoJsonTxt = @"SyncCurrency{
  ""InfoLists"": [
    {
      ""Ntype"": 11,
      ""Val"": 101660500
    }
  ]
}";
    [HorizontalGroup("Split", 0.5f)]
    [Button("伪_接收到协议", ButtonSizes.Medium, ButtonHeight = 30), PropertyOrder(Order = 4)]
    public void ReceiveNet()
    {
        int index = mDtoJsonTxt.IndexOf('{');
        string typeName = mDtoJsonTxt.Substring(0, index).Trim();
        string jsonContent = mDtoJsonTxt.Substring(index).Trim();
        if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(jsonContent))
        {
            Debug.LogError("数据格式 不对哦   dtoName{jsonString}   eg:SyncCurrency{  \"InfoLists\": [    {      \"Ntype\": 11,      \"Val\": 101660500    }  ]}");
            return;
        }
        if (mEntityPbClass.TryGetValue(typeName, out var itemClass))
        {
            var syncCurrency = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonContent, itemClass); // 使用非泛型的方法
            PropertyInfo messageIDProperty = itemClass.GetProperty("MessageID");
            object messageIDValue = messageIDProperty.GetValue(syncCurrency);
            var cmdValue = (int)messageIDValue;
            NetMgr.Ins.EditorReceive_Test((uint)cmdValue, syncCurrency);
        }
        else
        {
            Debug.LogError("查查吧~1.DTO没写对? 2.协议不是最新的?");
        }
    }

    [VerticalGroup("Split/right")]
    [Button("发送请求", ButtonSizes.Medium, ButtonHeight = 30), PropertyOrder(Order = 5)]
    public void SendNet()
    {
        int index = mDtoJsonTxt.IndexOf('{');
        string typeName = mDtoJsonTxt.Substring(0, index).Trim();
        string jsonContent = mDtoJsonTxt.Substring(index).Trim();
        if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(jsonContent))
        {
            Debug.LogError("数据格式 不对哦   dtoName{jsonString}   eg:SyncCurrency{  \"InfoLists\": [    {      \"Ntype\": 11,      \"Val\": 101660500    }  ]}");
            return;
        }
        if (mEntityPbClass.TryGetValue(typeName, out var itemClass))
        {
            var syncCurrency = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonContent, itemClass); // 使用非泛型的方法
            PropertyInfo messageIDProperty = itemClass.GetProperty("MessageID");
            object messageIDValue = messageIDProperty.GetValue(syncCurrency);
            var cmdValue = (int)messageIDValue;
            NetMgr.Ins.Send((uint)cmdValue, syncCurrency);//此行 调用 自己的业务 
        }
        else
        {
            Debug.LogError("查查吧~1.DTO没写对? 2.协议不是最新的?");
        }
    }
}
相关推荐
90后小陈老师2 小时前
Unity教学 项目2 2D闯关游戏
游戏·unity·游戏引擎
噗噗夹的TA之旅3 小时前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
nnsix3 小时前
Unity ReferenceFinder插件 多选资源查找bug解决
unity·游戏引擎·bug
gzroy5 小时前
Unity Shader Graph实现全息瞄准器
unity·游戏引擎
90后小陈老师8 小时前
Unity教学 基础介绍
unity·游戏引擎
90后小陈老师8 小时前
Unity教学 项目3 3D坦克大战
3d·unity·游戏引擎
秦奈10 小时前
Unity复习学习随笔(五):Unity基础
学习·unity·游戏引擎
nnsix10 小时前
Unity ReferenceFinder插件 窗口中选择资源时 同步选择Assets下的资源
java·unity·游戏引擎
麷飞花12 小时前
unity3d scene窗口选中物体, 在 hierarchy高光显示
unity·editor·unity3d·u3d·hierarchy
正在走向自律12 小时前
从Oracle到金仓KES:PL/SQL兼容性与高级JSON处理实战解析
数据库·sql·oracle·json·金仓数据库·电科金仓·兼容性挑战