从零开始手写mmo游戏从框架到爆炸(十六)— 客户端指定回调路由与登录

导航:从零开始手写mmo游戏从框架到爆炸(零)------ 导航-CSDN博客

我们这次来把注册、登录、选择英雄,进入主页-选择地图的功能完善。

在这之前,我们还要解决一个问题,就是服务端往客户端发消息的路由问题,这个路由其实应该由客户端来指定,因为客户端在不同的场景中可能会调用同一个服务端路由,比如查询英雄状态,装备状态等等。所以应该由客户端来指定回调地址比较友好。由于这个字段并不是必须的,我们可以把回调的topic和tag放到一个基类中。

RequestBase.java

java 复制代码
package com.loveprogrammer.dto.base;

import java.io.Serializable;

/**
 * @ClassName RequestBase
 * @Description 请求基类
 * @Author admin
 * @Date 2024/2/19 10:35
 * @Version 1.0
 */
public class RequestBase implements Serializable {

    private int callbackTopic;
    private int callbackTag;

    public int getCallbackTopic() {
        return callbackTopic;
    }

    public void setCallbackTopic(int callbackTopic) {
        this.callbackTopic = callbackTopic;
    }

    public int getCallbackTag() {
        return callbackTag;
    }

    public void setCallbackTag(int callbackTag) {
        this.callbackTag = callbackTag;
    }
}

补充登录相关的请求体以及执行handler

java 复制代码
@Data
public class UserLogin extends RequestBase {

    private String userName;

    private String password;

}

服务端的LoginHandler 中增加登录代码:

java 复制代码
 /***
     * 登录
     * @param ctx
     * @param register
     */
    @TagListener(tag = LogAndRegisterTag.TAG_LOGIN_LOGIN,messageClass = UserLogin.class)
    public void register(ChannelHandlerContext ctx, UserLogin register){
        //  查询用户
        User user = userService.findUserByAccount(register.getUserName());
        if(user == null) {

            // TODO 返回登录页面
        }
        // 对比密码
        if(!register.getPassword().equalsIgnoreCase(user.getPassword())) {
            // TODO 返回登录页面
        }
        // 登录成功,把user信息放入session中
        Session session = SessionManager.getInstance().getSessionByChannel(ctx.channel());
        session.setUserId(user.getId().toString());
        session.setNickname(user.getNickName());

        // 进入主页
        String result = "登录成功";
        StringMessage message = StringMessage.create(ClientTopic.TOPIC_MENU, ClientMenuTag.TAG_MENU_PORTAL);
        message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);
        message.setBody(result);
        SessionManager.getInstance().sendMessage(ctx.channel(),message);

        // TODO 客户端进入选择英雄页面

    }

客户端增加登录的处理:LoginHandler

java 复制代码
package com.loveprogrammer.handler.support;

import com.alibaba.fastjson2.JSON;
import com.loveprogrammer.command.BaseHandler;
import com.loveprogrammer.command.anotation.TagListener;
import com.loveprogrammer.command.anotation.TopicListener;
import com.loveprogrammer.command.client.ClientLoginTag;
import com.loveprogrammer.command.client.ClientMenuTag;
import com.loveprogrammer.command.client.ClientTopic;
import com.loveprogrammer.command.server.LogAndRegisterTag;
import com.loveprogrammer.command.server.ServerTopic;
import com.loveprogrammer.console.ConsolePrint;
import com.loveprogrammer.constants.CommonValue;
import com.loveprogrammer.dto.login.UserLogin;
import com.loveprogrammer.dto.login.UserRegister;
import com.loveprogrammer.network.NetworkClientListener;
import com.loveprogrammer.pojo.StringMessage;
import com.loveprogrammer.utils.ChannelUtils;
import com.loveprogrammer.utils.ScannerInput;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Scanner;

/**
 * @ClassName MenuHandler
 * @Description TODO
 * @Author admin
 * @Date 2024/2/18 17:37
 * @Version 1.0
 */
@TopicListener(topic = ClientTopic.TOPIC_LOGIN)
public class LoginHandler extends BaseHandler {

    public static final Logger log = LoggerFactory.getLogger(LoginHandler.class);

