func InitPlayer(player *Player, conn net.Conn) { player.PlayerStatus = GPS_BEGIN_SESSION player.conn = conn read := make(chan packet.Packet, 1) write := make(chan packet.Packet, 1) player.send = write player.client = read go func() { reader := packet.NewReader() player.packetReader = reader for { data, err := reader.Read(player.conn) if err != nil { if _, ok := err.(packet.NotImplementError); ok { log.Errorln("读到一个未实现的包:", data.PacketID()) } else { if err == io.EOF { log.Infoln("后台gouroutine读客户端失败了:", err) player.conn.Close() // 关闭读channel会使得agent的goroutine退出,回收资源 close(read) return } else { log.Errorln("这是一个严重的错误:", err) return } } } log.Debugln("读到了一个packet:", data) read <- data } }() go func() { writer := packet.NewWriter() player.packetWriter = writer for { pkt, ok := <-write if !ok { // 关闭使读goroutine退出 player.conn.Close() return } log.Debugf("write channel get a pkt: %#v\n", pkt) err := writer.Write(player.conn, pkt) if err != nil { log.Errorln(err) continue } } }() }
func serve(conn net.Conn) { defer conn.Close() reader := packet.NewReader() writer := packet.NewWriter() for { pkt, err := reader.Read(conn) if err != nil { if _, ok := err.(packet.NotImplementError); !ok { log.Errorln("read packet error in loginserver's serve:", err) return } } log.Debugln("read a packet: ", pkt.PacketID()) switch pkt.PacketID() { case packet.PACKET_CL_GET_WORLD_LIST: writer.Write(conn, packet.LCWorldListPacket{}) case packet.PACKET_CL_LOGIN: writer.Write(conn, packet.LCLoginOKPacket{}) case packet.PACKET_CL_SELECT_SERVER: writer.Write(conn, &packet.LCPCListPacket{}) case packet.PACKET_CL_SELECT_WORLD: writer.Write(conn, &packet.LCServerListPacket{}) case packet.PACKET_CL_VERSION_CHECK: writer.Write(conn, packet.LCVersionCheckOKPacket{}) case packet.PACKET_CL_SELECT_PC: reconnect := &packet.LCReconnectPacket{ Ip: config.GameServerIP, Port: 9998, Key: 82180, } writer.Write(conn, reconnect) return default: log.Errorf("get a unknow packet: %d\n", pkt.PacketID()) } } }