Gogs 4 tháng trước cách đây
mục cha
commit
67bf0c9a09

+ 3 - 0
bin/client_msg/common.proto

@@ -65,6 +65,7 @@ message TeenPattiRoomList {
 }
 }
 
 
 message TeenPattiRoom {
 message TeenPattiRoom {
+  
   string boot = 1; //0.1
   string boot = 1; //0.1
   string minBuyin = 2; // 1
   string minBuyin = 2; // 1
   string chaalLimmit = 3; // 12.8
   string chaalLimmit = 3; // 12.8
@@ -72,6 +73,7 @@ message TeenPattiRoom {
   string totalPlayers = 5; // 3999
   string totalPlayers = 5; // 3999
   string roomLevel = 6; //low - mid - high
   string roomLevel = 6; //low - mid - high
   string roomId = 7;
   string roomId = 7;
+  string type = 8; 
 }
 }
 
 
 // 通知客户端发牌
 // 通知客户端发牌
@@ -121,6 +123,7 @@ message ReqRound {
     string userId = 4;
     string userId = 4;
 }
 }
 
 
+
 //error
 //error
 message MsgError {
 message MsgError {
   int32 error_code = 1;
   int32 error_code = 1;

+ 1 - 1
bin/conf/server.json

@@ -1,6 +1,6 @@
 {
 {
 	"LogLevel": "debug",
 	"LogLevel": "debug",
 	"LogPath": "/home/zjh/teen_patti/bin/log",
 	"LogPath": "/home/zjh/teen_patti/bin/log",
-	"WSAddr": "0.0.0.0:8080",
+	"WSAddr": "0.0.0.0:3653",
 	"MaxConnNum": 20000
 	"MaxConnNum": 20000
 }
 }

+ 87 - 0
src/server/datacenter/usercenterd.go

@@ -0,0 +1,87 @@
+package usercenter
+
+import (
+	"log"
+	"server/models"
+	"sync"
+	"time"
+)
+
+type UserCenter struct {
+	activeCache sync.Map // 当前正在使用的主缓存
+	backupCache sync.Map // 刷新期间使用的备用缓存
+	mu          sync.Mutex
+}
+
+func NewUserCenter() *UserCenter {
+	return &UserCenter{}
+}
+
+// LoadThreeDayUsers 分页加载最近三天登录的用户到备用缓存
+func (uc *UserCenter) LoadThreeDayUsers() error {
+	const batchSize = 1000 // 每次加载1000条记录
+	skip := 0
+
+	// 清空备用缓存
+	uc.backupCache = sync.Map{}
+
+	for {
+		users, err := models.GetThreeDayUsersWithPagination(skip, batchSize)
+		if err != nil {
+			return err
+		}
+
+		// 如果没有更多用户,跳出循环
+		if len(users) == 0 {
+			break
+		}
+
+		// 将用户数据存入备用缓存
+		for _, user := range users {
+			uc.backupCache.Store(user.UserID, user)
+		}
+
+		skip += batchSize
+	}
+
+	log.Println("User data loaded into backup cache")
+	return nil
+}
+
+// SwitchCache 切换主缓存与备用缓存
+func (uc *UserCenter) SwitchCache() {
+	uc.mu.Lock()
+	defer uc.mu.Unlock()
+
+	// 用备用缓存替换主缓存
+	uc.activeCache, uc.backupCache = uc.backupCache, sync.Map{}
+	log.Println("Cache switched successfully")
+}
+
+// GetUserFromCache 从主缓存中获取用户
+func (uc *UserCenter) GetUserFromCache(userID int64) (*models.User, bool) {
+	value, ok := uc.activeCache.Load(userID)
+	if !ok {
+		return nil, false
+	}
+	user, ok := value.(models.User)
+	return &user, ok
+}
+
+// StartAutoRefresh 定期刷新备用缓存并切换
+func (uc *UserCenter) StartAutoRefresh(interval time.Duration) {
+	go func() {
+		ticker := time.NewTicker(interval)
+		defer ticker.Stop()
+
+		for range ticker.C {
+			log.Println("Starting to refresh user cache...")
+			err := uc.LoadThreeDayUsers()
+			if err != nil {
+				log.Printf("Failed to refresh user cache: %v", err)
+				continue
+			}
+			uc.SwitchCache() // 切换缓存
+		}
+	}()
+}

+ 1 - 1
src/server/game/internal/chanrpc.go

@@ -44,7 +44,7 @@ func rpcCloseAgent(args []interface{}) {
 // 处理认证消息
 // 处理认证消息
 func handleAuth(args []interface{}) {
 func handleAuth(args []interface{}) {
 	// 收到的登录消息
 	// 收到的登录消息
-	m := args[0].(*msg.ReqLogin)
+	m := args[0].(*msg.ResLogin)
 	// 消息的发送者
 	// 消息的发送者
 	a := args[1].(gate.Agent)
 	a := args[1].(gate.Agent)
 
 

+ 0 - 17
src/server/game/internal/handler.go

@@ -10,8 +10,6 @@ import (
 )
 )
 
 
 func init() {
 func init() {
-	// 向当前模块(game 模块)注册 Hello 消息的消息处理函数 handleHello
-	Handler(&msg.Hello{}, handleHello)
 	Handler(&msg.ResPlayerOptAction{}, handlePlayerOptAction)
 	Handler(&msg.ResPlayerOptAction{}, handlePlayerOptAction)
 }
 }
 
 
@@ -32,18 +30,3 @@ func handlePlayerOptAction(args []interface{}) {
 		}
 		}
 	}
 	}
 }
 }
