40

leaf 和cocos creator 游戏实战(二)注册与登陆

 5 years ago
source link: https://studygolang.com/articles/14316?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

mongodb的安装及配置,参考下文:

https://blog.csdn.net/heshushun/article/details/77776706

proto注册协议扩展:

1.服务端:

编译 lobby.proto 文件(对此不了解?请先阅读《 在 Golang 中使用 Protobuf 》一文)得到 lobby.pb.go 文件,命令如下:

protoc --go_out=. lobby.proto

将lobby.pb.go 放在LeafServerExample src/msg文件夹下。

2.客户端:

把lobby.proto 复制到LeafServerCocosClient node_modules.bin文件夹下,把proto文件编译成静态文件使用:

pbjs -t static-module -w commonjs -o protocol.js lobby.proto
pbts -o protocol.d.ts protocol.js

把protocol.js 和protocol.d.ts拷贝到LeafServerCocosClient assets\script\protocol文件夹中.

3.lobby.proto:

syntax = "proto3";
package msg;

enum Result {
    REGISTER_SUCCESS=0;
    REGISTER_FAIL=1;
    LOGIN_SUCCESS=2;
    LOGIN_FAIL=3;
}

message Test {
    string Test = 2;
}

// 用户登陆协议
message UserLogin  {
    string LoginName = 1;   // 用户名
    string LoginPW =2;      // 密码
}
// 注册协议
message UserRegister {
    string LoginName =1;    // 用户名
    string LoginPW =2;      // 密码
}
// 消息返回协议
message UserResult {
    Result RetResult =1;
    string ErrorInfo = 2;
}

// 玩家有角色的情况
message UserST {
    string UID    =1;       // 账号ID
    string ServerID =2;     // 服务器ID
    string RoleUID  =3;     // 角色UID
    string RoleName =4;     // 角色名字
    string RoleLev =5;      // 角色等级
    string Coin  =6;        // 金币
    // 其他的暂时不做定义
}

向当前模块(game 模块)注册 消息处理函数

func init() {
    handler(&msg.UserLogin{}, handleUserLogin)
    handler(&msg.UserRegister{}, handleUserRegister)
}

处理相关消息

func handleUserRegister(args []interface{}) {
    m := args[0].(*msg.UserRegister)
    a := args[1].(gate.Agent)
    name :=m.GetLoginName()
    pwd :=m.GetLoginPW()
    log.Debug("receive UserRegister name=%v", m.GetLoginName())

    reg := regexp.MustCompile(`/^[a-zA-Z\d]\w{2,10}[a-zA-Z\d]$/`)
    matched := reg.FindString(name)
    if(matched!=" "){
        log.Debug("UserRegister name is licit", )
    }
    err := mongodbmgr.Find("game","login",bson.M{"name":name,})
    if err == nil {
        fmt.Println(err)
        log.Debug("UserRegister find in fail", )
        retBuf := &msg.UserResult{
            RetResult: msg.Result_REGISTER_FAIL,
            ErrorInfo:"账号已存在!",
        }
        a.WriteMsg(retBuf)
    }
    err =mongodbmgr.Insert("game","login",bson.M{"name":name,"password":pwd})
    if err != nil {
        fmt.Println(err)
        log.Debug("UserRegister write in fail", )
        retBuf := &msg.UserResult{
            RetResult: msg.Result_REGISTER_FAIL,
            ErrorInfo:"注册失败,请稍后再试!",
        }
        a.WriteMsg(retBuf)
    } else{
        log.Debug("UserRegister write in success", )
        retBuf := &msg.UserResult{
            RetResult: msg.Result_REGISTER_SUCCESS,
        }
        a.WriteMsg(retBuf)
    }
}
func handleUserLogin(args []interface{}) {
    m := args[0].(*msg.UserLogin)
    a := args[1].(gate.Agent)
    log.Debug("receive UserLogin name=%v", m.GetLoginName())

    retBuf := &msg.UserResult{
        RetResult: msg.Result_LOGIN_SUCCESS,
        ErrorInfo:"登陆失败,请稍后再试!",
    }
    a.WriteMsg(retBuf)
}

初始化时连接mongodb

package mongodbmgr

