6-16 Finishing Sign Up Mechanism
前幾章將登入完成以後,接著來製作註冊功能吧。註冊功能與登入功能非常相似,相信大家要自行完成註冊功能沒什麼難度。首先,在Client端新增SignupRequest,繼承Request,實作OnDefaultRequest。
完成發送Request的部分後,回到Inspector畫面,Operation Code選擇為Signup。
在NoliahFantasyServer.cs主類中記得要在Dictionary中新增新的SignupHandler。如不懂為何要做這一步的話,請記得將前兩章都看一下唷。
6-15 Using Handler To Respond Requisition In Photon Server
https://3dactionrpg.blogspot.tw/2018/05/6-15-using-handler-to-respond.html
6-14 Using Dictionary To Manage All Request
接下來處理我們在SignupHandler中的OnOperationRequest部分吧。先從Parameters中取得帳號跟密碼。
再使用UserManager確認該用戶是否已存在,如不存在才建立新帳號,如已存在則建立失敗。並使用ReturnCode方式回傳註冊結果。
回到Client端的SignupRequest,接收來自Server的ReturnCode後,將剩下的處理交給SignupWindow類。
主要因為註冊動作牽涉到UI變動,這部分的職責應劃分給SignupWindow。
以下提供本次有變動的原始碼。
Client端
SignupWindow.cs:
SignupRequest.cs:
Server端
SignupHandler.cs:
NoliahFantasyServer.cs:
接下來測試看看吧,首先輸入一個不存在的帳號密碼。嘗試登入後出現帳號或密碼錯誤。
接著來進行註冊,註冊成功。
再次按下註冊鈕,確實有檢查,並顯示該帳號已存在。
回到登入畫面,嘗試登入後顯示登入成功啦!
查詢MySQL資料庫後也確認該帳號確實有加進資料庫,不過這邊還是先提醒大家一點,密碼的儲存最好使用SHA-256並加鹽之類的方式儲存,才具有安全性唷,可不能這麼大喇喇地存在資料庫裡。
完成發送Request的部分後,回到Inspector畫面,Operation Code選擇為Signup。
接著到Server端新增SignupHandler繼承自BaseHandler,需要在建構子指定OperationCode為Signup。
在NoliahFantasyServer.cs主類中記得要在Dictionary中新增新的SignupHandler。如不懂為何要做這一步的話,請記得將前兩章都看一下唷。
6-15 Using Handler To Respond Requisition In Photon Server
https://3dactionrpg.blogspot.tw/2018/05/6-15-using-handler-to-respond.html
6-14 Using Dictionary To Manage All Request
接下來處理我們在SignupHandler中的OnOperationRequest部分吧。先從Parameters中取得帳號跟密碼。
再使用UserManager確認該用戶是否已存在,如不存在才建立新帳號,如已存在則建立失敗。並使用ReturnCode方式回傳註冊結果。
回到Client端的SignupRequest,接收來自Server的ReturnCode後,將剩下的處理交給SignupWindow類。
主要因為註冊動作牽涉到UI變動,這部分的職責應劃分給SignupWindow。
以下提供本次有變動的原始碼。
Client端
SignupWindow.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SignupWindow : Panel {
[SerializeField] InputField accountInput;
[SerializeField] InputField passwordInput;
[SerializeField] LoginWindow loginWindow;
[SerializeField] Text hintText;
SignupRequest signupRequest;
void Start(){
base.Start ();
signupRequest = GetComponent ();
}
public void OnSignupButton(){
hintText.text = string.Empty;
// 設定帳號及密碼參數後,呼叫OnDefaultRequest發送Request給Photon
signupRequest.account = accountInput.text;
signupRequest.password = passwordInput.text;
signupRequest.OnDefaultRequest ();
}
public void OnShowLoginButton(){
this.Hide ();
loginWindow.Show ();
}
public void OnSignupResponse(ReturnCode returnCode){
if (returnCode == ReturnCode.Success) {
hintText.text = "註冊成功";
} else {
hintText.text = "該帳號已存在";
}
}
}
SignupRequest.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SignupRequest : Request {
[HideInInspector] public string account;
[HideInInspector] public string password;
SignupWindow signupWindow;
void Start(){
base.Start ();
signupWindow = GetComponent ();
}
public override void OnDefaultRequest ()
{
Dictionary data = new Dictionary ();
data.Add((byte)ParameterCode.Acccount, account);
data.Add((byte)ParameterCode.Password, password);
// 向Server發出Request,true代表建立可靠連接
PhotonEngine.Instance.GetPeer().OpCustom((byte)operationCode, data, true);
}
public override void OnOperationResponse (ExitGames.Client.Photon.OperationResponse operationResponse)
{
ReturnCode returnCode = (ReturnCode)operationResponse.ReturnCode;
signupWindow.OnSignupResponse (returnCode);
}
}
Server端
SignupHandler.cs:
using System;
using Photon.SocketServer;
using NoliahFantasyServer.Constant;
using NoliahFantasyServer.Manager;
using NoliahFantasyServer.Model;
namespace NoliahFantasyServer.Handler
{
public class SignupHandler : BaseHandler
{
public SignupHandler()
{
operationCode = OperationCode.Signup;
}
public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer clientPeer)
{
// 從OperationRequest取得帳號密碼資訊
object account;
operationRequest.Parameters.TryGetValue((byte)ParameterCode.Acccount, out account);
object password;
operationRequest.Parameters.TryGetValue((byte)ParameterCode.Password, out password);
// 從資料庫中查詢用戶是否已存在
UserManager userManager = new UserManager();
Users users = userManager.GetByAccount(account as string);
// 使用short類型的ReturnCode簡單回傳結果
OperationResponse operationResponse = new OperationResponse((byte)OperationCode.Signup);
// 用戶不存在,建立帳號
if(users == null){
users = new Users() {
Account = account as string,
Pwd = password as string,
Registerdate = DateTime.Now
};
userManager.Add(users);
operationResponse.ReturnCode = (short)ReturnCode.Success;
}else{
// 用戶已存在,回傳訊息
operationResponse.ReturnCode = (short)ReturnCode.Failed;
}
// 發送Response
clientPeer.SendOperationResponse(operationResponse, sendParameters);
}
}
}
NoliahFantasyServer.cs:
using System;
using System.IO;
using System.Collections.Generic;
using Photon.SocketServer;
using ExitGames.Logging;
using ExitGames.Logging.Log4Net;
using log4net.Config;
using NHibernate;
using NHibernate.Cfg;
using NoliahFantasyServer.Constant;
using NoliahFantasyServer.Handler;
using NoliahFantasyServer.Model;
using NoliahFantasyServer.Manager;
namespace NoliahFantasyServer
{
public class NoliahFantasyServer : ApplicationBase
{
public static readonly ILogger logger = LogManager.GetCurrentClassLogger();
public static Dictionary handlerDict =
new Dictionary();
// 當Client端發出Request的時候
protected override PeerBase CreatePeer(InitRequest initRequest)
{
return new MyClientPeer(initRequest);
}
// Server端啟動的時候初始化
protected override void Setup()
{
InitLogger();
InitHandler();
}
// Server端關閉的時候
protected override void TearDown()
{
}
void InitLogger()
{
// 日誌初始化
log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] =
Path.Combine(this.ApplicationRootPath, "bin_Win64", "log");
FileInfo loggerConfig = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config"));
if (loggerConfig.Exists)
{
// 設置使用log4net的Log功能
LogManager.SetLoggerFactory(ExitGames.Logging.Log4Net.Log4NetLoggerFactory.Instance);
// 讓log4net讀取config
XmlConfigurator.ConfigureAndWatch(loggerConfig);
}
logger.Info("Setup Log4Net Compeleted!");
}
void InitHandler(){
LoginHandler loginHandler = new LoginHandler();
handlerDict.Add(loginHandler.operationCode, loginHandler);
SignupHandler signupHandler = new SignupHandler();
handlerDict.Add(signupHandler.operationCode, signupHandler);
}
}
}
接下來測試看看吧,首先輸入一個不存在的帳號密碼。嘗試登入後出現帳號或密碼錯誤。
接著來進行註冊,註冊成功。
再次按下註冊鈕,確實有檢查,並顯示該帳號已存在。
回到登入畫面,嘗試登入後顯示登入成功啦!
查詢MySQL資料庫後也確認該帳號確實有加進資料庫,不過這邊還是先提醒大家一點,密碼的儲存最好使用SHA-256並加鹽之類的方式儲存,才具有安全性唷,可不能這麼大喇喇地存在資料庫裡。












留言
張貼留言