Example #1
0
File: main.go Project: hycxa/gonet
func stats_sender() {
	_accum_buffer := make(map[string]map[string]int32)
	_update_buffer := make(map[string]map[string]string)

	stats_timer := make(chan int32, 100)
	stats_timer <- 1
	for {
		select {
		case req := <-AccumQueue:
			if _, ok := _accum_buffer[req.F_lang]; !ok {
				val := make(map[string]int32)
				val[req.F_key] = 0
				_accum_buffer[req.F_lang] = val
			}
			val := _accum_buffer[req.F_lang]
			val[req.F_key] += req.F_value
			_accum_buffer[req.F_lang] = val
		case req := <-UpdateQueue:
			if _, ok := _update_buffer[req.F_lang]; !ok {
				val := make(map[string]string)
				val[req.F_key] = ""
				_update_buffer[req.F_lang] = val
			}
			val := _update_buffer[req.F_lang]
			val[req.F_key] = req.F_value
			_update_buffer[req.F_lang] = val
		case <-stats_timer:
			INFO("Stats Buffer:", len(_accum_buffer), len(_update_buffer))
			// 累计
			accum := SET_ADDS_REQ{}
			for accum.F_lang, _ = range _accum_buffer {
				for accum.F_key, accum.F_value = range _accum_buffer[accum.F_lang] {
					Send(packet.Pack(Code["set_adds_req"], &accum, nil))
				}
			}
			_accum_buffer = make(map[string]map[string]int32)

			// 更新
			update := SET_UPDATE_REQ{}
			for update.F_lang, _ = range _update_buffer {
				for update.F_key, update.F_value = range _update_buffer[update.F_lang] {
					Send(packet.Pack(Code["set_update_req"], &update, nil))
				}
			}
			_update_buffer = make(map[string]map[string]string)

			// FINI
			config := cfg.Get()
			period := STATS_COLLECT_PERIOD
			if config["stats_collect_period"] != "" {
				period, _ = strconv.Atoi(config["stats_collect_period"])
			}

			timer.Add(0, time.Now().Unix()+int64(period), stats_timer)
			runtime.GC()
		}
	}
}
Example #2
0
func (gs *centerGs) SendToUser(userId int64, api int16, tbl interface{}) {
	payload := packet.Pack(api, tbl, nil)
	msg := protocol.PKT_forward_msg_info{
		F_size:       int32(len(payload)),
		F_session_id: protocol.NIL_SESSION_ID,
		F_user_id:    userId,
		F_msg:        string(payload),
	}
	gs.session.Send(packet.Pack(protocol.FORWARD_MSG_NTF, &msg, nil))
}
Example #3
0
// 发送公会广播信息(通过Gate广播,所以这条转发消息发给任意GS都可以)。
func AllianceBoardCast(asId int32, api int16, tbl interface{}) {
	payload := packet.Pack(api, tbl, nil)
	for _, gs := range gsMap {
		msg := protocol.PKT_gs_alliance_boardcast_info{
			F_alliance_id: asId,
			F_msg:         string(payload),
		}
		gs.session.Send(packet.Pack(protocol.GS_ALLIANCE_BOARDCAST_NTF,
			&msg, nil))
		return
	}
}
func BenchmarkAgent(b *testing.B) {
	fmt.Println("Benchmark", b.N)
	for i := 0; i < b.N; i++ {
		addr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:8888")
		if err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}

		conn, err := net.DialTCP("tcp", nil, addr)
		if err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}

		U := user_login_info{}
		U.F_user_name = fmt.Sprintf("test%v", i)
		U.F_mac_addr = fmt.Sprintf("mac%v", i)

		pkt := packet.Pack(Code["user_login_req"], &U, nil)

		writer := packet.Writer()
		writer.WriteU16(uint16(len(pkt) + 4))
		writer.WriteU32(0)
		writer.WriteRawBytes(pkt)
		ret := make([]byte, 100)

		conn.Write(writer.Data())
		conn.Read(ret)
	}
}
Example #5
0
func P_forward_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_FORWARDIPC(pkt)

	object := &IPCObject{}
	err := json.Unmarshal(tbl.F_IPC, object)

	if err != nil {
		log.Println("decode forward IPCObject error")
		return nil
	}

	// if user is online, send to the server, or else send to database
	state := core.State(object.DestID)

	//fmt.Println(tbl.F_dest_id, tbl.F_IPC)
	switch state {
	case core.ON_PROT, core.ON_FREE:
		host := core.Host(object.DestID)

		ch := ForwardChan(host)

		if ch != nil {
			ch <- tbl.F_IPC
		} else {
			forward_tbl.Push(object)
		}
	default:
		forward_tbl.Push(object)
	}

	ret := INT{F_v: 1}
	return packet.Pack(-1, &ret, nil)
}
Example #6
0
func P_rank_list_req(sess *Session, reader *packet.Packet) (ret []byte, err error) {
	ids, scores, err := ipc.GetList(1, -1)

	if err != nil {
		return nil, err
	}

	out := rank_list{}
	out.F_items = make([]rank_list_item, len(ids))

	for k, v := range ids {
		info, _ := ipc.GetInfo(v)
		out.F_items[k].F_id = v
		out.F_items[k].F_name = info.Name
		out.F_items[k].F_rank = scores[k]
		out.F_items[k].F_state = info.State

		t := int32(info.ProtectTime - time.Now().Unix())
		if t > 0 {
			out.F_items[k].F_protect_time = int32(t)
		} else {
			out.F_items[k].F_protect_time = 0
		}
	}

	writer := packet.Writer()
	return packet.Pack(Code["rank_list_ack"], out, writer), nil
}
Example #7
0
func P_cancel_req(reader *packet.Packet) []byte {
	tbl, _ := PKT_CANCEL_EVENT(reader)
	core.Cancel(tbl.F_event_id)
	ret := INT{1}

	return packet.Pack(-1, &ret, nil)
}
Example #8
0
func P_add_req(reader *packet.Packet) []byte {
	tbl, _ := PKT_ADD_EVENT(reader)
	event_id := core.Add(tbl.F_type, tbl.F_user_id, tbl.F_timeout, tbl.F_params)
	ret := INT{event_id}

	return packet.Pack(-1, &ret, nil)
}
Example #9
0
// 密钥交换
func P_get_seed_req(sess *Session, reader *packet.Packet) []byte {
	tbl, _ := PKT_seed_info(reader)
	// KEY1
	X1, E1 := dh.DHExchange()
	KEY1 := dh.DHKey(X1, big.NewInt(int64(tbl.F_client_send_seed)))

	// KEY2
	X2, E2 := dh.DHExchange()
	KEY2 := dh.DHKey(X2, big.NewInt(int64(tbl.F_client_receive_seed)))

	ret := seed_info{int32(E1.Int64()), int32(E2.Int64())}
	// 服务器加密种子是客户端解密种子
	encoder, err := rc4.NewCipher([]byte(fmt.Sprintf("%v%v", SALT, KEY2)))
	if err != nil {
		log.Critical(err)
		return nil
	}
	decoder, err := rc4.NewCipher([]byte(fmt.Sprintf("%v%v", SALT, KEY1)))
	if err != nil {
		log.Critical(err)
		return nil
	}
	sess.Encoder = encoder
	sess.Decoder = decoder
	sess.Flag |= SESS_KEYEXCG
	return packet.Pack(Code["get_seed_ack"], ret, nil)
}
Example #10
0
func P_add_req(reader *packet.Packet) []byte {
	tbl, _ := PKT_ADD_REQ(reader)
	ret := INT{0}

	fmt.Println(tbl)
	return packet.Pack(-1, &ret, nil)
}
Example #11
0
func P_user_login_req(sess *Session, reader *packet.Packet) (ret []byte, err error) {
	tbl, _ := PKT_user_login_info(reader)
	writer := packet.Writer()
	failed := command_result_pack{F_rst: 0}
	success := user_snapshot{}
	//------------------------------------------------

	config := cfg.Get()
	version, _ := strconv.Atoi(config["version"])

	if tbl.F_client_version != int32(version) {
		ret = packet.Pack(Code["user_login_faild_ack"], failed, writer)
		return
	}

	if tbl.F_new_user == 0 {
		if user_tbl.LoginMAC(sess.User.Mac, &sess.User) {
			ipc.Register(sess, sess.User.Id)
			_fill_user_snapshot(&sess.User, &success)
			ret = packet.Pack(Code["user_login_succeed_ack"], success, writer)
			return
		} else {
			ret = packet.Pack(Code["user_login_faild_ack"], failed, writer)
			return
		}
	} else {
		// register to db & online user
		sess.User.Name = tbl.F_user_name
		sess.User.Mac = tbl.F_mac_addr
		sess.User.CreatedAt = time.Now()

		if user_tbl.New(&sess.User) {
			ipc.Register(sess, sess.User.Id)
			// TODO: add user
			//ranklist.AddUser(&sess.User)
			_fill_user_snapshot(&sess.User, &success)
			ret = packet.Pack(Code["user_login_succeed_ack"], success, writer)
			return
		} else {
			ret = packet.Pack(Code["user_login_faild_ack"], failed, writer)
			return
		}
	}

	return
}
func TestAgent(t *testing.T) {
	log.Println("Connecting to GS")
	addr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	conn, err := net.DialTCP("tcp", nil, addr)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	U := &user_login_info{}
	U.F_user_name = "test1"
	U.F_mac_addr = "mac1"
	pkt := packet.Pack(Code["user_login_req"], U, nil)

	writer := packet.Writer()
	writer.WriteU16(uint16(len(pkt) + 4))
	writer.WriteU32(0)
	writer.WriteRawBytes(pkt)

	conn.Write(writer.Data())

	ret := make([]byte, 100)
	n, _ := conn.Read(ret)
	fmt.Printf("%q\n", ret[:n])

	// talk
	msg := &talk{}
	msg.F_user = "******"
	msg.F_msg = "hello world"
	pkt = packet.Pack(Code["talk_req"], msg, nil)

	writer = packet.Writer()
	writer.WriteU16(uint16(len(pkt) + 4))
	writer.WriteU32(0)
	writer.WriteRawBytes(pkt)

	conn.Write(writer.Data())
	n, _ = conn.Read(ret)
	fmt.Printf("%q\n", ret[:n])
}
Example #13
0
func P_changescore_req(hostid int32, pkt *packet.Packet) ([]byte, error) {
	tbl, _ := PKT_CHGSCORE(pkt)
	ret := INT{F_v: 0}

	if ranklist.ChangeScore(tbl.F_id, tbl.F_oldscore, tbl.F_newscore) {
		ret.F_v = 1
	}

	return packet.Pack(Code["changescore_ack"], ret, nil), nil
}
Example #14
0
func P_logout_req(hostid int32, pkt *packet.Packet) ([]byte, error) {
	tbl, _ := PKT_ID(pkt)
	ret := INT{F_v: 0}

	if ranklist.Logout(tbl.F_id) {
		ret.F_v = 1
	}

	return packet.Pack(Code["logout_ack"], ret, nil), nil
}
func IPC_talk(sess *Session, obj *IPCObject) []byte {
	var str string
	err := json.Unmarshal(obj.Object, &str)
	if err == nil {
		ret := &talk{F_user: sess.User.Name, F_msg: str}
		return packet.Pack(Code["talk_notify"], ret, nil)
	}

	return nil
}
Example #16
0
func send_proto(conn net.Conn, p int16, info interface{}) {
	seqid++
	payload := packet.Pack(p, info, nil)
	writer := packet.Writer()
	writer.WriteU16(uint16(len(payload)) + 4)
	writer.WriteU32(seqid)
	writer.WriteRawBytes(payload)
	conn.Write(writer.Data())
	time.Sleep(time.Second)
}
Example #17
0
func P_free_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_ID(pkt)
	ret := INT{F_v: 0}

	if core.Free(tbl.F_id) {
		ret.F_v = 1
	}

	return packet.Pack(-1, &ret, nil)
}
Example #18
0
func P_protect_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_PROTECT(pkt)
	ret := INT{F_v: 0}

	if core.Protect(tbl.F_id, tbl.F_protecttime) {
		ret.F_v = 1
	}

	return packet.Pack(-1, &ret, nil)
}
Example #19
0
func P_changescore_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_CHGSCORE(pkt)
	ret := INT{F_v: 0}

	if core.UpdateScore(tbl.F_id, tbl.F_oldscore, tbl.F_newscore) {
		ret.F_v = 1
	}

	return packet.Pack(-1, &ret, nil)
}
Example #20
0
func P_atk_monster_req(sess *Session, reader *packet.Packet) (ret []byte, err error) {
	tbl, _ := PKT_command_id_pack(reader)
	writer := packet.Writer()
	payload := command_result_pack{}

	//
	println(tbl.F_id)
	ret = packet.Pack(Code["atk_monster_ack"], payload, writer)
	return
}
Example #21
0
func P_login_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_LOGIN_REQ(pkt)
	ret := LOGIN_ACK{F_success: 0}

	if core.Login(tbl.F_id, hostid) {
		ret.F_success = 1
	}

	return packet.Pack(-1, &ret, nil)
}
Example #22
0
func P_adduser_req(hostid int32, pkt *packet.Packet) []byte {
	tbl, _ := PKT_ID(pkt)
	ret := INT{F_v: 0}

	if core.LoadUser(tbl.F_id) {
		core.Login(tbl.F_id, hostid)
		ret.F_v = 1
	}

	return packet.Pack(-1, &ret, nil)
}
Example #23
0
func Ping() bool {
	defer _hub_err()
	req := INT{}
	req.F_v = 1
	ret := _call(packet.Pack(Code["ping_req"], &req, nil))
	if ret == nil {
		ERR("HUB Ping return", false)
		return false
	}
	return true
}
Example #24
0
func P_key_exchange_req(sess *Session, reader *packet.Packet) []byte {
	tbl, _ := PKT_KEY(reader)
	A := big.NewInt(int64(tbl.F_E))
	secret, B := diffie.DHGenKey(diffie.DH1BASE, diffie.DH1PRIME)

	key := big.NewInt(0).Exp(A, secret, diffie.DH1PRIME)
	sess.Crypto = pike.NewCtx(uint32(key.Uint64()))

	ret := KEY{int32(B.Uint64())}
	return packet.Pack(Code["key_exchange_ack"], &ret, nil)
}
Example #25
0
func P_user_login_req(sess *Session, reader *packet.Packet) []byte {
	tbl, _ := PKT_user_login_info(reader)
	ret := command_result_pack{}

	if user := user_tbl.LoginMac(tbl.F_user_name, tbl.F_mac_addr); user != nil {
		sess.User = user
		AI.LoginProc(sess)
	}

	return packet.Pack(Code["user_login_succeed_ack"], &ret, nil)
}
Example #26
0
func P_getinfo_req(hostid int32, pkt *packet.Packet) ([]byte, error) {
	tbl, _ := PKT_ID(pkt)
	ret := INFO{}
	ret.F_id = tbl.F_id
	ret.F_state = ranklist.State(tbl.F_id)
	ret.F_score = ranklist.Score(tbl.F_id)
	ret.F_clan = ranklist.Score(tbl.F_id)
	ret.F_protecttime = ranklist.ProtectTime(tbl.F_id)
	ret.F_name = ranklist.Name(tbl.F_id)
	return packet.Pack(Code["getinfo_ack"], ret, nil), nil
}
Example #27
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
}
Example #28
0
func P_atk_player_req(sess *Session, reader *packet.Packet) (ret []byte, err error) {
	tbl, _ := PKT_command_id_pack(reader)
	writer := packet.Writer()
	success := user_snapshot{}
	failed := command_result_pack{}

	if ipc.Raid(tbl.F_id) {
		opponent, e := user_tbl.Load(tbl.F_id)
		if e == nil {
			_fill_user_snapshot(&opponent, &success)
			ret = packet.Pack(Code["atk_player_succeed_ack"], success, writer)
			return
		}
	}

	//
	info, err := ipc.GetInfo(tbl.F_id)
	failed.F_rst = info.Id
	ret = packet.Pack(Code["atk_player_faild_ack"], failed, writer)
	return
}
Example #29
0
// 玩家登陆过程
func P_user_login_req(sess *Session, reader *packet.Packet) []byte {
	// TODO: 登陆鉴权
	sess.UserId = 1

	// TODO: 选择登陆服务器
	sess.GSID = DEFAULT_GSID

	// 选服
	cli, err := sp.GetServiceWithId(sp.SERVICE_GAME, sess.GSID)
	if err != nil {
		log.Critical(err)
		return nil
	}

	// type assertion
	game_cli, ok := cli.(spp.GameServiceClient)
	if !ok {
		log.Critical("cannot do type assertion on: %v", sess.GSID)
		return nil
	}

	// 开启到游戏服的流
	// TODO: 处理context,设定超时
	stream, err := game_cli.Stream(context.Background())
	if err != nil {
		log.Critical(err)
		return nil
	}
	sess.Stream = stream

	// 在game注册
	// TODO: 新用户的创建由game处理
	sess.Stream.Send(&spp.Game_Frame{Type: spp.Game_Register, UserId: sess.UserId})

	// 读取GAME返回消息
	fetcher_task := func(sess *Session) {
		for {
			in, err := sess.Stream.Recv()
			if err == io.EOF { // 流关闭
				log.Trace(err)
				return
			}
			if err != nil {
				log.Error(err)
				return
			}
			sess.MQ <- *in
		}
	}
	go fetcher_task(sess)
	return packet.Pack(Code["user_login_ack"], user_snapshot{F_uid: sess.UserId}, nil)
}
Example #30
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
}