import (
    "fmt"
    "github.com/name5566/leaf/db/mongodb"
    "github.com/name5566/leaf/log"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

// 连接消息
var dialContext = new(mongodb.DialContext)

func init() {
    Connect()
}
func Connect() {
    c, err := mongodb.Dial("localhost", 10)
    if err != nil {
        fmt.Println(err)
        return
    }
    //defer c.Close()
    // index
    c.EnsureUniqueIndex("game", "login", []string{"name"})
    log.Release("mongodb Connect success")
    dialContext = c

    Test()
}
func Test() {
    err :=Find("game","login",bson.M{"name":"hello"})
    if err == nil {
        log.Debug("Test have data,regFail!", )
    }else{
        err =Insert("game","login",bson.M{"name":"hello","password":"123456"})
        if err != nil {
            fmt.Println(err)
            log.Debug("Test write in fail", )
        }
    }
}

func Example() {
    c, err := mongodb.Dial("localhost", 10)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer c.Close()

    // session
    s := c.Ref()
    defer c.UnRef(s)
    err = s.DB("test").C("counters").RemoveId("test")
    if err != nil && err != mgo.ErrNotFound {
        fmt.Println(err)
        return
    }

    // auto increment
    err = c.EnsureCounter("test", "counters", "test")
    if err != nil {
        fmt.Println(err)
        return
    }
    for i := 0; i < 3; i++ {
        id, err := c.NextSeq("test", "counters", "test")
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(id)
    }

    // index
    c.EnsureUniqueIndex("test", "counters", []string{"key1"})

    // Output:
    // 1
    // 2
    // 3
}

func Find(db string, collection string, docs interface{}) error{
    c:=dialContext
    s := c.Ref()
    defer c.UnRef(s)

    type person struct {
        Id_ bson.ObjectId `bson:"_id"`
        Name string `bson:"name"`
    };
    user:=new(person);
    err := s.DB(db).C(collection).Find(docs).One(&user)
    //idStr:=user.Id_.Hex()
    //fmt.Println(idStr)
    if err != nil {
        fmt.Println(err)
        return err
    }

    return err;
}

// goroutine safe
func Insert(db string, collection string, docs interface{}) error {
    c:=dialContext
    s := c.Ref()
    defer c.UnRef(s)

    //// 创建索引
    //index := mgo.Index{
    //  Key:        []string{"name"}, // 索引字段, 默认升序,若需降序在字段前加-
    //  Unique:     true,             // 唯一索引 同mysql唯一索引
    //  DropDups:   true,             // 索引重复替换旧文档,Unique为true时失效
    //  Background: true,             // 后台创建索引
    //}
    //if err := s.DB(db).C(collection).EnsureIndex(index); err != nil {
    //  fmt.Println(err)
    //  return err
    //}
    //if err := s.DB(db).C(collection).EnsureIndexKey("$2dsphere:location"); err != nil { // 创建一个范围索引
    //  fmt.Println(err)
    //  return err
    //}

    err := s.DB(db).C(collection).Insert(docs)
    if err != nil {
        fmt.Println(err)
        return err
    }

    return err
}

Cocos creator客户端注册及登陆

简单的合法性判断工具类

import messageDialog from './MessageDialog';
interface CheckRet{
    ret:boolean,
    msg:string
}
interface message{
    title:string,
    text:string
}
export default class Utils {
    //检测用户名是否合法
    static check_usr(str:string):CheckRet{
        let c=<CheckRet>{};
        var b :RegExp=/^[a-zA-Z\d]\w{2,10}[a-zA-Z\d]$/;
        if (b.test(str)) {
            c.ret = true;
            c.msg = "用戶名合法";
        }
        else {
            c.ret = false;
            c.msg = "用戶名不合法";
        }

        return c;
    }
    
    
    //判断密码输入是否合法,一个是长度,一个是没有特殊字符
    static check_psw(str:string):CheckRet{
        let c=<CheckRet>{};
        if(str.length > 5 && str.length<21){
            c.ret = true;
            c.msg = "";
        }else {
            c.ret = false;
            c.msg = "密码长度不合规范";
        }
        var b:RegExp =/^[a-zA-Z\d]\w{2,10}[a-zA-Z\d]$/;
        if (b.test(str)) {
            c.ret = true;
            c.msg = "";
        }else {
            c.ret = false;
            c.msg = "密码字符不合规范";
        }

        return c;
    }

        
    //判断手机号码格式是否合法
    static check_tel(str:string):CheckRet{
        let c=<CheckRet>{};
        var regx=/^(?:13\d|15\d|18[123456789])-?\d{5}(\d{3}|\*{3})$/;
        if(regx.test(str)){
            c.ret = true;
            c.msg = "";
        }else{
            c.ret = false;
            c.msg = "手机号不合规范";
        }

        return c;
    }
    
        
    //判断邮箱地址格式是否合法
    static check_mail(str:string):CheckRet{
        let c=<CheckRet>{};
        var regm = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;//验证Mail的正则表达式,^[a-zA-Z0-9_-]:开头必须为字母,下划线,数字,
        if (str.match(regm)){
            c.ret = true;
            c.msg = "";
            
        } else{
            c.ret = false;
            c.msg = "邮箱地址不合规范";
        }

        return c;
    }

    static showTips(title:string,text:string){
        messageDialog.getInstance().showTips({title:title,text:text})
    }
}

注册流程

import NetMessageCtrl  from './NetMessageCtrl';
import Utils from './Utils';
const {ccclass, property} = cc._decorator

@ccclass
export default class Register extends cc.Component {

    @property(cc.EditBox)
    Name: cc.EditBox = null;

    @property(cc.EditBox)
    Pwd: cc.EditBox = null;

    onLoad(){
           
    }

    onBtnPanel(){
        this.node.parent.active = false
    }

    onBtnComfirm(){
        var name = this.Name.string;
        var pwd = this.Pwd.string;
        if(name && pwd){
            let check = Utils.check_usr(name)
            let checkPwd = Utils.check_psw(name)
            if(check.ret){
                if(checkPwd.ret){
                    NetMessageCtrl.getInstance().sendRegister(name,pwd);
                }
                else{
                    Utils.showTips("提示",checkPwd.msg)
                }
            }
            else{
                Utils.showTips("提示",check.msg)
            }
        }
        else{
            Utils.showTips("提示","请输入完整注册数据")
        }
    }
}

处理收到的回信

dealMessage(id: number,data: Uint8Array ){
      switch(id){
            case netConfig.ProtocolId.Test:
                this.dealTest(data)
                break;
            case netConfig.ProtocolId.UserResult:
                this.dealUserResult(data)
                break;
            default:
                break;
        }
    }

  //注册登陆登一系列用户行为的结果都通过netConfig.ProtocolId.UserResult协议返回
   dealUserResult(data: Uint8Array){
        console.log("get UserResult message!");
        let gameMsg = msg.UserResult.decode(data);
        console.log(gameMsg);
    }

Example gihub地址:

server: https://github.com/ddkgo/LeafServerExample.git

client: https://github.com/ddkgo/LeafServerCocosClient.git


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK