TIPS:
本系列贴仅用于博主学习ET框架的记录
前言
本章节使用账号登录注册的例子来展示ET框架与数据库之间的连接。
注意!!!本章节出现的账号登录注册逻辑仅限于学习,还不能拿去直接用,因为没考虑到的东西实在是太多了!!!!例如玩家短时间内多次请求登录、不同玩家同一时间登录同一账号等等…
一、安装数据库
安装mongoDB数据库及其可视化软件robot3T
1.新建数据库连接:
2.新建一个ET2数据库和Account表(集合):
在ET目录下的Excel文件夹下有一个StartZoneConfig@s.xlsx文件,默认对应两个数据库,分别为ET1和ET2,id代表区服,每个区服都有自己的数据库。
二、创建账号实体
打开ET源代码目录下的Server/Server.Model/Demo,新建一个Account文件夹,再在其下方创建一个Account实体类。
namespace ET
{
public enum AccountType
{
General = 1, //默认状态
Black = 2 //账号处在黑名单状态
}
public class Account: Entity, IAwake
{
public string AccountName { get; set; }//账号
public string Password { get; set; }//密码
public int AccountType { get; set; }//状态
public long CreateTime { get; set; }//创建日期
}
}
三、创建账号服务器
1.找到SceneType文件新增一个枚举变量Account
2.找到SceneFactory类新增一个case代码:
case SceneType.Account:
scene.AddComponent<NetKcpComponent, IPEndPoint, int>(startSceneConfig.OuterIPPort, SessionStreamDispatcherType.SessionStreamDispatcherServerOuter);
break;
3.回到ET\Excel文件夹目录下打开StartSceneConfig@s.xlsx文件并新增账号服务器。完成后回到目录双击bat命令行等待编译完成
4.这时候保存代码编译通过后运行服务端就能看到账号服务器被我们创建出来了
四、编写Protobuf消息
使用vs code打开ET目录下的Proto文件夹,在OuterMessage.proto下编写前后端通信消息,编写完成后回到目录运行bat文件等待编译通过:
//ResponseType A2C_LoginAccountResponse
message C2A_LoginAccountRequest // IRequest
{
int32 RpcId = 90;
string Account = 1;
string Password = 2;
}
message A2C_LoginAccountResponse // IResponse
{
int32 RpcId = 90;
int32 Error = 91;
string Message = 92;
}
C2A_LoginAccountRequest代表从客户端C向账号服务器A发起一条请求消息,内容是账号和密码。
A2C_LoginAccountResponse代表从账号服务器A向客户端C发起一条响应消息。
注意:这里这是简单的编写一下而已,正式的登录请求,响应消息是应该要有一个返回值token的。
五、编写逻辑代码
找到LoginHelper下的Login方法,把原有的代码都删掉重新编写:
using System;
namespace ET
{
public static class LoginHelper
{
public static async ETTask Login(Scene zoneScene, string address, string account, string password)
{
//定义响应消息
A2C_LoginAccountResponse a2CLoginAccountResponse = null;
Session session = null;
try
{
//通过地址创建一个session,这个session在这里是用来跟账号服务器做会话的
//所以address = 10005 刚刚在配表那里写的账号服务器的端口号
session = zoneScene.GetComponent<NetKcpComponent>().Create(NetworkHelper.ToIPEndPoint(address));
//发送请求消息
a2CLoginAccountResponse = (A2C_LoginAccountResponse) await session.Call(new C2A_LoginAccountRequest()
{
Account = account, Password = password
});
//查看响应码状态
if (a2CLoginAccountResponse.Error != ErrorCode.ERR_Success)
{
Log.Error(a2CLoginAccountResponse.Error.ToString());
return;
}
}
catch (Exception e)
{
Log.Error(e.ToString());
}
}
}
}
编写服务器处理登录请求消息的类:
using System;
namespace ET
{
public class C2A_LoginAccountRequestHandler: AMRpcHandler<C2A_LoginAccountRequest, A2C_LoginAccountResponse>
{
protected override async ETTask Run(Session session, C2A_LoginAccountRequest request, A2C_LoginAccountResponse response, Action reply)
{
//判断是否在账号服务器中
if (session.DomainScene().SceneType != SceneType.Account)
{
Log.Error("当前未处于账号服务器中。。。。");
response.Error = ErrorCode.ERR_SceneTypeError;//需要自行定义
reply();
session?.Dispose();
return;
}
//判断密码是否为空
if (string.IsNullOrEmpty(request.Account) || string.IsNullOrEmpty(request.Password))
{
response.Error = ErrorCode.ERR_AccountOrPasswordIsNull;
reply();
session?.Dispose();
return;
}
//等等一些其他判断就不做了 例如什么账号格式这些
//查询数据库 使用DBManagerComponent
//DBManagerComponent挂载在Game.Scene全局下
//这里的GetZoneDB里面的2代表的是2服 这里就写死了 代表ET2数据库的那个id 配表里可以找到
var users = await DBManagerComponent.Instance.GetZoneDB(2)
.Query<Account>(d => d.AccountName.Equals(request.Account.Trim()));
Account account = null;
//如果获取到的数据为空则证明没有该用户
if (users == null || users.Count == 0)
{
//没有用户的话就注册。
account = session.AddChild<Account>();
//赋值
account.AccountName = request.Account.Trim();
account.Password = request.Password.Trim();
account.CreateTime = TimeHelper.ServerNow();
account.AccountType = (int)AccountType.General;
//存到数据库
await DBManagerComponent.Instance.GetZoneDB(2).Save<Account>(account);
}
else
{
//如果存在账号走这里
account = users[0];
session.AddChild(account);
//判断账号处于冻结还是正常
if (account.AccountType == (int)AccountType.Black)
{
response.Error = ErrorCode.ERR_AccountIsBlack;
reply();
session?.Dispose();
account?.Dispose();
return;
}
//判断账号密码是否一致
if (!account.Password.Equals(request.Password))
{
response.Error = ErrorCode.ERR_PasswordError;
reply();
session?.Dispose();
account.Dispose();
return;
}
}
//如果可以走到这里就代表成功了
account.Dispose();
reply();
}
}
}
同时还要在AppStart_Init脚本中给Scene加上DBManagerComponent组件才能使用
最后把ConstValue中的LoginAddress的值后面的端口号改成账号服务器的100005即可。
六、运行
保存代码重新编译一下代码,通过后运行服务器端,并且回到Unity编辑器按下F5等待编译完成后运行游戏,输入账号后点击登录按钮即可看到数据库中已经有一条新数据了。
总结
good