Пример #1
0
func Add(Type int16, user_id int32, timeout int64, params []byte) int32 {
	defer _event_err()
	req := event.ADD_EVENT{}
	req.F_type = Type
	req.F_user_id = user_id
	req.F_timeout = timeout
	req.F_params = params
	ret := _call(packet.Pack(event.Code["add_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _ := event.PKT_INT(reader)
	return tbl.F_v
}
Пример #2
0
//------------------------------------------------ Forward to Hub/Group
func GroupForward(req *IPCObject) bool {
	defer _hub_err()
	msg := hub.FORWARDIPC{F_IPC: req.Json()}
	ret := _call(packet.Pack(hub.Code["forwardgroup_req"], &msg, nil))
	reader := packet.Reader(ret)
	tbl, err := hub.PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		return false
	}

	return true
}
Пример #3
0
func Ping() bool {
	defer _event_err()
	req := event.INT{}
	req.F_v = 1
	ret := _call(packet.Pack(event.Code["ping_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _ := event.PKT_INT(reader)
	if tbl.F_v != req.F_v {
		return false
	}

	return true
}
Пример #4
0
func AddUser(id int32) bool {
	defer _hub_err()
	req := hub.ID{}
	req.F_id = id
	ret := _call(packet.Pack(hub.Code["adduser_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, err := hub.PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		return false
	}

	return true
}
Пример #5
0
func Login(id int32) bool {
	defer _hub_err()
	req := hub.LOGIN_REQ{}
	req.F_id = id
	ret := _call(packet.Pack(hub.Code["login_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, err := hub.PKT_LOGIN_ACK(reader)

	if err != nil || !tbl.F_success {
		return false
	}

	return true
}
Пример #6
0
func Logout(id int32) bool {
	defer _hub_err()
	req := protos.ID{}
	req.F_id = id
	ret := _call(packet.Pack(protos.Code["logout_req"], req, nil))
	reader := packet.Reader(ret)
	tbl, err := protos.PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		return false
	}

	return true
}
Пример #7
0
func AddUser(id int32) bool {
	defer _hub_err()
	req := ID{}
	req.F_id = id
	ret := _call(packet.Pack(Code["adduser_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, err := PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		NOTICE("HUB AddUser  return", false, "param", id)
		return false
	}

	return true
}
Пример #8
0
//---------------------------------------------------------- Forward IPCObject
func Forward(req *IPCObject) bool {
	defer _hub_err()
	// HUB protocol forwarding
	msg := FORWARDIPC{F_IPC: req.Json()}
	ret := _call(packet.Pack(Code["forward_req"], &msg, nil))
	reader := packet.Reader(ret)
	tbl, err := PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		ERR("HUB Forward return false", "param", req)
		return false
	}

	return true
}
Пример #9
0
func Logout(id int32) bool {
	defer _hub_err()
	req := ID{}
	req.F_id = id
	ret := _call(packet.Pack(Code["logout_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _ := PKT_INT(reader)

	if tbl.F_v == 0 {
		NOTICE("HUB Logout return  ", false, "param", id)
		return false
	}

	return true
}
Пример #10
0
func Protect(id int32, until time.Time) bool {
	defer _hub_err()

	req := hub.ID{}
	req.F_id = id
	ret := _call(packet.Pack(hub.Code["protect_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, err := hub.PKT_INT(reader)

	if err != nil || tbl.F_v == 0 {
		return false
	}

	return true
}
Пример #11
0
//------------------------------------------------ Stats Server Agent
func StatsAgent(incoming chan []byte, conn net.Conn) {
	queue_timer := make(chan int32, 1)
	queue_timer <- 1

	for {
		select {
		case sample := <-incoming:
			reader := packet.Reader(sample)
			HandleRequest(reader)
		case <-queue_timer:
			log.Println("============== STATS QUEUE SIZE:", len(incoming), "===================")
			timer.Add(1, time.Now().Unix()+PRINT_INTERVAL, queue_timer)
		}
	}
}
Пример #12
0
func Login(id int32) bool {
	defer _hub_err()
	req := LOGIN_REQ{}
	req.F_id = id
	ret := _call(packet.Pack(Code["login_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _ := PKT_LOGIN_ACK(reader)

	if tbl.F_success == 0 {
		NOTICE("HUB Login return  ", false, "param", id)
		return false
	}

	return true
}
Пример #13
0
func Protect(id int32, until int64) bool {
	defer _hub_err()

	req := PROTECT{}
	req.F_id = id
	req.F_protecttime = until
	ret := _call(packet.Pack(Code["protect_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _ := PKT_INT(reader)

	if tbl.F_v == 0 {
		NOTICE("HUB Protect return", false, "param", id, until)
		return false
	}

	return true
}
Пример #14
0
//---------------------------------------------------------- Hub processing
func HubAgent(incoming chan []byte, conn net.Conn) {
	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	hostid := atomic.AddInt32(&_host_genid, 1)
	// forward buffer
	forward := make(chan []byte, MAXCHAN)
	// output buffer
	output := make(chan []byte, MAXCHAN)

	protos.AddServer(hostid, forward)
	log.Printf("game server [id:%v] connected\n", hostid)

	go _write_routine(output, conn)

	defer func() {
		protos.RemoveServer(hostid)
		core.LogoutServer(hostid)
		close(forward)
		close(output)

		log.Printf("game server [id:%v] disconnected\n", hostid)
	}()

	for {
		select {
		case msg, ok := <-incoming: // from hub
			if !ok {
				return
			}

			reader := packet.Reader(msg)
			protos.HandleRequest(hostid, reader, output)
		case msg := <-forward: // send forward packet
			helper.SendChan(0, msg, output)
		}
	}

}
Пример #15
0
func GetInfo(id int32) (info Info, err error) {
	defer _hub_err()

	req := protos.ID{}
	req.F_id = id
	ret := _call(packet.Pack(protos.Code["getinfo_req"], req, nil))
	reader := packet.Reader(ret)
	tbl, _err := protos.PKT_INFO(reader)
	info.Id = tbl.F_id
	info.State = tbl.F_state
	info.Score = tbl.F_score
	info.Clan = tbl.F_clan
	info.ProtectTime = tbl.F_protecttime
	info.Name = tbl.F_name

	return info, _err
}
Пример #16
0
func GetList(A, B int32) (ids, scores []int32, err error) {
	defer _hub_err()

	req := protos.GETLIST{}
	req.F_A = A
	req.F_B = B
	ret := _call(packet.Pack(protos.Code["getlist_req"], req, nil))
	reader := packet.Reader(ret)
	tbl, _err := protos.PKT_LIST(reader)
	ids = make([]int32, len(ids))
	scores = make([]int32, len(scores))

	for k := range tbl.F_items {
		ids[k] = tbl.F_items[k].F_id
		scores[k] = tbl.F_items[k].F_score
	}

	return ids, scores, _err
}
Пример #17
0
func send_proto(conn net.Conn, p int16, info interface{}) (reader *packet.Packet) {
	seqid++
	payload := packet.Packet(p, info, nil)
	writer := packet.Writer()
	writer.WriteU16(uint16(len(payload)) + 4)

	w := packet.Writer()
	w.WriteU32(seqid)
	w.WriteRawBytes(payload)
	data := w.Data()
	if KEY_EXCHANGE {
		encoder.XORKeyStream(data, data)
	}
	writer.WriteRawBytes(data)
	conn.Write(writer.Data())
	log.Printf("send : %#v", writer.Data())
	time.Sleep(time.Second)

	//read
	header := make([]byte, 2)
	io.ReadFull(conn, header)
	size := binary.BigEndian.Uint16(header)
	log.Printf("read header: %v \n", size)
	r := make([]byte, size)
	_, err := io.ReadFull(conn, r)
	if err != nil {
		log.Println(err)
	}
	if KEY_EXCHANGE {
		decoder.XORKeyStream(r, r)
	}

	reader = packet.Reader(r)
	b, err := reader.ReadS16()
	if err != nil {
		log.Println(err)
	}
	if _, ok := RCode[b]; !ok {
		log.Println("unknown proto ", b)
	}

	return
}
Пример #18
0
//---------------------------------------------------------- HUB SERVICE
func StartAgent(incoming chan []byte, conn net.Conn) {
	hostid := atomic.AddInt32(&_host_genid, 1)
	log.Printf("game server [id:%v] connected\n", hostid)

	// forward queue (IPCObject)
	forward := make(chan IPCObject, 100000)
	protos.AddServer(hostid, forward)

	// closing
	defer func() {
		protos.RemoveServer(hostid)
		core.LogoutServer(hostid)
		close(forward)

		log.Printf("game server [id:%v] disconnected\n", hostid)
	}()

	for {
		select {
		case msg, ok := <-incoming: // request from game server
			if !ok {
				return
			}

			// read seqid
			reader := packet.Reader(msg)
			seqid, err := reader.ReadU32()
			if err != nil {
				log.Println("read SEQID failed.", err)
				return
			}

			// handle request
			ret := GSProxy(hostid, reader)
			// send result
			if len(ret) != 0 {
				_send(seqid, ret, conn)
			}
		case obj := <-forward: // forwarding packets(ie. seqid == 0)
			_send(0, obj.Json(), conn)
		}
	}
}
Пример #19
0
func parseRawMsg(data *[]byte, session *Session) *RawNetMsg {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("DECODE RAW MSG ERR: %p %v %v", session, data, err)
		}
	}()

	reader := packet.Reader(*data)
	api, err := reader.ReadS16()
	if err != nil {
		fmt.Printf("Get header fail: %v", data)
		return nil
	}

	return &RawNetMsg{
		Api:     api,
		Data:    *data,
		Session: session,
	}
}
Пример #20
0
func GetInfo(id int32) (info Info, flag bool) {
	defer _hub_err()

	req := hub.ID{}
	req.F_id = id
	ret := _call(packet.Pack(hub.Code["getinfo_req"], &req, nil))
	reader := packet.Reader(ret)
	tbl, _err := hub.PKT_INFO(reader)
	if _err == nil && tbl.F_flag {
		info.Id = tbl.F_id
		info.State = tbl.F_state
		info.Score = tbl.F_score
		info.ProtectTime = tbl.F_protecttime
		flag = true
		return
	}

	flag = false
	return
}
Пример #21
0
//------------------------------------------------ Hub processing
func HubAgent(incoming chan []byte, conn net.Conn) {
	hostid := atomic.AddInt32(&_host_genid, 1)
	forward := make(chan []byte)

	_server_lock.Lock()
	_servers[hostid] = forward // message chan for forwarding to client
	_server_lock.Unlock()

	log.Printf("server id:%v connected\n", hostid)

	defer func() {
		_server_lock.Lock()
		delete(_servers, hostid)
		_server_lock.Unlock()

		log.Printf("server id:%v disconnected\n", hostid)
	}()

	for {
		select {
		case msg, ok := <-incoming:
			if !ok {
				return
			}

			reader := packet.Reader(msg)
			seqid, err := reader.ReadU64() // read seqid
			if err != nil {
				log.Printf("Read Sequence Id failed.")
				continue
			}

			if result := HandleRequest(hostid, reader); result != nil {
				_send(seqid, result, conn)
			}
		case msg := <-forward:
			_send(0, msg, conn)
		}
	}

}
Пример #22
0
//----------------------------------------------------------- Event Server Agent
func EventAgent(incoming chan []byte, conn net.Conn) {
	// output buffer
	output := make(chan []byte, MAXCHAN)
	go _write_routine(output, conn)

	defer func() {
		close(output)
	}()

	for {
		select {
		case msg, ok := <-incoming:
			if !ok {
				return
			}

			reader := packet.Reader(msg)
			protos.HandleRequest(reader, output)
		}
	}
}
Пример #23
0
//----------------------------------------------- client protocol handle proxy
func UserRequestProxy(sess *Session, p []byte) []byte {
	defer _ProxyError()

	reader := packet.Reader(p)
	b, err := reader.ReadU16()

	if err != nil {
		log.Println("read protocol error")
	}

	proto_logger.Printf("code:%v,user:%v\n", b, sess.User.Id)

	handle := protos.ProtoHandler[b]
	if handle != nil {
		ret, err := handle(sess, reader)
		fmt.Println(ret)
		if err == nil {
			return ret
		}
	}

	return nil
}
Пример #24
0
//----------------------------------------------- client protocol handle proxy
func UserRequestProxy(sess *Session, p []byte) []byte {
	defer PrintPanicStack()
	now := time.Now()

	reader := packet.Reader(p)
	// read client_elapsed in milli-second since startup time-sync
	client_elapsed, err := reader.ReadU32()
	if err != nil {
		log.Println("Read timestamp failed.", err)
		return nil
	}

	// sampling latencies for cheat detection
	if sess.LoggedIn {
		server_elapsed := now.Sub(sess.ConnectTime).Nanoseconds() / 1000
		diff := int(server_elapsed - int64(client_elapsed))
		sess.LatencySamples.G.Add(diff)
	}

	// read protocol id
	b, err := reader.ReadU16()
	if err != nil {
		log.Println("read protocol error")
	}

	//log.Printf("code:%v\n", b)
	handle := ipc.ProtoHandler[b]
	if handle != nil {
		ret := handle(sess, reader)
		if len(ret) != 0 {
			return ret
		}
	}

	return nil
}
Пример #25
0
// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack(sess, p)
	// 解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		sess.Decoder.XORKeyStream(p, p)
	}
	// 封装为reader
	reader := packet.Reader(p)

	// 读客户端数据包序列号(1,2,3...)
	// 客户端发送的数据包必须包含一个自增的序号,必须严格递增
	// 加密后,可避免重放攻击-REPLAY-ATTACK
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 数据包序列号验证
	if seq_id != sess.PacketCount {
		log.Errorf("illegal packet sequence id:%v should be:%v size:%v", seq_id, sess.PacketCount, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 读协议号
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 根据协议号断做服务划分
	// 协议号的划分采用分割协议区间, 用户可以自定义多个区间,用于转发到不同的后端服务
	var ret []byte
	if b > MAX_PROTO_NUM {
		if err := forward(sess, p[4:]); err != nil {
			log.Errorf("service id:%v execute failed, error:%v", b, err)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else {
		if h := client_handler.Handlers[b]; h != nil {
			ret = h(sess, reader)
		} else {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	}

	// 监控协议处理时间
	// 监控数值会发送到statsd,格式为:
	// API.XXX_REQ = 10ms
	elasped := time.Now().Sub(start)
	if b != 0 { // 排除心跳包日志
		log.Trace("[REQ]", client_handler.RCode[b])
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, client_handler.RCode[b]), elasped)
	}
	return ret
}
Пример #26
0
// stream server
func (s *server) Stream(stream GameService_StreamServer) error {
	var sess Session
	ch_agent := s.recv(stream)
	ch_ipc := make(chan *Game_Frame, DEFAULT_CH_IPC_SIZE)

	defer func() {
		if sess.Flag&SESS_REGISTERED != 0 {
			// TODO: destroy session
			sess.Flag &^= SESS_REGISTERED
			registry.Unregister(sess.UserId)
		}
		log.Trace("stream end:", sess.UserId)
	}()

	// >> main message loop <<
	for {
		select {
		case frame, ok := <-ch_agent: // frames from agent
			if !ok { // EOF
				return nil
			}
			switch frame.Type {
			case Game_Message:
				// validation
				if sess.Flag&SESS_REGISTERED == 0 {
					log.Critical("user not registered")
					return ERROR_USER_NOT_REGISTERED
				}

				// locate handler by proto number
				reader := packet.Reader(frame.Message)
				c, err := reader.ReadS16()
				if err != nil {
					log.Critical(err)
					return err
				}
				handle := client_handler.Handlers[c]
				if handle == nil {
					log.Criticalf("service not bind: %v", c)
					return ERROR_SERVICE_NOT_BIND

				}

				// serialized processing, no future locks needed.
				// multiple agents can connect simutaneously to games
				var ret []byte
				wrap := func() { ret = handle(&sess, reader) }
				s.latch(wrap)

				// construct frame & return message from logic
				if ret != nil {
					if err := stream.Send(&Game_Frame{Type: Game_Message, Message: ret}); err != nil {
						log.Critical(err)
						return err
					}
				}

				// session control by logic
				if sess.Flag&SESS_KICKED_OUT != 0 { // logic kick out
					if err := stream.Send(&Game_Frame{Type: Game_Kick}); err != nil {
						log.Critical(err)
						return err
					}
					return nil
				}
			case Game_Register:
				if sess.Flag&SESS_REGISTERED == 0 {
					// TODO: create session
					sess.Flag |= SESS_REGISTERED
					sess.UserId = frame.UserId
					registry.Register(frame.UserId, ch_ipc)
					log.Trace("user registered")
				} else {
					log.Critical("user already registered")
				}
			case Game_Unregister:
				if sess.Flag&SESS_REGISTERED != 0 {
					// TODO: destroy session
					sess.Flag &^= SESS_REGISTERED
					registry.Unregister(sess.UserId)
					log.Trace("user unregistered")
				} else {
					log.Critical("user not registered")
				}
			case Game_Ping:
				if err := stream.Send(&Game_Frame{Type: Game_Ping, Message: frame.Message}); err != nil {
					log.Critical(err)
					return err
				}
				log.Trace("pinged")
			default:
				log.Criticalf("incorrect frame type: %v", frame.Type)
				return ERROR_INCORRECT_FRAME_TYPE
			}
		case frame := <-ch_ipc: // forward async messages from interprocess(goroutines) communication
			if err := stream.Send(frame); err != nil {
				log.Critical(err)
				return err
			}
		}
	}
}
Пример #27
0
// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack()
	//解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		//使用2组密钥匙, 增加破解难度
		sess.Decoder.XORKeyStream(p, p)
	}

	//封装成reader
	reader := packet.Reader(p)

	// 读客户端数据包序列号(1,2,3...)
	// 可避免重放攻击-REPLAY-ATTACK
	//数据包的前4个字节存放的是客户端的发包数量
	//客户端每次发包要包含第几次发包信息
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 数据包个数验证
	if seq_id != sess.PacketCount {
		//数据包真实长度是,总长度-4个字节的包个数长度-2个字节的协议号长度
		log.Errorf("illegal packet sequeue id:%v should be:%v size:%v", seq_id, sess.PacketCount, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 读协议号
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	//根据协议号段 做服务划分
	var ret []byte
	if b > MAX_PROTO_NUM {
		//去除4字节发包个数,将其余的向前传递
		if err := forward(sess, p[4:]); err != nil {
			log.Errorf("service id:%v execute failed, error:%v", b, err)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else {
		if h := client_handler.Handlers[b]; h != nil {
			ret = h(sess, reader)
		} else {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	}

	// 统计处理时间
	elasped := time.Now().Sub(start)
	if b != 0 { //排除心跳包日志
		log.Trace("[REQ]", client_handler.RCode[b])
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, client_handler.RCode[b]), elasped)
	}
	return ret
}
Пример #28
0
// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack(sess, p)
	// 解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		sess.Decoder.Codec(p)
	}

	// 封装为reader
	reader := packet.Reader(p)

	// 读客户端数据包序列号(1,2,3...)
	// 可避免重放攻击-REPLAY-ATTACK
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 读协议号
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 数据包序列号验证
	if seq_id != sess.PacketCount {
		log.Errorf("illegal packet sequence id:%v should be:%v proto:%v size:%v", seq_id, sess.PacketCount, b, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	var ret []byte
	if b > MAX_PROTO_NUM { // game协议
		// 透传
		ret, err = forward(sess, p)
		if err != nil {
			log.Errorf("service id:%v execute failed", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else { // agent保留协议段 [0, MAX_PROTO_NUM]
		// handle有效性检查
		h := client_handler.Handlers[b]
		if h == nil {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
		// 执行
		ret = h(sess, reader)
	}

	// 统计处理时间
	elasped := time.Now().Sub(start)
	if b != 0 { // 排除心跳包日志
		log.Trace("[REQ]", b)
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, b), elasped)
	}
	return ret
}
Пример #29
0
//----------------------------------------------- client protocol handle proxy
func UserRequestProxy(sess *Session, p []byte) []byte {
	defer PrintPanicStack()
	// decrypt
	if sess.Flag&SESS_ENCRYPT != 0 {
		sess.Decoder.Codec(p)
	}

	// encapsulate into reader
	reader := packet.Reader(p)

	// client timestamp check
	// mainly for REPLAY-ATTACK
	client_elapsed, err := reader.ReadU32()
	if err != nil {
		ERR("read client timestamp failed.", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	client_time := sess.ConnectTime.Unix() + int64(client_elapsed)/1000
	now := time.Now().Unix()
	if client_time > now+PACKET_ERROR || client_time < now-PACKET_EXPIRE {
		ERR("client timestamp is illegal.", client_elapsed, client_time, now)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// read protocol number
	b, err := reader.ReadS16()
	if err != nil {
		ERR("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// handle validation
	handle := net.ProtoHandler[b]
	if handle == nil {
		ERR("service id", b, "not bind")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// before HOOK
	if !_before_hook(sess, b) {
		ERR("before hook failed, code", b)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// handle packet
	start := time.Now()
	ret := handle(sess, reader)
	end := time.Now()

	uid := int32(-1)
	name := ""
	if sess.Flag&SESS_LOGGED_IN != 0 {
		uid = sess.User.Id
		name = sess.User.Name
	}

	log.Printf("\033[0;36m[REQ] %v\tbytes[in:%v out:%v seq:%v]\tusr:[%v %v]\ttime:%v\033[0m\n", net.RCode[b], len(p)-6, len(ret), sess.PacketCount, uid, name, end.Sub(start))
	// after HOOK
	_after_hook(sess, net.RCode[b])
	sess.MarkDirty()
	return ret
}
Пример #30
0
//----------------------------------------------- receive message from hub
func HubReceiver(conn net.Conn) {
	defer conn.Close()

	header := make([]byte, 2)
	seq_id := make([]byte, 8)

	for {
		// header
		n, err := io.ReadFull(conn, header)
		if n == 0 && err == io.EOF {
			break
		} else if err != nil {
			log.Println("error receving header:", err)
			break
		}

		// packet seq_id uint32
		n, err = io.ReadFull(conn, seq_id)
		if n == 0 && err == io.EOF {
			break
		} else if err != nil {
			log.Println("error receving seq_id:", err)
			break
		}

		seqval := uint64(0)

		for k, v := range seq_id {
			seqval |= uint64(v) << uint((7-k)*8)
		}

		// data
		size := int(header[0])<<8 | int(header[1]) - 8
		data := make([]byte, size)
		n, err = io.ReadFull(conn, data)

		if err != nil {
			log.Println("error receving msg:", err)
			break
		}

		if seqval == 0 { // packet forwarding, deliver to MQ
			reader := packet.Reader(data)
			forward_id, err := reader.ReadS32()
			if err != nil {
				log.Println("packet forwarding error")
				goto L
			}

			sess := Query(forward_id)
			if sess == nil {
				log.Println("forward failed, maybe user is offline?")
			} else {
				func() {
					defer func() {
						if x := recover(); x != nil {
							log.Println("forward to MQ failed, the user is so lucky")
						}
					}()
					sess.MQ <- data[reader.Pos():] // the payload is the message
				}()
			}
		} else {
			_wait_ack_lock.Lock()
			if ack, ok := _wait_ack[seqval]; ok {
				ack <- data
				delete(_wait_ack, seqval)
			} else {
				log.Println("Illegal packet sequence number from HUB")
			}
			_wait_ack_lock.Unlock()
		}
	L:
	}
}