1. 程式人生 > >Photon Server遊戲伺服器從零開始學習(六)遊戲登入與註冊操作

Photon Server遊戲伺服器從零開始學習(六)遊戲登入與註冊操作

為了在客戶端與伺服器端使用共同的code,建立共有引用Common:

public enum OperationCode:byte //區分請求和響應的型別 
{
    Default,//預設請求
    Login, //登入 
    Register //註冊
}

public enum ReturnCode:short //伺服器返回的型別
{
    Success,//成功
    Failed //失敗
}

public enum ParameterCode:byte //區分傳送資料的時候,引數的型別
{
   Username,//使用者名稱
   Password,  //密碼
}

//獲取字典的值
public
class DictTool { public static T2 GetValue<T1, T2>(Dictionary<T1,T2> dict, T1 key) { T2 value; bool isSuccess = dict.TryGetValue(key, out value); if (isSuccess) { return value; } else { return
default(T2); } } }

在客戶端新建一個請求的基類Request:

//客戶端向伺服器的請求
public abstract class Request:MonoBehaviour  
{
    public OperationCode OpCode;//請求型別
    public abstract void DefaultRequest();//預設的請求

    //伺服器端返回的響應
    public abstract void OnOperationResponse(OperationResponse operationResponse);

    public
virtual void Start() { //新增請求到集合 GamePhotonEngine.Instance.AddRequest(this); } public void OnDestroy() { //從集合中刪除當前請求 GamePhotonEngine.Instance.RemoveRequest(this); } }

在GamePhotonEngine 類中新增:

//所有請求的一個集合
private Dictionary<OperationCode, Request> RequestDict = new Dictionary<OperationCode, Request>();

//客戶端向伺服器發起一個請求以後伺服器處理完以後 就會給客戶端一個響應  
 public void OnOperationResponse(OperationResponse operationResponse)
    {
        //把伺服器返回的請求分發給對應的子類去處理
        OperationCode opCode =(OperationCode) operationResponse.OperationCode;
        Request request = null;
        bool temp= RequestDict.TryGetValue(opCode, out request);

        if (temp)
        {
            request.OnOperationResponse(operationResponse);
        }
        else
        {
            Debug.Log("沒找到對應的響應處理物件");
        }
    }

 public void AddRequest(Request request)
 {
     RequestDict.Add(request.OpCode, request);
 }
 public void RemoveRequest(Request request)
 {
     RequestDict.Remove(request.OpCode);
 }

伺服器端新建處理各個請求的 BaseHandler基類:

public abstract class BaseHandler
 {
     public OperationCode OpCode;

     public abstract void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters,MyClientPeer peer);
 }

//新建一個預設的Handler:
class DefaultHandler:BaseHandler
{
    public DefaultHandler()
    {
        OpCode = Common.OperationCode.Default;
    }
    public override void OnOperationRequest(Photon.SocketServer.OperationRequest operationRequest, Photon.SocketServer.SendParameters sendParameters, MyClientPeer peer)
    {
        throw new NotImplementedException();
    }
}

在MyClientPeer中分派各個響應:

//處理客戶端的請求
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
    BaseHandler handler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict, (OperationCode)operationRequest.OperationCode);
    if (handler != null)
    {
    handler.OnOperationRequest(operationRequest, sendParameters, this);
    }
    else
    {
    BaseHandler defaultHandler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict, OperationCode.Default);
    defaultHandler.OnOperationRequest(operationRequest, sendParameters, this);
    }
}

在 伺服器端MyGameServer中新增程式碼:

//Handler集合
public Dictionary<OperationCode, BaseHandler> HandlerDict = new Dictionary<OperationCode, BaseHandler>();

public static MyGameServer Instance
{
    get;
    private set;
}

protected override void Setup()
{
    //初始化各個Handler
    Instance = this;
    InitHandler();
}

public void InitHandler()
{
    DefaultHandler defaultHandler = new DefaultHandler();
    HandlerDict.Add(defaultHandler.OpCode, defaultHandler);

    LoginHandler loginHandler = new LoginHandler();
    HandlerDict.Add(loginHandler.OpCode, loginHandler);

    RegisterHandler registerHandler = new RegisterHandler();
    HandlerDict.Add(registerHandler.OpCode, registerHandler);
}

