想做网络游戏的小伙伴肯定找过 mirro ,Photon的工具 ,但是不是很好用,想自定义强一点,连外网服务器 资料很少或者没有。
我直接用java的netty做的udp服务器就实现了个简单的
实现了功能有
创建人物,人物移动可以同步。 登录后加载身边的人物。
代码
这个类初始化netty服务器 ,转发操作命令
package com.hewei.config;
import cn.hutool.core.util.StrUtil;
import com.hewei.game.service.cmd.Command;
import com.hewei.game.vo.CmdVo;
import com.hewei.util.ScanSupport;
import com.hewei.util.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {
Logger logger = LoggerFactory.getLogger(BootNettyUdpSimpleChannelInboundHandler.class);
Map<String, Constructor> commandMap = new HashMap<>();
{
ScanSupport scanSupport = SpringUtil.getBean(ScanSupport.class);
try {
Set<Class<?>> classes = scanSupport.doScan("com.hewei.game.service.cmd");
for (Class<?> aClass : classes) {
putCmdName((Class<? extends Command>) aClass);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
void putCmdName(Class<? extends Command> clazz) throws NoSuchMethodException {
String cmd = StrUtil.subBefore(clazz.getSimpleName(), "Cmd", true).toLowerCase();
Constructor c = clazz.getConstructor(CmdVo.class);//获取有参构造
commandMap.put(cmd, c);
logger.info("putCmdName|{}", clazz);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
try {
ByteBuf content = Unpooled.copiedBuffer(packet.content());
ByteBuf header = content.readBytes(50);
String s1 = header.toString(CharsetUtil.UTF_8).trim();
logger.info("channelRead0|{}", s1);
String[] split = s1.split(":");
String type = split[0];
String userId = split[1];
CmdVo cmdVo = new CmdVo()
.setContent(content)
.setCtx(ctx)
.setHeader(header)
.setPacket(packet)
.setUserId(userId);
Command c = (Command) commandMap.get(type).newInstance(cmdVo);
c.execute();
} catch (Exception e) {
logger.error("channelRead0", e);
}
}
}
这个类是命令的公共父类
package com.hewei.game.service.cmd;
import com.hewei.game.service.GameCtx;
import com.hewei.game.vo.CmdVo;
import com.hewei.util.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import java.net.InetSocketAddress;
@Slf4j
public abstract class AbsCmd implements Command {
ChannelHandlerContext ctx;
String senderUserId;
DatagramPacket packet;
ByteBuf content;
ByteBuf header;
InetSocketAddress sender;
CmdVo cmdVo;
public AbsCmd(CmdVo cmdVo) {
this.cmdVo = cmdVo;
this.ctx = cmdVo.ctx;
this.senderUserId = cmdVo.userId;
this.packet = cmdVo.packet;
this.content = cmdVo.content;
this.header = cmdVo.header;
this.sender = this.packet.sender();
}
public void send2Sender(ByteBuf byteBuf) {
byteBuf.setIndex(0, byteBuf.writerIndex());
ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(byteBuf), packet.sender()));
}
public void sendSkipSender(ByteBuf byteBuf) {
for (InetSocketAddress addr : GameCtx.login.values()) {
if (addr.equals(packet.sender())) {
continue;
}
byteBuf.retain();
log.info("sendSkipSender-to|{}", addr);
byteBuf.setIndex(0, byteBuf.writerIndex());
ctx.writeAndFlush(new DatagramPacket(byteBuf, addr));
}
}
public void sendAll(ByteBuf byteBuf) {
for (InetSocketAddress addr : GameCtx.login.values()) {
log.info("sendSkipSender-to|{}", addr);
byteBuf.retain();
byteBuf.setIndex(0, byteBuf.writerIndex());
ctx.writeAndFlush(new DatagramPacket(byteBuf, addr));
}
}
public ByteBuf createHeader(String str){
byte[] padding = ByteUtil.padding(50, str.getBytes());
System.out.println(new String(padding));
return Unpooled.wrappedBuffer(padding);
}
}
代码示例
unity3d的代码
代码太多我已经放到gitee
java
留言再给
u3d
https://gitee.com/nhniu/unity3d_udp
下一步要实现 心跳 ,战斗