-
-func handleHello(args []interface{}) {
-	// 收到的 Hello 消息
-	m := args[0].(*msg.Hello)
-	// 消息的发送者
-	a := args[1].(gate.Agent)
-
-	// 输出收到的消息的内容
-	log.Debug("hello %v", m.Name)
-
-	// 给发送者回应一个 Hello 消息
-	a.WriteMsg(&msg.Hello{
-		Name: "client",
-	})
-}

+ 8 - 2
src/server/game/teen/teen.go

@@ -21,10 +21,11 @@ type TeenPattiRoom struct {
 	TotalPlayers string `json:"totalPlayers"`
 	TotalPlayers string `json:"totalPlayers"`
 	RoomLevel    string `json:"roomLevel"`
 	RoomLevel    string `json:"roomLevel"`
 	RoomId       string `json:"roomId"`
 	RoomId       string `json:"roomId"`
+	Type         string `json:"type"`
 }
 }
 
 
 var GameConfig struct {
 var GameConfig struct {
-	GameId    int             `json:"game_id"`
+	GameId    string          `json:"game_id"`
 	Name      string          `json:"name"`
 	Name      string          `json:"name"`
 	Status    int             `json:"status"`
 	Status    int             `json:"status"`
 	RoomList  []TeenPattiRoom `json:"room_list"`
 	RoomList  []TeenPattiRoom `json:"room_list"`
@@ -37,8 +38,11 @@ var GameConfig struct {
 // 	Status:  1,
 // 	Status:  1,
 // }
 // }
 
 
+func InitGame() {
+
+}
 func init() {
 func init() {
-	data, err := os.ReadFile("../../../bin/gamedata/teen_patti_conf.json")
+	data, err := os.ReadFile("../../bin/gamedata/teen_patti_conf.json")
 	if err != nil {
 	if err != nil {
 		log.Fatal("%v", err)
 		log.Fatal("%v", err)
 	}
 	}
@@ -88,6 +92,7 @@ func startGame(userId string, roomId string, agent gate.Agent) {
 		RoomId: roomId,
 		RoomId: roomId,
 		GameId: "teen_patti",
 		GameId: "teen_patti",
 	})
 	})
+
 }
 }
 
 
 func convertToMsgRoomList(rooms []TeenPattiRoom) *msg.TeenPattiRoomList {
 func convertToMsgRoomList(rooms []TeenPattiRoom) *msg.TeenPattiRoomList {
@@ -101,6 +106,7 @@ func convertToMsgRoomList(rooms []TeenPattiRoom) *msg.TeenPattiRoomList {
 			TotalPlayers: room.TotalPlayers,
 			TotalPlayers: room.TotalPlayers,
 			RoomLevel:    room.RoomLevel,
 			RoomLevel:    room.RoomLevel,
 			RoomId:       room.RoomId,
 			RoomId:       room.RoomId,
+			Type:         room.Type,
 		}
 		}
 	}
 	}
 	return &msg.TeenPattiRoomList{
 	return &msg.TeenPattiRoomList{

+ 3 - 1
src/server/gate/router.go

@@ -2,11 +2,13 @@ package gate
 
 
 import (
 import (
 	"server/game"
 	"server/game"
+	"server/hall"
 	"server/login"
 	"server/login"
 	"server/msg"
 	"server/msg"
 )
 )
 
 
 func init() {
 func init() {
 	msg.Processor.SetRouter(&msg.Hello{}, game.ChanRPC)
 	msg.Processor.SetRouter(&msg.Hello{}, game.ChanRPC)
-	msg.Processor.SetRouter(&msg.ReqLogin{}, login.ChanRPC)
+	msg.Processor.SetRouter(&msg.ResLogin{}, login.ChanRPC)
+	msg.Processor.SetRouter(&msg.ResGameInfo{}, hall.ChanRPC)
 }
 }

+ 4 - 3
src/server/hall/internal/handler.go

@@ -20,13 +20,14 @@ func init() {
 	handleMsg(&msg.ResJoinRoom{}, joinRoomHandler)
 	handleMsg(&msg.ResJoinRoom{}, joinRoomHandler)
 	handleMsg(&msg.PlayList{}, playListHandler)
 	handleMsg(&msg.PlayList{}, playListHandler)
 	handleMsg(&msg.Shop{}, shopHandler)
 	handleMsg(&msg.Shop{}, shopHandler)
-	handleMsg(&msg.ReqGameInfo{}, reqGameInfoHandler)
+	handleMsg(&msg.ResGameInfo{}, reqGameInfoHandler)
 }
 }
 
 
 func reqGameInfoHandler(args []interface{}) {
 func reqGameInfoHandler(args []interface{}) {
-	m := args[0].(*msg.ReqGameInfo)
+	m := args[0].(*msg.ResGameInfo)
 	a := args[1].(gate.Agent)
 	a := args[1].(gate.Agent)
-
+	// log.Debug("reqGameInfoHandler, msg: %v, agent: %v", m, a)
+	log.Debug("reqGameInfoHandler, msg: %+v, agent: %+v", m, a)
 	switch m.GameId {
 	switch m.GameId {
 	case "teen_patti":
 	case "teen_patti":
 		events.EventChan <- events.Event{
 		events.EventChan <- events.Event{

+ 2 - 2
src/server/login/internal/handler.go

@@ -14,12 +14,12 @@ func handleMsg(m interface{}, h interface{}) {
 }
 }
 
 
 func init() {
 func init() {
-	handleMsg(&msg.ReqLogin{}, loginHandler)
+	handleMsg(&msg.ResLogin{}, loginHandler)
 }
 }
 
 
 func loginHandler(args []interface{}) {
 func loginHandler(args []interface{}) {
 	// agent := args[1].(gate.Agent)
 	// agent := args[1].(gate.Agent)
-	m := args[0].(*msg.ReqLogin)
+	m := args[0].(*msg.ResLogin)
 	// 消息的发送者
 	// 消息的发送者
 	a := args[1].(gate.Agent)
 	a := args[1].(gate.Agent)
 
 

+ 5 - 0
src/server/main.go

@@ -6,6 +6,9 @@ import (
 	"server/gate"
 	"server/gate"
 	"server/login"
 	"server/login"
 
 
+	"server/game/teen"
+	"server/hall"
+
 	"github.com/name5566/leaf"
 	"github.com/name5566/leaf"
 	lconf "github.com/name5566/leaf/conf"
 	lconf "github.com/name5566/leaf/conf"
 )
 )
@@ -17,9 +20,11 @@ func main() {
 	lconf.ConsolePort = conf.Server.ConsolePort
 	lconf.ConsolePort = conf.Server.ConsolePort
 	lconf.ProfilePath = conf.Server.ProfilePath
 	lconf.ProfilePath = conf.Server.ProfilePath
 
 
+	teen.InitGame()
 	leaf.Run(
 	leaf.Run(
 		game.Module,
 		game.Module,
 		gate.Module,
 		gate.Module,
 		login.Module,
 		login.Module,
+		hall.Module,
 	)
 	)
 }
 }

+ 1 - 0
src/server/models/game.model.go

@@ -0,0 +1 @@
+package models

+ 46 - 0
src/server/models/user.model.go

@@ -0,0 +1,46 @@
+package models
+
+import (
+	"server/conf"
+	mongodbmgr "server/db/mongodb"
+	"time"
+
+	"gopkg.in/mgo.v2/bson"
+)
+
+// 定义用户集合操作
+var userCollection = mongodbmgr.NewCollection(conf.MongoDBName, "users")
+
+// 用户模型
+type User struct {
+	UserID    int64     `bson:"user_id"`
+	Name      string    `bson:"name"`
+	Password  string    `bson:"password"`
+	LastLogin time.Time `bson:"last_login"`
+}
+
+// 获取最近三天有登录的用户,支持分页
+func GetThreeDayUsersWithPagination(skip, limit int) ([]User, error) {
+	var users []User
+	threeDaysAgo := time.Now().AddDate(0, 0, -3)
+	err := userCollection.FindMany(
+		bson.M{"last_login": bson.M{"$gte": threeDaysAgo}},
+		skip,
+		limit,
+		&users,
+	)
+	if err != nil {
+		return nil, err
+	}
+	return users, nil
+}
+
+// 根据用户ID获取用户信息
+func GetUserByID(userID int64) (*User, error) {
+	var user User
+	err := userCollection.FindOne(bson.M{"user_id": userID}, &user)
+	if err != nil {
+		return nil, err
+	}
+	return &user, nil
+}

+ 56 - 47
src/server/msg/common.pb.go

@@ -715,6 +715,7 @@ type TeenPattiRoom struct {
 	TotalPlayers string `protobuf:"bytes,5,opt,name=totalPlayers,proto3" json:"totalPlayers,omitempty"` // 3999
 	TotalPlayers string `protobuf:"bytes,5,opt,name=totalPlayers,proto3" json:"totalPlayers,omitempty"` // 3999
 	RoomLevel    string `protobuf:"bytes,6,opt,name=roomLevel,proto3" json:"roomLevel,omitempty"`       //low - mid - high
 	RoomLevel    string `protobuf:"bytes,6,opt,name=roomLevel,proto3" json:"roomLevel,omitempty"`       //low - mid - high
 	RoomId       string `protobuf:"bytes,7,opt,name=roomId,proto3" json:"roomId,omitempty"`
 	RoomId       string `protobuf:"bytes,7,opt,name=roomId,proto3" json:"roomId,omitempty"`
+	Type         string `protobuf:"bytes,8,opt,name=type,proto3" json:"type,omitempty"`
 }
 }
 
 
 func (x *TeenPattiRoom) Reset() {
 func (x *TeenPattiRoom) Reset() {
@@ -798,6 +799,13 @@ func (x *TeenPattiRoom) GetRoomId() string {
 	return ""
 	return ""
 }
 }
 
 
+func (x *TeenPattiRoom) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
 // 通知客户端发牌
 // 通知客户端发牌
 type ReqDealCard struct {
 type ReqDealCard struct {
 	state         protoimpl.MessageState
 	state         protoimpl.MessageState
@@ -1270,7 +1278,7 @@ var file_common_proto_rawDesc = []byte{
 	0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
 	0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
 	0x32, 0x0e, 0x2e, 0x54, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d,
 	0x32, 0x0e, 0x2e, 0x54, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d,
 	0x52, 0x0d, 0x74, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d, 0x22,
 	0x52, 0x0d, 0x74, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f, 0x6d, 0x22,
-	0xd7, 0x01, 0x0a, 0x0d, 0x54, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f,
+	0xeb, 0x01, 0x0a, 0x0d, 0x54, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x74, 0x69, 0x52, 0x6f, 0x6f,
 	0x6d, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x6d, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x04, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6e, 0x42, 0x75, 0x79, 0x69,
 	0x04, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6e, 0x42, 0x75, 0x79, 0x69,
 	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x42, 0x75, 0x79, 0x69,
 	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x42, 0x75, 0x79, 0x69,
@@ -1283,53 +1291,54 @@ var file_common_proto_rawDesc = []byte{
 	0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x6d, 0x4c, 0x65, 0x76, 0x65, 0x6c,
 	0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x6d, 0x4c, 0x65, 0x76, 0x65, 0x6c,
 	0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x6f, 0x6d, 0x4c, 0x65, 0x76, 0x65,
 	0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x6f, 0x6d, 0x4c, 0x65, 0x76, 0x65,
 	0x6c, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
 	0x6c, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x22, 0x25, 0x0a, 0x0b, 0x52, 0x65, 0x71,
-	0x44, 0x65, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x74, 0x50,
-	0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73,
-	0x22, 0x29, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x41, 0x63, 0x74,
-	0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x12,
-	0x52, 0x65, 0x73, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x41, 0x63, 0x74, 0x69,
-	0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x09, 0x70, 0x6c,
-	0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e,
+	0x09, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x25, 0x0a,
+	0x0b, 0x52, 0x65, 0x71, 0x44, 0x65, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06,
+	0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69,
+	0x74, 0x50, 0x6f, 0x73, 0x22, 0x29, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x50, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f,
+	0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x22,
+	0x9e, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74,
+	0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x12, 0x28,
+	0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0a, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x52, 0x09, 0x70,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d,
+	0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64,
+	0x12, 0x16, 0x0a, 0x06, 0x67, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x67, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72,
+	0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64,
+	0x22, 0x73, 0x0a, 0x09, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x12, 0x29, 0x0a,
+	0x08, 0x6f, 0x70, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x0e, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52,
+	0x07, 0x6f, 0x70, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x65, 0x74, 0x5f,
+	0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x65,
+	0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x84, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x52, 0x6f, 0x75,
+	0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x6e,
+	0x64, 0x53, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x72,
+	0x6f, 0x75, 0x6e, 0x64, 0x53, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x09, 0x70, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e,
 	0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65,
 	0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65,
-	0x72, 0x4f, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06,
-	0x67, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x61,
-	0x6d, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x73, 0x0a, 0x09,
-	0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x12, 0x29, 0x0a, 0x08, 0x6f, 0x70, 0x74,
-	0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x50, 0x6c,
-	0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6f, 0x70, 0x74,
-	0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75,
-	0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x65, 0x74, 0x41, 0x6d, 0x6f,
-	0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x22, 0x84, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x14,
-	0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72,
-	0x6f, 0x75, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x69, 0x74,
-	0x50, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64,
-	0x53, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72,
-	0x4f, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x50, 0x6c, 0x61, 0x79,
-	0x65, 0x72, 0x4f, 0x70, 0x74, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74,
-	0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x46, 0x0a, 0x08, 0x4d, 0x73, 0x67, 0x45,
-	0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f,
-	0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43,
-	0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67,
-	0x22, 0x1b, 0x0a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x7c, 0x0a,
-	0x0d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c,
-	0x0a, 0x08, 0x4f, 0x50, 0x54, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
-	0x4f, 0x50, 0x54, 0x5f, 0x4c, 0x4f, 0x4f, 0x4b, 0x5f, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12,
-	0x0f, 0x0a, 0x0b, 0x4f, 0x50, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02,
-	0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x50, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x03, 0x12, 0x0d,
-	0x0a, 0x09, 0x4f, 0x50, 0x54, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x10, 0x04, 0x12, 0x0e, 0x0a,
-	0x0a, 0x4f, 0x50, 0x54, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x0c, 0x0a,
-	0x08, 0x4f, 0x50, 0x54, 0x5f, 0x46, 0x4f, 0x4c, 0x44, 0x10, 0x06, 0x42, 0x07, 0x5a, 0x05, 0x2e,
-	0x2f, 0x6d, 0x73, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x72, 0x4f, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x46, 0x0a, 0x08,
+	0x4d, 0x73, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f,
+	0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x65, 0x72,
+	0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72,
+	0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f,
+	0x72, 0x4d, 0x73, 0x67, 0x22, 0x1b, 0x0a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x2a, 0x7c, 0x0a, 0x0d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x54, 0x79,
+	0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x50, 0x54, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00,
+	0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x50, 0x54, 0x5f, 0x4c, 0x4f, 0x4f, 0x4b, 0x5f, 0x43, 0x41, 0x52,
+	0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x50, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x41,
+	0x52, 0x44, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x50, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c,
+	0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x50, 0x54, 0x5f, 0x52, 0x41, 0x49, 0x53, 0x45, 0x10,
+	0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x50, 0x54, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10,
+	0x05, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x50, 0x54, 0x5f, 0x46, 0x4f, 0x4c, 0x44, 0x10, 0x06, 0x42,
+	0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x6d, 0x73, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (