DMM新网络框架开发适配.md 7.8 KB

DMM新网络框架开发适配

目前新网络框架(DmmNetwork)第一阶段已经合入主干开发分支。为了确保单局战斗逻辑能在PhotonDmmNetwork的网络框架下都正常运行,需遵照以下流程进行开发。

框架

编码

  • ### GameNetwork

由于目前项目中同时存在两种网络框架,即Photon和DmmNet,所以需要一个中间层在业务层进行网络接口的封装隔离,以便能通过开关切换单局网络类型。

适配方式:在公共业务层统一使用GameNetwork,不要直接调用PhotonNetwork。

  • ###### 常用属性

inRoom

//Before
if(PhotonNetwork.inRoom)
  
//After
if(GameNetwork.inRoom)

isMasterClient

//Before
if(PhotonNetwork.isMasterClient)
  
//After
if(GameNetwork.isMasterClient)

offlineMode

//Before
if(PhotonNetwork.offlineMode)
  
//After
if(GameNetwork.offlineMode)

player

//Before
msg.Add("sender", PhotonNetwork.player.UserId);
    
//After
msg.Add("sender", GameNetwork.player.UserId);

playerList

//Before
foreach (var player in PhotonNetwork.playerList)
{
    if (player.UserId == playerName)
    {
        return true;
    }
}
    
//After
foreach (var player in GameNetwork.playerList)
{
    if (player.UserId == playerName)
    {
        return true;
    }
}
  • 常用方法

InstantiateSceneObject

//Before
     GameObject inst = PhotonNetwork.InstantiateSceneObject(prefabName, pos, Quaternion.LookRotation(dir), 0, data);
     
//After
      GameObject inst = GameNetwork.InstantiateSceneObject(prefabName, pos, Quaternion.LookRotation(dir), 0, data);

RaiseEvent

//Before
PhotonNetwork.RaiseEvent(GamePhotonEvents.SynMaster, null, true, new RaiseEventOptions() {Receivers = ReceiverGroup.MasterClient});
  
//After
GameNetwork.RaiseEvent(GamePhotonEvents.SynMaster, null, true, new RaiseEventOptions() {Receivers = ReceiverGroup.MasterClient});
      

RPC

//Before
PhotonNetwork.RPC(this, methodName, targetPlayer, false, parameters);

//After
GameNetwork.RPC(this, methodName, targetPlayer, false, parameters);
      

其他属性和方法替换方式以此类推。

  • ### PhotonView

为了避免改动过多的预设,PhotonView脚本保留。在其类内的方法做了区分。

调用方式与原来Photon基本一致,仅在使用规则上有以下区别

1.手动注册rpc回调,减少发射带来的GC。

//该RPC协议号为1
[PunRPC(1)]
void AddPropProxy(int propID)
{
    AntiCheatingSystem.BehaviourCheck(RpcBehaviourType.AddProp, m_PlayerController, propID);
    m_PlayerController.LocalAddProp(propID);
}

制定RPC的协议号可以使用RPC协议号编号辅助工具:Toos/DmmLightNet/检查全部PunRPC的ID

RPC协议号定义类:RPCID

//RPC调用
public void RpcAddProp(int propID)
{
    m_IsDevouring = true;
    //需要手动填入要广播的RPC协议号,这里rpcId填1
    //如果不传rpcId,则RPC方法走反射通知的方式,和Photon一致。
    m_PhotonView.RPC("AddPropProxy", 1, PhotonTargets.AllViaServer, propID);
}
 
//手动注册
void Awake()
{
    if (NetworkType.UseDmmLightNet2)
    {
        int viewId = m_PlayerController.m_PhotonView.viewID;
        //注册
        DmmRpcRegister.RegisterCallback(viewId, 1, args => AddPropProxy((int) args[0]));
       ....
    }
}

//不带PhotonView组件的对象需手动注销rpc回调
protected override void OnDestroy()
{
    if (NetworkType.UseDmmLightNet2 && m_UsableId > 0)
    {
        DmmRpcRegister.UnregisterCallback(m_UsableId, 109);
    }
}
//带PhotonView的会自动统一注销,不需要手动单独注销
public void RemoveDmmRpc()
{
    var player = GetComponent<PlayerController>();
    if (player != null && player.IsRealPlayer)
    {
        //由于玩家对象断线重连时不销毁,所以不注销,统一在退出单局时的Reset中处理
        return;
    }
    DmmRpcRegister.RemoveView(viewID);
}
//为了兼容Photon方式,保留rpc方法名传参,只有当rpcid==0时有效。
public void RPC(string methodName, int rpcId, PhotonTargets target, params object[] parameters)
{
    GameNetwork.RPC(this, methodName, rpcId, target, false, parameters);
}

public void RPC(string methodName, PhotonTargets target, params object[] parameters)
{
    GameNetwork.RPC(this, methodName, 0, target, false, parameters);
}

2.RPC传参默认不支持新增的自定义枚举类型,统一转换成基础数据类型进行传递。

//Before
//不要直接传自定义的枚举
m_PlayerController.SkillManager.RPCSkillProxy(GameConstants.ID_SKILL_900,  Connect.ProxyEnum.TailCooldown);
    
//After
//把自定义枚举转成整型传递
m_PlayerController.SkillManager.RPCSkillProxy(GameConstants.ID_SKILL_900,  (int)Connect.ProxyEnum.TailCooldown);
    

如果需要传自定义的结构体,去DmmLightNet2CustomTypes.cs下实现序列化/反序列化方法:

public struct UseExtraInfo : ICustomSerializer
{
    public int userType; //0:角色 1:木偶 2:分身
    public void Serialize(FastBinaryWriter write)
    {
        write.Write(userType);
    }

    public void Deserialize(byte[] data, ref int offset)
    {
        userType = FastBinaryReader.ReadInt32(data, ref offset);
    }
}

调试

需要验证开发的战斗逻辑在DmmNet下能正常运行。

1.打开GM工具,设置网络类型为DmmNet,填写本机战斗服务器地址:127.0.0.1:45002

2.服务器工程地址在项目目录下的LightNetServer文件夹内,使用VS打开解决方案,运行即可。

3.单局内可查看单局网络类型

D代表Dmmnet

P代表Photon