登入操作

UI介面:
這裡寫圖片描述

LoginPanel :

using Common;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LoginPanel : MonoBehaviour
{
    public GameObject goLoginPanel;
    public GameObject RegisterPanel;
    private LoginRequest loginRequest;
    public InputField usernameIF;
    public InputField passwordIF;
    public Text hintMessage;
    void Start()
    {
        loginRequest = GetComponent<LoginRequest>();
    }

    public void OnLoginBtn()
    {
        hintMessage.text = "";
        loginRequest.Username = usernameIF.text;
        loginRequest.Password = passwordIF.text;
        loginRequest.DefaultRequest();

        Debug.Log("OnLoginBtn");
    }

    public void OnRegister()
    {
        goLoginPanel.SetActive(false);
        RegisterPanel.SetActive(true);
    }
    public void OnLoginResponse(ReturnCode returnCode)
    {
        if (returnCode == ReturnCode.Success)
        {
            // 跳轉到下一個場景 
           // SceneManager.LoadScene("Game");
            Debug.Log("登入成功");
        }
        else
        {
            hintMessage.text = "使用者名稱或密碼錯誤";
        }
    }
}

在客戶端新建一個登入操作請求LoginRequest :

public class LoginRequest : Request {
    [HideInInspector]
    public string Username;
    [HideInInspector]
    public string Password;

    private LoginPanel loginPanel;

    public override void Start()
    {
        base.Start();
        loginPanel = GetComponent<LoginPanel>();
    }

    public override void DefaultRequest()
    {
        Dictionary<byte,object> data = new Dictionary<byte,object>();
        data.Add((byte)ParameterCode.Username, Username);
        data.Add((byte)ParameterCode.Password, Password);
        GamePhotonEngine.Peer.OpCustom((byte)OpCode, data, true);
    }

    public override void OnOperationResponse(OperationResponse operationResponse)
    {
        ReturnCode returnCode = (ReturnCode)operationResponse.ReturnCode;

        loginPanel.OnLoginResponse(returnCode);
    }
}

在伺服器端新建LoginHandler:

 class LoginHandler:BaseHandler
 {
     public LoginHandler()
     {
         OpCode = OperationCode.Login;
     }
     public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
     {
         string username = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Username) as string;
         string password = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Password) as string;
         UserManager manager = new UserManager();
         bool isSuccess = manager.VerifyUser(username, password);

         OperationResponse response = new OperationResponse(operationRequest.OperationCode);
         if (isSuccess)
         {
             response.ReturnCode = (short)Common.ReturnCode.Success;
             peer.username = username;
         }
         else
         {
             response.ReturnCode = (short)Common.ReturnCode.Failed;
         }
         peer.SendOperationResponse(response, sendParameters);
     }
 }

註冊操作:

public class RegisterRequest : Request {

[HideInInspector]
  public string username;
  [HideInInspector]
  public string password;

  private RegisterPanel registerPanel;
  public override void Start()
  {
      base.Start();
      registerPanel = GetComponent<RegisterPanel>();
  }

  public override void DefaultRequest()
  {
      Dictionary<byte, object> data = new Dictionary<byte, object>();
      data.Add((byte)ParameterCode.Username, username);
      data.Add((byte)ParameterCode.Password, password);
      GamePhotonEngine.Peer.OpCustom((byte)OpCode, data, true);
  }

  public override void OnOperationResponse(OperationResponse operationResponse)
  {
      ReturnCode returnCode = (ReturnCode)operationResponse.ReturnCode;
     // registerPanel.OnReigsterResponse(returnCode);
  }
}
class RegisterHandler:BaseHandler
{
    public RegisterHandler()
    {
        OpCode = OperationCode.Register;
    }

    public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
    {
        string username = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Username) as string;
        string password = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Password) as string;
        UserManager manager = new UserManager();
        User user = manager.GetByUsername(username);
        OperationResponse response = new OperationResponse( operationRequest.OperationCode );
        if (user == null)
        {
            user= new User(){Username=username,Password=password};
            manager.Add(user);
            response.ReturnCode =(short) ReturnCode.Success;
        }
        else
        {
            response.ReturnCode = (short)ReturnCode.Failed;
        }
        peer.SendOperationResponse(response, sendParameters);
    }
}