match服
This commit is contained in:
parent
5db1090d7d
commit
8cbd113015
@ -2,6 +2,7 @@ package baseroom
|
||||
|
||||
import (
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/service"
|
||||
)
|
||||
|
||||
type IRoom interface {
|
||||
@ -38,7 +39,7 @@ type IRobot interface {
|
||||
}
|
||||
|
||||
type ICreateRoom interface {
|
||||
CreateRoom(id, roomType int) (IRoom, pb.ErrCode)
|
||||
CreateRoom(id, roomType int, service service.IService) (IRoom, pb.ErrCode)
|
||||
}
|
||||
|
||||
type ICreatePlayer interface {
|
||||
|
62
common/config/game/color.go
Normal file
62
common/config/game/color.go
Normal file
@ -0,0 +1,62 @@
|
||||
package game
|
||||
|
||||
const (
|
||||
ColorKey = "color_config"
|
||||
)
|
||||
|
||||
type ColorMulRate struct {
|
||||
Mul int64 `json:"mul"` // 赔率
|
||||
Rate int `json:"rate"` // 概率
|
||||
}
|
||||
type ColorRoomConfig struct {
|
||||
RoomType int `json:"room_type"` // 房间类型:初级,低级,中级,高级
|
||||
Name string `json:"name"` // 游戏房间名称
|
||||
Blind int64 `json:"blind"` // 底注
|
||||
Rate int64 `json:"rate"` // 房间明税率
|
||||
|
||||
WinSingleColorWeight []int `json:"win_single_color_weight"` // 胜利单色奖励三个权重
|
||||
WinSingleColorMul [][]*ColorMulRate `json:"win_single_color_mul"` // 胜利单色奖励赔率 (1个同色,2个同色,3个同色)
|
||||
WinDoubleColorMul []*ColorMulRate `json:"win_double_color_mul"` // 胜利双色奖励赔率
|
||||
WinThreeColorMul []*ColorMulRate `json:"win_three_color_mul"` // 胜利三色奖励赔率
|
||||
InitJackpot int64 `json:"init_jackpot"` // 初始jackpot值
|
||||
JackpotRate int `json:"jackpot_rate"` // 单色投注区域每个颜色出现jackpot的概率
|
||||
JpXRate int `json:"jp_x_rate"` // jp池赎回比例
|
||||
JpYRate int `json:"jp_y_rate"` // jp池追加比例
|
||||
JpXYRate int `json:"jp_xy_rate"` // 系统池为正时jackpot追加比例
|
||||
|
||||
AreaBetLimit int64 `json:"area_bet_limit"` // 下注区域自己的下注限制
|
||||
|
||||
NoBetCountMax int `json:"no_bet_count_max"` // 未操作回合踢出房间
|
||||
BetList [][]int64 `json:"bet_list"` // 筹码
|
||||
BetLevel []int64 `json:"bet_level"` // 筹码等级
|
||||
OneCreateMin int32 `json:"one_create_min"` // 一次创建机器最少数
|
||||
OneCreateMax int32 `json:"one_create_max"` // 一次创建机器人最大数
|
||||
UserAddRobotNum int32 `json:"user_add_robot_num"` // 真人+机器人最小数
|
||||
UserAddRobotNumMax int32 `json:"user_add_robot_num_max"` // 真人+机器人最大数
|
||||
OneDeleteNum int32 `json:"one_delete_num"` // 一次删除机器人数量
|
||||
BalanceMin int64 `json:"balance_min"` // 机器人生成最小金币
|
||||
BalanceMax int64 `json:"balance_max"` // 机器人生成最大金币
|
||||
BalanceMinDelete int64 `json:"balance_min_delete"` // 机器人低于多少金币删除
|
||||
RobotCreateTime int32 `json:"robot_create_time"` // 多少时间创建机器人
|
||||
RobotDeleteTime int32 `json:"robot_delete_time"` // 多少时间删除机器人
|
||||
RobotBetNumMin int32 `json:"robot_bet_num_min"` // 机器人每轮下注最少次数
|
||||
RobotBetNumMax int32 `json:"robot_bet_num_max"` // 机器人每轮下注最大次数
|
||||
OpenRobot bool `json:"open_robot"` // 机器人开关
|
||||
BetMap map[int64][]int32
|
||||
TotalBetLimit int64 `json:"total_bet_limit"`
|
||||
}
|
||||
|
||||
type ColorGameTiming struct {
|
||||
//Ready int64 // 准备倒计时
|
||||
Start int64 // 开始
|
||||
Betting int64 // 下注
|
||||
EndBetting int64 // 结束下注
|
||||
OpenThreeDice int64 // 开普通3个骰子
|
||||
Settle int64 // 结算
|
||||
//Ranking int64 // 排行榜
|
||||
}
|
||||
|
||||
type ColorConfig struct {
|
||||
Rooms []*ColorRoomConfig `json:"rooms"` // 房间信息
|
||||
GameTiming *ColorGameTiming `json:"game_timing"`
|
||||
}
|
@ -33,7 +33,7 @@ const (
|
||||
func LoadSpecialConfig[T any](rd *redis.Client, specialKey string, comm *Common[T]) error {
|
||||
s, err := rd.Get(context.Background(), specialKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
log.FatalF("init config:%v", err)
|
||||
log.ErrorF("init config:%v", err)
|
||||
return err
|
||||
}
|
||||
if s == "" {
|
||||
|
@ -17,3 +17,8 @@ func (u User) GetId() int64 {
|
||||
func (u User) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
|
||||
type GameUser struct {
|
||||
User
|
||||
UserResources
|
||||
}
|
||||
|
9
common/pb/colorgame.proto
Normal file
9
common/pb/colorgame.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
common/pb/match.proto
Normal file
36
common/pb/match.proto
Normal file
@ -0,0 +1,36 @@
|
||||
syntax = "proto3";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
import "code.proto";
|
||||
import "user.proto";
|
||||
|
||||
// 房间匹配
|
||||
message C2SMatchRoom
|
||||
{
|
||||
int32 PlayType = 1; // 玩法id
|
||||
int32 RoomType = 2; // 房间类型,低级,中级,高级等
|
||||
}
|
||||
|
||||
// 玩家进房间返回 匹配服返回该消息,假房间。匹配成功后发给对应玩法服,玩法服发NotifyUserEnterRoom才是真房间
|
||||
message S2CMatchRoom
|
||||
{
|
||||
// color玩法配置信息
|
||||
message ColorInfo
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ErrCode code = 1;
|
||||
int32 PlayType = 2; // 玩法id
|
||||
int32 RoomType = 3; // 房间类型,低级,中级,高级等
|
||||
GameUser User = 4; // 玩家数据
|
||||
|
||||
ColorInfo colorInfo = 20; // color玩法配置信息
|
||||
}
|
||||
|
||||
message NotifyUserEnterRoom
|
||||
{
|
||||
repeated GameUser User = 1; // 玩家进房间广播
|
||||
}
|
||||
|
@ -14,17 +14,22 @@ enum MsgId
|
||||
|
||||
NtfMaintainId = 1000; // 通知维护
|
||||
|
||||
// 聊天服 2000-2100
|
||||
// 聊天服 2000-2099
|
||||
C2SChatId = 2000; // 玩家聊天消息
|
||||
S2CChatId = 2001; // 复用C2SChatMsg
|
||||
|
||||
// 登陆服 2100-2200
|
||||
// 登陆服 2100-2199
|
||||
C2SUserLoginId = 2100; // 玩家登陆
|
||||
S2CUserLoginId = 2101;
|
||||
NtfUserOnlineId = 2102;
|
||||
C2SUserLogoutId = 2104;
|
||||
S2CUserLogoutId = 2105;
|
||||
NtfUserOfflineId = 2106;
|
||||
|
||||
// 匹配服 2200-2299
|
||||
C2SMatchRoomId = 2200; // 匹配服
|
||||
S2CMatchRoomId = 2201;
|
||||
NtfUserEnterRoomId = 2202; // 玩家进入房间 所有玩法共用此消息
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ enum ServiceTypeId
|
||||
STI_Login = 101; // 登陆服
|
||||
STI_Chat = 102; // 聊天服
|
||||
STI_DB = 103; // db服
|
||||
STI_Match = 104; // 匹配服
|
||||
|
||||
STI_ColorGame = 120; // color game
|
||||
}
|
||||
|
@ -7,11 +7,24 @@ option go_package = "common/proto/pb";
|
||||
message ChatUser
|
||||
{
|
||||
int64 user_id = 1;
|
||||
string nickname = 2; // 用户名
|
||||
string nickname = 2; // 昵称
|
||||
string avatar = 3; // 头像
|
||||
string avatar_frame = 4; // 头像框
|
||||
string vip_level = 5; // vip等级
|
||||
}
|
||||
|
||||
// 房间内的玩家数据
|
||||
message GameUser
|
||||
{
|
||||
int64 user_id = 1;
|
||||
string nickname = 2; // 昵称
|
||||
string avatar = 3; // 头像
|
||||
string avatar_frame = 4; // 头像框
|
||||
int32 vip_level = 5; // vip等级
|
||||
int32 vip_exp = 6; // vip经验
|
||||
int64 seat = 20; // 座位
|
||||
int64 gold = 25; // 金币
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
59
common/proto/pb/colorgame.pb.go
Normal file
59
common/proto/pb/colorgame.pb.go
Normal file
@ -0,0 +1,59 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: colorgame.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
var File_colorgame_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_colorgame_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x0fcolorgame.proto\x12\x02pbB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var file_colorgame_proto_goTypes = []any{}
|
||||
var file_colorgame_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_colorgame_proto_init() }
|
||||
func file_colorgame_proto_init() {
|
||||
if File_colorgame_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_colorgame_proto_rawDesc), len(file_colorgame_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_colorgame_proto_goTypes,
|
||||
DependencyIndexes: file_colorgame_proto_depIdxs,
|
||||
}.Build()
|
||||
File_colorgame_proto = out.File
|
||||
file_colorgame_proto_goTypes = nil
|
||||
file_colorgame_proto_depIdxs = nil
|
||||
}
|
312
common/proto/pb/match.pb.go
Normal file
312
common/proto/pb/match.pb.go
Normal file
@ -0,0 +1,312 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: match.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// 房间匹配
|
||||
type C2SMatchRoom struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PlayType int32 `protobuf:"varint,1,opt,name=PlayType,proto3" json:"PlayType,omitempty"` // 玩法id
|
||||
RoomType int32 `protobuf:"varint,2,opt,name=RoomType,proto3" json:"RoomType,omitempty"` // 房间类型,低级,中级,高级等
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *C2SMatchRoom) Reset() {
|
||||
*x = C2SMatchRoom{}
|
||||
mi := &file_match_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *C2SMatchRoom) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*C2SMatchRoom) ProtoMessage() {}
|
||||
|
||||
func (x *C2SMatchRoom) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_match_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use C2SMatchRoom.ProtoReflect.Descriptor instead.
|
||||
func (*C2SMatchRoom) Descriptor() ([]byte, []int) {
|
||||
return file_match_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *C2SMatchRoom) GetPlayType() int32 {
|
||||
if x != nil {
|
||||
return x.PlayType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *C2SMatchRoom) GetRoomType() int32 {
|
||||
if x != nil {
|
||||
return x.RoomType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 玩家进房间返回 匹配服返回该消息,假房间。匹配成功后发给对应玩法服,玩法服发NotifyUserEnterRoom才是真房间
|
||||
type S2CMatchRoom struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code ErrCode `protobuf:"varint,1,opt,name=code,proto3,enum=pb.ErrCode" json:"code,omitempty"`
|
||||
PlayType int32 `protobuf:"varint,2,opt,name=PlayType,proto3" json:"PlayType,omitempty"` // 玩法id
|
||||
RoomType int32 `protobuf:"varint,3,opt,name=RoomType,proto3" json:"RoomType,omitempty"` // 房间类型,低级,中级,高级等
|
||||
User *GameUser `protobuf:"bytes,4,opt,name=User,proto3" json:"User,omitempty"` // 玩家数据
|
||||
ColorInfo *S2CMatchRoom_ColorInfo `protobuf:"bytes,20,opt,name=colorInfo,proto3" json:"colorInfo,omitempty"` // color玩法配置信息
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) Reset() {
|
||||
*x = S2CMatchRoom{}
|
||||
mi := &file_match_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2CMatchRoom) ProtoMessage() {}
|
||||
|
||||
func (x *S2CMatchRoom) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_match_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2CMatchRoom.ProtoReflect.Descriptor instead.
|
||||
func (*S2CMatchRoom) Descriptor() ([]byte, []int) {
|
||||
return file_match_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) GetCode() ErrCode {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return ErrCode_OK
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) GetPlayType() int32 {
|
||||
if x != nil {
|
||||
return x.PlayType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) GetRoomType() int32 {
|
||||
if x != nil {
|
||||
return x.RoomType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) GetUser() *GameUser {
|
||||
if x != nil {
|
||||
return x.User
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom) GetColorInfo() *S2CMatchRoom_ColorInfo {
|
||||
if x != nil {
|
||||
return x.ColorInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NotifyUserEnterRoom struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
User []*GameUser `protobuf:"bytes,1,rep,name=User,proto3" json:"User,omitempty"` // 玩家进房间广播
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NotifyUserEnterRoom) Reset() {
|
||||
*x = NotifyUserEnterRoom{}
|
||||
mi := &file_match_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *NotifyUserEnterRoom) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NotifyUserEnterRoom) ProtoMessage() {}
|
||||
|
||||
func (x *NotifyUserEnterRoom) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_match_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NotifyUserEnterRoom.ProtoReflect.Descriptor instead.
|
||||
func (*NotifyUserEnterRoom) Descriptor() ([]byte, []int) {
|
||||
return file_match_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *NotifyUserEnterRoom) GetUser() []*GameUser {
|
||||
if x != nil {
|
||||
return x.User
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// color玩法配置信息
|
||||
type S2CMatchRoom_ColorInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom_ColorInfo) Reset() {
|
||||
*x = S2CMatchRoom_ColorInfo{}
|
||||
mi := &file_match_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *S2CMatchRoom_ColorInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2CMatchRoom_ColorInfo) ProtoMessage() {}
|
||||
|
||||
func (x *S2CMatchRoom_ColorInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_match_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2CMatchRoom_ColorInfo.ProtoReflect.Descriptor instead.
|
||||
func (*S2CMatchRoom_ColorInfo) Descriptor() ([]byte, []int) {
|
||||
return file_match_proto_rawDescGZIP(), []int{1, 0}
|
||||
}
|
||||
|
||||
var File_match_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_match_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vmatch.proto\x12\x02pb\x1a\n" +
|
||||
"code.proto\x1a\n" +
|
||||
"user.proto\"F\n" +
|
||||
"\fC2SMatchRoom\x12\x1a\n" +
|
||||
"\bPlayType\x18\x01 \x01(\x05R\bPlayType\x12\x1a\n" +
|
||||
"\bRoomType\x18\x02 \x01(\x05R\bRoomType\"\xd0\x01\n" +
|
||||
"\fS2CMatchRoom\x12\x1f\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2\v.pb.ErrCodeR\x04code\x12\x1a\n" +
|
||||
"\bPlayType\x18\x02 \x01(\x05R\bPlayType\x12\x1a\n" +
|
||||
"\bRoomType\x18\x03 \x01(\x05R\bRoomType\x12 \n" +
|
||||
"\x04User\x18\x04 \x01(\v2\f.pb.GameUserR\x04User\x128\n" +
|
||||
"\tcolorInfo\x18\x14 \x01(\v2\x1a.pb.S2CMatchRoom.ColorInfoR\tcolorInfo\x1a\v\n" +
|
||||
"\tColorInfo\"7\n" +
|
||||
"\x13NotifyUserEnterRoom\x12 \n" +
|
||||
"\x04User\x18\x01 \x03(\v2\f.pb.GameUserR\x04UserB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_match_proto_rawDescOnce sync.Once
|
||||
file_match_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_match_proto_rawDescGZIP() []byte {
|
||||
file_match_proto_rawDescOnce.Do(func() {
|
||||
file_match_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_match_proto_rawDesc), len(file_match_proto_rawDesc)))
|
||||
})
|
||||
return file_match_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_match_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_match_proto_goTypes = []any{
|
||||
(*C2SMatchRoom)(nil), // 0: pb.C2SMatchRoom
|
||||
(*S2CMatchRoom)(nil), // 1: pb.S2CMatchRoom
|
||||
(*NotifyUserEnterRoom)(nil), // 2: pb.NotifyUserEnterRoom
|
||||
(*S2CMatchRoom_ColorInfo)(nil), // 3: pb.S2CMatchRoom.ColorInfo
|
||||
(ErrCode)(0), // 4: pb.ErrCode
|
||||
(*GameUser)(nil), // 5: pb.GameUser
|
||||
}
|
||||
var file_match_proto_depIdxs = []int32{
|
||||
4, // 0: pb.S2CMatchRoom.code:type_name -> pb.ErrCode
|
||||
5, // 1: pb.S2CMatchRoom.User:type_name -> pb.GameUser
|
||||
3, // 2: pb.S2CMatchRoom.colorInfo:type_name -> pb.S2CMatchRoom.ColorInfo
|
||||
5, // 3: pb.NotifyUserEnterRoom.User:type_name -> pb.GameUser
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_match_proto_init() }
|
||||
func file_match_proto_init() {
|
||||
if File_match_proto != nil {
|
||||
return
|
||||
}
|
||||
file_code_proto_init()
|
||||
file_user_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_match_proto_rawDesc), len(file_match_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_match_proto_goTypes,
|
||||
DependencyIndexes: file_match_proto_depIdxs,
|
||||
MessageInfos: file_match_proto_msgTypes,
|
||||
}.Build()
|
||||
File_match_proto = out.File
|
||||
file_match_proto_goTypes = nil
|
||||
file_match_proto_depIdxs = nil
|
||||
}
|
@ -30,16 +30,20 @@ type MsgId int32
|
||||
const (
|
||||
MsgId_MI_Unknown MsgId = 0
|
||||
MsgId_NtfMaintainId MsgId = 1000 // 通知维护
|
||||
// 聊天服 2000-2100
|
||||
// 聊天服 2000-2099
|
||||
MsgId_C2SChatId MsgId = 2000 // 玩家聊天消息
|
||||
MsgId_S2CChatId MsgId = 2001 // 复用C2SChatMsg
|
||||
// 登陆服 2100-2200
|
||||
// 登陆服 2100-2199
|
||||
MsgId_C2SUserLoginId MsgId = 2100 // 玩家登陆
|
||||
MsgId_S2CUserLoginId MsgId = 2101
|
||||
MsgId_NtfUserOnlineId MsgId = 2102
|
||||
MsgId_C2SUserLogoutId MsgId = 2104
|
||||
MsgId_S2CUserLogoutId MsgId = 2105
|
||||
MsgId_NtfUserOfflineId MsgId = 2106
|
||||
// 匹配服 2200-2299
|
||||
MsgId_C2SMatchRoomId MsgId = 2200 // 匹配服
|
||||
MsgId_S2CMatchRoomId MsgId = 2201
|
||||
MsgId_NtfUserEnterRoomId MsgId = 2202 // 玩家进入房间 所有玩法共用此消息
|
||||
)
|
||||
|
||||
// Enum value maps for MsgId.
|
||||
@ -55,18 +59,24 @@ var (
|
||||
2104: "C2SUserLogoutId",
|
||||
2105: "S2CUserLogoutId",
|
||||
2106: "NtfUserOfflineId",
|
||||
2200: "C2SMatchRoomId",
|
||||
2201: "S2CMatchRoomId",
|
||||
2202: "NtfUserEnterRoomId",
|
||||
}
|
||||
MsgId_value = map[string]int32{
|
||||
"MI_Unknown": 0,
|
||||
"NtfMaintainId": 1000,
|
||||
"C2SChatId": 2000,
|
||||
"S2CChatId": 2001,
|
||||
"C2SUserLoginId": 2100,
|
||||
"S2CUserLoginId": 2101,
|
||||
"NtfUserOnlineId": 2102,
|
||||
"C2SUserLogoutId": 2104,
|
||||
"S2CUserLogoutId": 2105,
|
||||
"NtfUserOfflineId": 2106,
|
||||
"MI_Unknown": 0,
|
||||
"NtfMaintainId": 1000,
|
||||
"C2SChatId": 2000,
|
||||
"S2CChatId": 2001,
|
||||
"C2SUserLoginId": 2100,
|
||||
"S2CUserLoginId": 2101,
|
||||
"NtfUserOnlineId": 2102,
|
||||
"C2SUserLogoutId": 2104,
|
||||
"S2CUserLogoutId": 2105,
|
||||
"NtfUserOfflineId": 2106,
|
||||
"C2SMatchRoomId": 2200,
|
||||
"S2CMatchRoomId": 2201,
|
||||
"NtfUserEnterRoomId": 2202,
|
||||
}
|
||||
)
|
||||
|
||||
@ -101,7 +111,7 @@ var File_msgId_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_msgId_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vmsgId.proto\x12\x02pb*\xce\x01\n" +
|
||||
"\vmsgId.proto\x12\x02pb*\x91\x02\n" +
|
||||
"\x05MsgId\x12\x0e\n" +
|
||||
"\n" +
|
||||
"MI_Unknown\x10\x00\x12\x12\n" +
|
||||
@ -113,7 +123,10 @@ const file_msgId_proto_rawDesc = "" +
|
||||
"\x0fNtfUserOnlineId\x10\xb6\x10\x12\x14\n" +
|
||||
"\x0fC2SUserLogoutId\x10\xb8\x10\x12\x14\n" +
|
||||
"\x0fS2CUserLogoutId\x10\xb9\x10\x12\x15\n" +
|
||||
"\x10NtfUserOfflineId\x10\xba\x10B\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
"\x10NtfUserOfflineId\x10\xba\x10\x12\x13\n" +
|
||||
"\x0eC2SMatchRoomId\x10\x98\x11\x12\x13\n" +
|
||||
"\x0eS2CMatchRoomId\x10\x99\x11\x12\x17\n" +
|
||||
"\x12NtfUserEnterRoomId\x10\x9a\x11B\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_msgId_proto_rawDescOnce sync.Once
|
||||
|
@ -29,6 +29,7 @@ const (
|
||||
ServiceTypeId_STI_Login ServiceTypeId = 101 // 登陆服
|
||||
ServiceTypeId_STI_Chat ServiceTypeId = 102 // 聊天服
|
||||
ServiceTypeId_STI_DB ServiceTypeId = 103 // db服
|
||||
ServiceTypeId_STI_Match ServiceTypeId = 104 // 匹配服
|
||||
ServiceTypeId_STI_ColorGame ServiceTypeId = 120 // color game
|
||||
)
|
||||
|
||||
@ -40,6 +41,7 @@ var (
|
||||
101: "STI_Login",
|
||||
102: "STI_Chat",
|
||||
103: "STI_DB",
|
||||
104: "STI_Match",
|
||||
120: "STI_ColorGame",
|
||||
}
|
||||
ServiceTypeId_value = map[string]int32{
|
||||
@ -48,6 +50,7 @@ var (
|
||||
"STI_Login": 101,
|
||||
"STI_Chat": 102,
|
||||
"STI_DB": 103,
|
||||
"STI_Match": 104,
|
||||
"STI_ColorGame": 120,
|
||||
}
|
||||
)
|
||||
@ -83,14 +86,15 @@ var File_service_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_service_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\rservice.proto\x12\x02pb*j\n" +
|
||||
"\rservice.proto\x12\x02pb*y\n" +
|
||||
"\rServiceTypeId\x12\x0f\n" +
|
||||
"\vSTI_Unknown\x10\x00\x12\f\n" +
|
||||
"\bSTI_Gate\x10d\x12\r\n" +
|
||||
"\tSTI_Login\x10e\x12\f\n" +
|
||||
"\bSTI_Chat\x10f\x12\n" +
|
||||
"\n" +
|
||||
"\x06STI_DB\x10g\x12\x11\n" +
|
||||
"\x06STI_DB\x10g\x12\r\n" +
|
||||
"\tSTI_Match\x10h\x12\x11\n" +
|
||||
"\rSTI_ColorGame\x10xB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
|
@ -25,7 +25,7 @@ const (
|
||||
type ChatUser struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` // 用户名
|
||||
Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` // 昵称
|
||||
Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
|
||||
AvatarFrame string `protobuf:"bytes,4,opt,name=avatar_frame,json=avatarFrame,proto3" json:"avatar_frame,omitempty"` // 头像框
|
||||
VipLevel string `protobuf:"bytes,5,opt,name=vip_level,json=vipLevel,proto3" json:"vip_level,omitempty"` // vip等级
|
||||
@ -98,6 +98,107 @@ func (x *ChatUser) GetVipLevel() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 房间内的玩家数据
|
||||
type GameUser struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` // 昵称
|
||||
Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
|
||||
AvatarFrame string `protobuf:"bytes,4,opt,name=avatar_frame,json=avatarFrame,proto3" json:"avatar_frame,omitempty"` // 头像框
|
||||
VipLevel int32 `protobuf:"varint,5,opt,name=vip_level,json=vipLevel,proto3" json:"vip_level,omitempty"` // vip等级
|
||||
VipExp int32 `protobuf:"varint,6,opt,name=vip_exp,json=vipExp,proto3" json:"vip_exp,omitempty"` // vip经验
|
||||
Seat int64 `protobuf:"varint,20,opt,name=seat,proto3" json:"seat,omitempty"` // 座位
|
||||
Gold int64 `protobuf:"varint,25,opt,name=gold,proto3" json:"gold,omitempty"` // 金币
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GameUser) Reset() {
|
||||
*x = GameUser{}
|
||||
mi := &file_user_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GameUser) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GameUser) ProtoMessage() {}
|
||||
|
||||
func (x *GameUser) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GameUser.ProtoReflect.Descriptor instead.
|
||||
func (*GameUser) Descriptor() ([]byte, []int) {
|
||||
return file_user_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GameUser) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GameUser) GetNickname() string {
|
||||
if x != nil {
|
||||
return x.Nickname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GameUser) GetAvatar() string {
|
||||
if x != nil {
|
||||
return x.Avatar
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GameUser) GetAvatarFrame() string {
|
||||
if x != nil {
|
||||
return x.AvatarFrame
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GameUser) GetVipLevel() int32 {
|
||||
if x != nil {
|
||||
return x.VipLevel
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GameUser) GetVipExp() int32 {
|
||||
if x != nil {
|
||||
return x.VipExp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GameUser) GetSeat() int64 {
|
||||
if x != nil {
|
||||
return x.Seat
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GameUser) GetGold() int64 {
|
||||
if x != nil {
|
||||
return x.Gold
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_user_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_user_proto_rawDesc = "" +
|
||||
@ -109,7 +210,16 @@ const file_user_proto_rawDesc = "" +
|
||||
"\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" +
|
||||
"\x06avatar\x18\x03 \x01(\tR\x06avatar\x12!\n" +
|
||||
"\favatar_frame\x18\x04 \x01(\tR\vavatarFrame\x12\x1b\n" +
|
||||
"\tvip_level\x18\x05 \x01(\tR\bvipLevelB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
"\tvip_level\x18\x05 \x01(\tR\bvipLevel\"\xd8\x01\n" +
|
||||
"\bGameUser\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
|
||||
"\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" +
|
||||
"\x06avatar\x18\x03 \x01(\tR\x06avatar\x12!\n" +
|
||||
"\favatar_frame\x18\x04 \x01(\tR\vavatarFrame\x12\x1b\n" +
|
||||
"\tvip_level\x18\x05 \x01(\x05R\bvipLevel\x12\x17\n" +
|
||||
"\avip_exp\x18\x06 \x01(\x05R\x06vipExp\x12\x12\n" +
|
||||
"\x04seat\x18\x14 \x01(\x03R\x04seat\x12\x12\n" +
|
||||
"\x04gold\x18\x19 \x01(\x03R\x04goldB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_user_proto_rawDescOnce sync.Once
|
||||
@ -123,9 +233,10 @@ func file_user_proto_rawDescGZIP() []byte {
|
||||
return file_user_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_user_proto_goTypes = []any{
|
||||
(*ChatUser)(nil), // 0: pb.ChatUser
|
||||
(*GameUser)(nil), // 1: pb.GameUser
|
||||
}
|
||||
var file_user_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
@ -146,7 +257,7 @@ func file_user_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_proto_rawDesc), len(file_user_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
@ -9,4 +9,5 @@ const (
|
||||
GetUserByUid = "get.user.uid.rpc"
|
||||
GetUserByAccountId = "get.user.account.id.rpc"
|
||||
GetUserResources = "get.user.resources.rpc"
|
||||
GetGameUser = "get.game.user.rpc"
|
||||
)
|
||||
|
@ -5,6 +5,7 @@ const (
|
||||
Chat = "chat"
|
||||
Login = "login"
|
||||
Db = "db"
|
||||
Match = "match"
|
||||
|
||||
// 下面是具体玩法服
|
||||
ColorGame = "color_game"
|
||||
|
@ -148,3 +148,31 @@ func (m *UserBindService) FindTopic(userId int64, serviceTypeId pb.ServiceTypeId
|
||||
}
|
||||
return "", sName
|
||||
}
|
||||
|
||||
// 从etcd中hash一个服务节点
|
||||
func (m *UserBindService) HashServiceNode(typeId pb.ServiceTypeId, uid int64) (*etcd.ServiceNode, error) {
|
||||
var nodes []etcd.ServiceNode
|
||||
var version string
|
||||
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
|
||||
node, ok := value.(etcd.ServiceNode)
|
||||
if ok && node.TypeId == int(typeId) {
|
||||
if version < node.Version {
|
||||
version = node.Version
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
|
||||
if node, ok := value.(etcd.ServiceNode); ok && node.TypeId == int(typeId) {
|
||||
if version == node.Version {
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
if len(nodes) == 0 {
|
||||
return nil, fmt.Errorf("not found service node.type id:%v. all node:%v", typeId, m.stringAllServiceNode())
|
||||
}
|
||||
n := uid % int64(len(nodes))
|
||||
return &nodes[n], nil
|
||||
}
|
||||
|
@ -1,8 +1,23 @@
|
||||
package utils
|
||||
|
||||
import "math"
|
||||
|
||||
func Tie[T any](ret bool, v1, v2 T) T {
|
||||
if ret {
|
||||
return v1
|
||||
}
|
||||
return v2
|
||||
}
|
||||
|
||||
func VipLevel(sumExp int32) (lv, exp int32) {
|
||||
lv = 1
|
||||
exp = 100
|
||||
for {
|
||||
if sumExp < exp {
|
||||
return lv, sumExp
|
||||
}
|
||||
sumExp -= exp
|
||||
lv++
|
||||
exp = int32(math.Pow(float64(lv), 1.6))
|
||||
}
|
||||
}
|
||||
|
7
common/utils/util_test.go
Normal file
7
common/utils/util_test.go
Normal file
@ -0,0 +1,7 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCleanWarn(t *testing.T) {
|
||||
_ = Tie[int](true, 1, 2)
|
||||
}
|
@ -1,79 +1,21 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"game/common/config"
|
||||
"game/common/config/game"
|
||||
"game/common/constant"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
const (
|
||||
specialKey = "color_config"
|
||||
)
|
||||
|
||||
var Command *config.Command
|
||||
var Cfg *config.Common[ColorConfig]
|
||||
|
||||
type MulRate struct {
|
||||
Mul int64 `json:"mul"` // 赔率
|
||||
Rate int `json:"rate"` // 概率
|
||||
}
|
||||
type RoomConfig struct {
|
||||
RoomType int `json:"room_type"` // 房间类型:初级,低级,中级,高级
|
||||
Name string `json:"name"` // 游戏房间名称
|
||||
Blind int64 `json:"blind"` // 底注
|
||||
Rate int64 `json:"rate"` // 房间明税率
|
||||
|
||||
WinSingleColorWeight []int `json:"win_single_color_weight"` // 胜利单色奖励三个权重
|
||||
WinSingleColorMul [][]*MulRate `json:"win_single_color_mul"` // 胜利单色奖励赔率 (1个同色,2个同色,3个同色)
|
||||
WinDoubleColorMul []*MulRate `json:"win_double_color_mul"` // 胜利双色奖励赔率
|
||||
WinThreeColorMul []*MulRate `json:"win_three_color_mul"` // 胜利三色奖励赔率
|
||||
InitJackpot int64 `json:"init_jackpot"` // 初始jackpot值
|
||||
JackpotRate int `json:"jackpot_rate"` // 单色投注区域每个颜色出现jackpot的概率
|
||||
JpXRate int `json:"jp_x_rate"` // jp池赎回比例
|
||||
JpYRate int `json:"jp_y_rate"` // jp池追加比例
|
||||
JpXYRate int `json:"jp_xy_rate"` // 系统池为正时jackpot追加比例
|
||||
|
||||
AreaBetLimit int64 `json:"area_bet_limit"` // 下注区域自己的下注限制
|
||||
|
||||
NoBetCountMax int `json:"no_bet_count_max"` // 未操作回合踢出房间
|
||||
BetList [][]int64 `json:"bet_list"` // 筹码
|
||||
BetLevel []int64 `json:"bet_level"` // 筹码等级
|
||||
OneCreateMin int32 `json:"one_create_min"` // 一次创建机器最少数
|
||||
OneCreateMax int32 `json:"one_create_max"` // 一次创建机器人最大数
|
||||
UserAddRobotNum int32 `json:"user_add_robot_num"` // 真人+机器人最小数
|
||||
UserAddRobotNumMax int32 `json:"user_add_robot_num_max"` // 真人+机器人最大数
|
||||
OneDeleteNum int32 `json:"one_delete_num"` // 一次删除机器人数量
|
||||
BalanceMin int64 `json:"balance_min"` // 机器人生成最小金币
|
||||
BalanceMax int64 `json:"balance_max"` // 机器人生成最大金币
|
||||
BalanceMinDelete int64 `json:"balance_min_delete"` // 机器人低于多少金币删除
|
||||
RobotCreateTime int32 `json:"robot_create_time"` // 多少时间创建机器人
|
||||
RobotDeleteTime int32 `json:"robot_delete_time"` // 多少时间删除机器人
|
||||
RobotBetNumMin int32 `json:"robot_bet_num_min"` // 机器人每轮下注最少次数
|
||||
RobotBetNumMax int32 `json:"robot_bet_num_max"` // 机器人每轮下注最大次数
|
||||
OpenRobot bool `json:"open_robot"` // 机器人开关
|
||||
BetMap map[int64][]int32
|
||||
TotalBetLimit int64 `json:"total_bet_limit"`
|
||||
}
|
||||
|
||||
type GameTiming struct {
|
||||
//Ready int64 // 准备倒计时
|
||||
Start int64 // 开始
|
||||
Betting int64 // 下注
|
||||
EndBetting int64 // 结束下注
|
||||
OpenThreeDice int64 // 开普通3个骰子
|
||||
Settle int64 // 结算
|
||||
//Ranking int64 // 排行榜
|
||||
}
|
||||
|
||||
type ColorConfig struct {
|
||||
Rooms []*RoomConfig `json:"rooms"` // 房间信息
|
||||
GameTiming *GameTiming `json:"game_timing"`
|
||||
}
|
||||
var Cfg *config.Common[game.ColorConfig]
|
||||
|
||||
func InitLog() {
|
||||
log.Open("./log/login.log", log.DebugL)
|
||||
log.Open("./log/color.log", log.DebugL)
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
@ -88,7 +30,7 @@ func LoadConfig(GitCommit, GitBranch, BuildDate string) {
|
||||
return
|
||||
}
|
||||
defer func() { _ = rdb.Close() }()
|
||||
Cfg, err = config.LoadCommonConfig[ColorConfig](rdb, GitCommit, GitBranch, BuildDate)
|
||||
Cfg, err = config.LoadCommonConfig[game.ColorConfig](rdb, GitCommit, GitBranch, BuildDate)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
@ -98,11 +40,11 @@ func LoadConfig(GitCommit, GitBranch, BuildDate string) {
|
||||
}
|
||||
|
||||
func LoadColorConfig(rdb *redis.Client) {
|
||||
if err := config.LoadSpecialConfig[ColorConfig](rdb, specialKey, Cfg); err == nil {
|
||||
if err := config.LoadSpecialConfig[game.ColorConfig](rdb, game.ColorKey, Cfg); err == nil {
|
||||
return
|
||||
}
|
||||
Cfg.Special = &ColorConfig{}
|
||||
Cfg.Special.GameTiming = &GameTiming{
|
||||
Cfg.Special = &game.ColorConfig{}
|
||||
Cfg.Special.GameTiming = &game.ColorGameTiming{
|
||||
//Ready: 100, // 倒计时321
|
||||
Start: 2000,
|
||||
Betting: 15000,
|
||||
@ -113,7 +55,7 @@ func LoadColorConfig(rdb *redis.Client) {
|
||||
}
|
||||
|
||||
WinSingleColorWeight := [3]int{50, 25, 25}
|
||||
WinSingleColorMul := [3][]*MulRate{
|
||||
WinSingleColorMul := [3][]*game.ColorMulRate{
|
||||
{{Mul: 0.6 * 100, Rate: 75 * 100}, {Mul: 1 * 100, Rate: 12 * 100},
|
||||
{Mul: 1.5 * 100, Rate: 7.5 * 100}, {Mul: 2 * 100, Rate: 5.5 * 100}},
|
||||
|
||||
@ -127,16 +69,16 @@ func LoadColorConfig(rdb *redis.Client) {
|
||||
{Mul: 29 * 100, Rate: 0.8 * 100}, {Mul: 49 * 100, Rate: 0.7 * 100},
|
||||
{Mul: 99 * 100, Rate: 0.6 * 100}, {Mul: 9 * 100, Rate: 0.5 * 100}},
|
||||
}
|
||||
WinDoubleColorMul := []*MulRate{{Mul: 8 * 100, Rate: 66 * 100}, {Mul: 11 * 100, Rate: 17 * 100},
|
||||
WinDoubleColorMul := []*game.ColorMulRate{{Mul: 8 * 100, Rate: 66 * 100}, {Mul: 11 * 100, Rate: 17 * 100},
|
||||
{Mul: 14 * 100, Rate: 9 * 100}, {Mul: 19 * 100, Rate: 3.5 * 100},
|
||||
{Mul: 24 * 100, Rate: 1.9 * 100}, {Mul: 54 * 100, Rate: 1.5 * 100},
|
||||
{Mul: 74 * 100, Rate: 1.05 * 100}, {Mul: 99 * 100, Rate: 0.05 * 100}}
|
||||
|
||||
WinThreeColorMul := []*MulRate{{Mul: 150 * 100, Rate: 84.5 * 100}, {Mul: 199 * 100, Rate: 5.5 * 100},
|
||||
WinThreeColorMul := []*game.ColorMulRate{{Mul: 150 * 100, Rate: 84.5 * 100}, {Mul: 199 * 100, Rate: 5.5 * 100},
|
||||
{Mul: 299 * 100, Rate: 4 * 100}, {Mul: 599 * 100, Rate: 3 * 100},
|
||||
{Mul: 799 * 100, Rate: 2 * 100}, {Mul: 999 * 100, Rate: 1 * 100}}
|
||||
|
||||
rmConfig := &RoomConfig{
|
||||
rmConfig := &game.ColorRoomConfig{
|
||||
BetList: [][]int64{
|
||||
{1000, 2000, 3000, 5000, 10000, 20000},
|
||||
{5000, 20000, 30000, 40000, 50000, 800000},
|
||||
@ -170,4 +112,8 @@ func LoadColorConfig(rdb *redis.Client) {
|
||||
RobotBetNumMax: 4,
|
||||
}
|
||||
Cfg.Special.Rooms = append(Cfg.Special.Rooms, rmConfig)
|
||||
|
||||
if bs, err := json.Marshal(&Cfg.Special); err == nil {
|
||||
err = rdb.Set(context.Background(), game.ColorKey, string(bs), 0).Err()
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
|
||||
type ColorPlayer struct {
|
||||
user.User
|
||||
gateTopicName string
|
||||
roomId int
|
||||
}
|
||||
|
||||
func (p *ColorPlayer) Id() int64 {
|
||||
@ -16,3 +18,11 @@ func (p *ColorPlayer) Id() int64 {
|
||||
func (p *ColorPlayer) Robot() baseroom.IRobot {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ColorPlayer) GateTopicName() string {
|
||||
return p.gateTopicName
|
||||
}
|
||||
|
||||
func (p *ColorPlayer) RoomId() int {
|
||||
return p.roomId
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package room
|
||||
import (
|
||||
"game/common/baseroom"
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/service"
|
||||
)
|
||||
|
||||
type RoomFactory struct {
|
||||
}
|
||||
|
||||
func (r *RoomFactory) CreateRoom(id, roomType int) (baseroom.IRoom, pb.ErrCode) {
|
||||
return newColorRoom(id, roomType)
|
||||
func (r *RoomFactory) CreateRoom(id, roomType int, srv service.IService) (baseroom.IRoom, pb.ErrCode) {
|
||||
return newColorRoom(id, roomType, srv)
|
||||
}
|
||||
|
||||
type PlayerFactory struct {
|
||||
|
@ -90,3 +90,21 @@ func (s *DbService) onGetUserResources(iMsg *ipb.InternalMsg) *ipb.InternalMsg {
|
||||
})
|
||||
return iMsg
|
||||
}
|
||||
|
||||
// 获取用户数据
|
||||
func (s *DbService) onGetGameUser(iMsg *ipb.InternalMsg) *ipb.InternalMsg {
|
||||
operationDb[user.GameUser](iMsg, func(gameUser *user.GameUser) (*user.GameUser, pb.ErrCode) {
|
||||
us, code := operation.NewUserOp().Find(gameUser.ID)
|
||||
if code != pb.ErrCode_OK {
|
||||
return nil, code
|
||||
}
|
||||
res, code1 := operation.NewUserResourcesOp().Find(gameUser.ID)
|
||||
if code1 != pb.ErrCode_OK {
|
||||
return nil, code
|
||||
}
|
||||
gameUser.User = *us
|
||||
gameUser.UserResources = *res
|
||||
return gameUser, pb.ErrCode_OK
|
||||
})
|
||||
return iMsg
|
||||
}
|
||||
|
@ -14,5 +14,6 @@ func (s *DbService) initRpcProcessor() {
|
||||
rpcName.GetUserByUid: s.onGetUserByUid,
|
||||
rpcName.GetUserByAccountId: s.onGetUserByAccountId,
|
||||
rpcName.GetUserResources: s.onGetUserResources,
|
||||
rpcName.GetGameUser: s.onGetGameUser,
|
||||
})
|
||||
}
|
||||
|
32
server/match/cmd/cmd.go
Normal file
32
server/match/cmd/cmd.go
Normal file
@ -0,0 +1,32 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/server/match/config"
|
||||
"game/server/match/model"
|
||||
"game/server/match/server"
|
||||
"github.com/fox/fox/log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func initRepo() {
|
||||
model.InitRedis()
|
||||
//model.InitDb()
|
||||
}
|
||||
|
||||
func Run(GitCommit, GitBranch, BuildDate string) {
|
||||
config.InitLog()
|
||||
config.LoadConfig(GitCommit, GitBranch, BuildDate)
|
||||
log.Info(fmt.Sprintf("版本分支:%v,hash值:%v,编译时间:%v", GitBranch, GitCommit, BuildDate))
|
||||
initRepo()
|
||||
|
||||
server.Init()
|
||||
// 截获 SIGINT 和 SIGTERM 信号
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-c
|
||||
server.Stop()
|
||||
log.Info(fmt.Sprintf("received %s, initiating shutdown...", sig))
|
||||
}
|
71
server/match/config/config.go
Normal file
71
server/match/config/config.go
Normal file
@ -0,0 +1,71 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"game/common/config"
|
||||
"game/common/constant"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
var Command *config.Command
|
||||
var Cfg *config.Common[MatchConfig]
|
||||
|
||||
type MatchConfig struct {
|
||||
//Color *game.ColorConfig
|
||||
}
|
||||
|
||||
func InitLog() {
|
||||
log.Open("./log/match.log", log.DebugL)
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
log.Info("-----init log success-----")
|
||||
}
|
||||
|
||||
func LoadConfig(GitCommit, GitBranch, BuildDate string) {
|
||||
Command = config.ParseCommand()
|
||||
rdb, err := db.InitRedis(Command.RedisPassword, Command.RedisHost, Command.RedisPort, constant.Redis0Config)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
defer func() { _ = rdb.Close() }()
|
||||
Cfg, err = config.LoadCommonConfig[MatchConfig](rdb, GitCommit, GitBranch, BuildDate)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
log.DebugF("load common config success")
|
||||
|
||||
//Cfg.Special.Color, err = LoadGameConfig[game.ColorConfig](rdb, game.ColorKey)
|
||||
}
|
||||
|
||||
type Value[T any] struct {
|
||||
Val T
|
||||
}
|
||||
|
||||
func LoadGameConfig[T any](rd *redis.Client, gameKey string) (*T, error) {
|
||||
s, err := rd.Get(context.Background(), gameKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
log.ErrorF("init config:%v", err)
|
||||
return nil, err
|
||||
}
|
||||
if s == "" {
|
||||
return nil, fmt.Errorf("config:%s not found from redis", gameKey)
|
||||
}
|
||||
var val Value[T]
|
||||
if err = json.Unmarshal([]byte(s), &val.Val); err != nil {
|
||||
log.ErrorF("init %v config:%v", gameKey, err)
|
||||
return nil, err
|
||||
}
|
||||
return &val.Val, nil
|
||||
}
|
||||
|
||||
//func GetColorConfig() *game.ColorConfig {
|
||||
// return Cfg.Special.Color
|
||||
//}
|
24
server/match/main.go
Normal file
24
server/match/main.go
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"game/server/match/cmd"
|
||||
"github.com/fox/fox/ksync"
|
||||
"github.com/fox/fox/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
GitCommit = "unknown"
|
||||
GitBranch = "unknown"
|
||||
BuildDate = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := time.Parse("20060102150405", BuildDate)
|
||||
if err == nil {
|
||||
BuildDate = tm.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
ksync.RunSafe(func() {
|
||||
cmd.Run(GitBranch, GitCommit, BuildDate)
|
||||
}, func() { log.ErrorF("reset run") })
|
||||
}
|
58
server/match/match/match.go
Normal file
58
server/match/match/match.go
Normal file
@ -0,0 +1,58 @@
|
||||
package match
|
||||
|
||||
import (
|
||||
"game/common/model/user"
|
||||
"game/common/proto/pb"
|
||||
)
|
||||
|
||||
type MatchPlayer struct {
|
||||
user.User
|
||||
user.UserResources
|
||||
}
|
||||
|
||||
type RoomTypeMatch struct {
|
||||
RoomMatch map[int32][]MatchPlayer
|
||||
}
|
||||
|
||||
type MatchMgr struct {
|
||||
users map[pb.ServiceTypeId]*RoomTypeMatch
|
||||
}
|
||||
|
||||
func NewMatchMgr() *MatchMgr {
|
||||
return &MatchMgr{
|
||||
users: make(map[pb.ServiceTypeId]*RoomTypeMatch),
|
||||
}
|
||||
}
|
||||
|
||||
//func (mgr *MatchMgr) Add(us *MatchPlayer, sid pb.ServiceTypeId, roomType int32) {
|
||||
// users, _ := mgr.users[sid]
|
||||
// for _, u := range users {
|
||||
// if u.ID == us.ID {
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// users = append(users, *us)
|
||||
// mgr.users[sid] = users
|
||||
//}
|
||||
//
|
||||
//func (mgr *MatchMgr) Remove(us *MatchPlayer, sid pb.ServiceTypeId, roomType int32) {
|
||||
// users, _ := mgr.users[sid]
|
||||
// for pos, u := range users {
|
||||
// if u.ID == us.ID {
|
||||
// users = append(users[:pos], users[pos+1:]...)
|
||||
// mgr.users[sid] = users
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func (mgr *MatchMgr) Match(sid pb.ServiceTypeId, num int) []MatchPlayer {
|
||||
// users, _ := mgr.users[sid]
|
||||
// if len(users) <= num {
|
||||
// return nil
|
||||
// }
|
||||
// ret := users[:num]
|
||||
// users = users[num:]
|
||||
// mgr.users[sid] = users
|
||||
// return ret
|
||||
//}
|
70
server/match/model/db.go
Normal file
70
server/match/model/db.go
Normal file
@ -0,0 +1,70 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"game/common/constant"
|
||||
"game/common/utils"
|
||||
"game/server/match/config"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
var (
|
||||
UserBindServiceRedis *redis.Client
|
||||
ConfigRedis *redis.Client
|
||||
// UserDB *gorm.DB
|
||||
// LogDB *gorm.DB
|
||||
)
|
||||
|
||||
func InitRedis() {
|
||||
log.Debug("init redis")
|
||||
var err error
|
||||
cfg := &config.Cfg.Redis
|
||||
UserBindServiceRedis, err = db.InitRedis(cfg.Password, cfg.Host, cfg.Port, constant.Redis3UserBindService)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
utils.AutoSetRedisPool(UserBindServiceRedis)
|
||||
|
||||
ConfigRedis, err = db.InitRedis(cfg.Password, cfg.Host, cfg.Port, constant.Redis0Config)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
utils.AutoSetRedisPool(UserBindServiceRedis)
|
||||
}
|
||||
|
||||
//
|
||||
// func InitDb() {
|
||||
// log.Debug("init db")
|
||||
// var err error
|
||||
// cfg := &config.Cfg.Mysql
|
||||
// UserDB, err = db.InitMysql(cfg.Username, cfg.Password, cfg.Host, cfg.Port, cfg.DbName)
|
||||
// if err != nil {
|
||||
// log.Fatal(err.Error())
|
||||
// return
|
||||
// }
|
||||
// cfg = &config.Cfg.MysqlLog
|
||||
// LogDB, err = db.InitMysql(cfg.Username, cfg.Password, cfg.Host, cfg.Port, cfg.DbName)
|
||||
// if err != nil {
|
||||
// log.Fatal(err.Error())
|
||||
// return
|
||||
// }
|
||||
// // 自动迁移game库表结构
|
||||
// err = UserDB.AutoMigrate(
|
||||
// &UserAccount{},
|
||||
// )
|
||||
// if err != nil {
|
||||
// log.Fatal(err.Error())
|
||||
// return
|
||||
// }
|
||||
// // 自动迁移game_log库表结构
|
||||
// err = LogDB.AutoMigrate(
|
||||
// &UserLoginLog{},
|
||||
// )
|
||||
// if err != nil {
|
||||
// log.Fatal(err.Error())
|
||||
// return
|
||||
// }
|
||||
// }
|
76
server/match/server/match.go
Normal file
76
server/match/server/match.go
Normal file
@ -0,0 +1,76 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"game/common/model/user"
|
||||
"game/common/proto/pb"
|
||||
"game/common/rpcName"
|
||||
"game/common/utils"
|
||||
"github.com/fox/fox/ipb"
|
||||
"github.com/fox/fox/ksync"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/fox/fox/service"
|
||||
)
|
||||
|
||||
func (s *MatchService) getGameUser(uid int64) (*user.GameUser, pb.ErrCode) {
|
||||
node, err := s.bindService.HashServiceNode(pb.ServiceTypeId_STI_DB, uid)
|
||||
if err != nil {
|
||||
log.ErrorF("db service node error:%v", err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
us := &user.GameUser{
|
||||
User: user.User{
|
||||
ID: uid,
|
||||
},
|
||||
UserResources: user.UserResources{
|
||||
UID: uid,
|
||||
},
|
||||
}
|
||||
rpcMsg := ipb.MakeRpcMsg[user.GameUser](rpcName.GetGameUser, uid, us)
|
||||
rspMsg, err := s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
|
||||
if err != nil {
|
||||
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
_ = json.Unmarshal(rspMsg.Msg, us)
|
||||
return us, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
// 匹配房间
|
||||
func (s *MatchService) onMatchRoom(iMsg *ipb.InternalMsg, req *pb.C2SMatchRoom) {
|
||||
ksync.GoSafe(func() {
|
||||
// color game无需进入匹配队列
|
||||
switch pb.ServiceTypeId(req.PlayType) {
|
||||
case pb.ServiceTypeId_STI_ColorGame:
|
||||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, iMsg.UserId, int32(pb.MsgId_S2CMatchRoomId), req)
|
||||
return
|
||||
}
|
||||
|
||||
var us *user.GameUser
|
||||
rsp := &pb.S2CMatchRoom{}
|
||||
us, rsp.Code = s.getGameUser(iMsg.UserId)
|
||||
if rsp.Code != pb.ErrCode_OK {
|
||||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, iMsg.UserId, int32(pb.MsgId_S2CMatchRoomId), rsp)
|
||||
return
|
||||
}
|
||||
vipLv, vipExp := utils.VipLevel(us.VipExp)
|
||||
rsp.User = &pb.GameUser{
|
||||
UserId: us.ID,
|
||||
Nickname: us.Nickname,
|
||||
Avatar: us.AvatarUrl,
|
||||
AvatarFrame: us.AvatarFrame,
|
||||
VipLevel: vipLv,
|
||||
VipExp: vipExp,
|
||||
Seat: 0,
|
||||
Gold: us.Gold,
|
||||
}
|
||||
rsp.PlayType = req.PlayType
|
||||
rsp.RoomType = req.RoomType
|
||||
switch pb.ServiceTypeId(rsp.PlayType) {
|
||||
case pb.ServiceTypeId_STI_ColorGame:
|
||||
rsp.ColorInfo = &pb.S2CMatchRoom_ColorInfo{}
|
||||
}
|
||||
|
||||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, iMsg.UserId, int32(pb.MsgId_S2CMatchRoomId), rsp)
|
||||
}, nil)
|
||||
}
|
17
server/match/server/processor.go
Normal file
17
server/match/server/processor.go
Normal file
@ -0,0 +1,17 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/processor"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
timeout = time.Second * 30
|
||||
)
|
||||
|
||||
func (s *MatchService) initProcessor() {
|
||||
s.processor.RegisterMessages(processor.RegisterMetas{
|
||||
pb.MsgId_C2SMatchRoomId: {pb.C2SMatchRoom{}, s.onMatchRoom},
|
||||
})
|
||||
}
|
119
server/match/server/service.go
Normal file
119
server/match/server/service.go
Normal file
@ -0,0 +1,119 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"game/common/serviceName"
|
||||
"game/common/userBindService"
|
||||
"game/server/match/config"
|
||||
"game/server/match/match"
|
||||
"game/server/match/model"
|
||||
"github.com/fox/fox/ipb"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/fox/fox/processor"
|
||||
"github.com/fox/fox/service"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
var Services []*MatchService
|
||||
|
||||
type MatchService struct {
|
||||
*service.NatsService
|
||||
processor *processor.Processor
|
||||
bindService *userBindService.UserBindService
|
||||
matchMgr *match.MatchMgr
|
||||
}
|
||||
|
||||
func Init() {
|
||||
log.DebugF("init service begin id:%v, num:%v", config.Command.ServiceId, config.Command.ServiceNum)
|
||||
for i := 0; i < config.Command.ServiceNum; i++ {
|
||||
sid := config.Command.ServiceId + i
|
||||
if srv := newService(sid); srv != nil {
|
||||
Services = append(Services, srv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Stop() {
|
||||
for _, srv := range Services {
|
||||
log.DebugF("notify stop service %v", srv.Name())
|
||||
srv.NotifyStop()
|
||||
}
|
||||
for _, srv := range Services {
|
||||
srv.WaitStop()
|
||||
}
|
||||
}
|
||||
|
||||
func newService(serviceId int) *MatchService {
|
||||
var err error
|
||||
s := new(MatchService)
|
||||
s.matchMgr = match.NewMatchMgr()
|
||||
|
||||
sName := fmt.Sprintf("%v-%d", serviceName.Match, serviceId)
|
||||
if s.NatsService, err = service.NewNatsService(&service.InitNatsServiceParams{
|
||||
EtcdAddress: config.Cfg.Etcd.Address,
|
||||
EtcdUsername: "",
|
||||
EtcdPassword: "",
|
||||
NatsAddress: config.Cfg.Nats.Address,
|
||||
ServiceType: serviceName.Match,
|
||||
ServiceName: sName,
|
||||
OnFunc: s,
|
||||
TypeId: int(pb.ServiceTypeId_STI_Match),
|
||||
Version: config.Cfg.BuildDate,
|
||||
}); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
s.bindService = userBindService.NewUserBindService(model.UserBindServiceRedis, s.ServiceEtcd())
|
||||
s.processor = processor.NewProcessor()
|
||||
s.initProcessor()
|
||||
s.OnInit()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *MatchService) OnInit() {
|
||||
// if err := s.NatsService.QueueSubscribe(service.GroupTopic(s), service.GroupQueue(s)); err != nil {
|
||||
// log.Error(err.Error())
|
||||
// }
|
||||
s.NatsService.Run()
|
||||
log.Debug("onInit")
|
||||
}
|
||||
|
||||
func (s *MatchService) CanStop() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *MatchService) OnStop() {
|
||||
s.NatsService.OnStop()
|
||||
log.Debug("OnStop")
|
||||
}
|
||||
|
||||
// 处理其它服发送过来的消息
|
||||
func (s *MatchService) OnMessage(data []byte) error {
|
||||
var iMsg = &ipb.InternalMsg{}
|
||||
var err error
|
||||
if err = proto.Unmarshal(data, iMsg); err != nil {
|
||||
log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
if req, err := s.processor.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil {
|
||||
err = s.processor.Dispatch(iMsg.MsgId, iMsg, req)
|
||||
} else {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
log.Debug(s.Log("received message:%v", iMsg.MsgId))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *MatchService) SendServiceData(topic string, connId uint32, userId int64, msgId int32, data []byte) {
|
||||
iMsg := ipb.MakeMsg(s.Name(), connId, userId, msgId, data)
|
||||
_ = s.Send(topic, iMsg)
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *MatchService) SendServiceMsg(topic string, connId uint32, userId int64, msgId int32, msg proto.Message) {
|
||||
data, _ := proto.Marshal(msg)
|
||||
s.SendServiceData(topic, connId, userId, msgId, data)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user