    @TagListener(tag = ClientLoginTag.TAG_LOGIN_REGISTER,messageClass = String.class)
    public void LoginMenu(ChannelHandlerContext ctx, String msg){

        // 展示首页数据
        ConsolePrint.publishMessage("【1.登录已有账户】  【2.注册新账户】  【3.退出】");
        ConsolePrint.publishMessage("请选择:");

        int choose = ScannerInput.inputInt(1, 3, 3);

        while (choose != 3) {
            switch (choose) {
                case 1:
                    ConsolePrint.publishMessage("请输入账户名:");
                    String name = ScannerInput.inputString();
                    ConsolePrint.publishMessage("请输入密码:");
                    String password = ScannerInput.inputString();
                    UserLogin userLogin = new UserLogin(name,password);
                    StringMessage message = new StringMessage();
                    message.setTopicId(ServerTopic.TOPIC_LOGIN);
                    message.setTagId(LogAndRegisterTag.TAG_LOGIN_LOGIN);
                    message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);
                    message.setBody(JSON.toJSONString(userLogin));
                    ChannelUtils.pushToServer(ctx.channel(), message);
                case 2:
                    // 注册
                    ConsolePrint.publishMessage("请输入注册的用户名");
                    String registerName = ScannerInput.inputString();
                    UserRegister register = new UserRegister();
                    register.setName(registerName);
                    StringMessage data = StringMessage.create(ServerTopic.TOPIC_LOGIN, LogAndRegisterTag.TAG_LOGIN_REGISTER);
                    data.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);
                    data.setBody(JSON.toJSONString(register));
                    ChannelUtils.pushToServer(ctx.channel(), data);
                default:
                    ConsolePrint.publishMessage("暂未开放,敬请期待", 1);
                    break;
            }
        }

        // 这里不退出,而是返回首页,做一个重定向
        NetworkClientListener.getInstance().forward(ctx,ClientTopic.TOPIC_LOGIN, ClientLoginTag.TAG_LOGIN_REGISTER,msg);
    }
}

客户端的效果如下:

Delphi 复制代码
14:28:18.060 [nioEventLoopGroup-2-1] [INFO ] com.loveprogrammer.handler.HandlerFactory:32 --- 初始化消息监听器成功 com.loveprogrammer.handler.support.MenuHandler
14:28:18.060 [nioEventLoopGroup-2-1] [INFO ] com.loveprogrammer.handler.HandlerFactory:32 --- 初始化消息监听器成功 com.loveprogrammer.handler.support.LoginHandler
【1.登录已有账户】  【2.注册新账户】  【3.退出】
请选择:
1
请输入账户名:
eric
请输入密码:
111111
请输入注册的用户名
14:28:29.832 [nioEventLoopGroup-2-1] [INFO ] com.loveprogrammer.network.NetworkClientListener:32 --- 数据内容:data=StringMessage{messageId=2, statusCode=1, length=12, body='登录成功'}
登录成功
请选择您要进行的操作
【1.打怪】  【2.装备】  【3.战兽】
【4.冒险者工会】   【5.副本】  【6.工会】 
【8.配置】  【9.退出】
请选择:

全部源码详见:

gitee : eternity-online: 多人在线mmo游戏 - Gitee.com

分支:step-09

请各位帅哥靓女帮忙去gitee上点个星星,谢谢!

相关推荐
代码小书生6 小时前
游戏多功能助手!PC电脑单机游戏难度适配,新手游玩体验优化设置调节!支持龙胤立志传、宗门起源、灰烬之国、杀戮尖塔2、克鲁赛德战记等
游戏·单机游戏·修改器·游戏教程·游戏助手·电脑游戏·游戏技巧
魔士于安8 小时前
Unity资源Toon City Pack 发电厂 工地 公园 地铁站口 银行 车 直升飞机 可动 URP
游戏·unity·游戏引擎·贴图·模型
沙振宇13 小时前
【Web】使用Vue3+PlayCanvas开发3D游戏(九)纹理视觉效果
前端·游戏·3d·纹理
win10系统14 小时前
多开游戏专用Win10 64位 专业版(专为多开搬砖制作)
游戏·win10·win10系统安装
张老师带你学14 小时前
Unity buildin 石头围墙 树木 树墩子 卡通风格 栅栏 小桥 低多边形
科技·游戏·unity·游戏引擎·模型
上海云盾-小余18 小时前
高防 IP 与游戏盾如何搭配?多场景攻击防护实战配置指南
网络协议·tcp/ip·游戏
呆呆敲代码的小Y18 小时前
【Unity工具篇】| 使用YooAsset接入自己的游戏项目,实现完整热更新流程
游戏·unity·游戏引擎·热更新·yooasset·资源热更新
qq_3573896318 小时前
游戏电竞俱乐部护航下单系统源码
游戏
谷歌开发者18 小时前
成就高品质游戏的获客之道|Google Play Games Level Up 计划
游戏
张老师带你学18 小时前
Unity 低多边形 赛博朋克城市 拼装 模型 道路 建筑 buildin
科技·游戏·unity·游戏引擎·模型