导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客
我们这次来把注册、登录、选择英雄,进入主页-选择地图的功能完善。
在这之前,我们还要解决一个问题,就是服务端往客户端发消息的路由问题,这个路由其实应该由客户端来指定,因为客户端在不同的场景中可能会调用同一个服务端路由,比如查询英雄状态,装备状态等等。所以应该由客户端来指定回调地址比较友好。由于这个字段并不是必须的,我们可以把回调的topic和tag放到一个基类中。
RequestBase.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
@Data
public class UserLogin extends RequestBase {private String userName;private String password;}
服务端的LoginHandler 中增加登录代码:
/**** 登录* @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
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);}
}
客户端的效果如下:
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上点个星星,谢谢!