233 lines
5.4 KiB
Go
233 lines
5.4 KiB
Go
package comm
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"go_dreamfactory/lego/base"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/utils/container/id"
|
|
"go_dreamfactory/pb"
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
"math/big"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
)
|
|
|
|
// 服务网关组件接口定义
|
|
type ISC_GateRouteComp interface {
|
|
core.IServiceComp
|
|
ReceiveMsg(ctx context.Context, args *pb.AgentMessage, reply *pb.RPCMessageReply) error
|
|
RegisterRoute(methodName string, comp reflect.Value, msg reflect.Type, handle reflect.Method)
|
|
GetUserSession(udata *pb.CacheUser) (session IUserSession)
|
|
PutUserSession(session IUserSession)
|
|
}
|
|
|
|
// 服务匹配组件
|
|
type ISC_MatchComp interface {
|
|
core.IServiceComp
|
|
RegisterMatchPool(poolName string, handle func(agrs map[string]interface{}) (err error))
|
|
}
|
|
|
|
// 游戏类资源类型
|
|
const (
|
|
AttrType = "attr" //用户属性资源 例如货币 经验 之类的
|
|
PerType = "per" //用户皮肤,动作,背景 相关资源
|
|
ItemType = "item" //道具物品资源
|
|
HeroType = "hero" //卡片资源 例如英雄卡,检验卡
|
|
EquipmentType = "equi" //武器资源
|
|
VipType = "vip" //vip
|
|
AtlasType = "atlas" //铁匠铺资源
|
|
PandaType = "panda" //熊猫武馆资源
|
|
MountsType = "mts" //捕羊大赛坐骑资源
|
|
TitleType = "title" //称号资源
|
|
XxlType = "xxl" //三消卡片资源
|
|
)
|
|
|
|
type Autogenerated struct {
|
|
ID string `json:"ID,omitempty" bson:"_id"`
|
|
UID string `json:"uid"`
|
|
Act string `json:"act"` // insert update delete
|
|
D []interface{}
|
|
}
|
|
|
|
// Api Check 错误返回结构
|
|
type ErrorCode struct {
|
|
Code pb.ErrorCode
|
|
Data interface{}
|
|
}
|
|
|
|
type IService interface {
|
|
base.IRPCXService
|
|
GetUserSession() (session IUserSession)
|
|
PutUserSession(session IUserSession)
|
|
}
|
|
|
|
// 用户会话
|
|
type IUserSession interface {
|
|
SetSession(ip, sessionId, stag, sid, uid string)
|
|
GetSessionId() string
|
|
GetUserId() string
|
|
GetIP() string
|
|
GetServiecTag() string
|
|
GetGatewayServiceId() string
|
|
IsLogin() bool
|
|
Bind(uid string, wokerId string) (err error)
|
|
UnBind() (err error)
|
|
SendMsg(mainType, subType string, msg proto.Message) (err error)
|
|
Polls() []*pb.UserMessage
|
|
Push() (err error) //警告 api传递过来的会话禁用此接口
|
|
SyncPush() (err error) //警告 api传递过来的会话禁用此接口 同步
|
|
Close() (err error)
|
|
Reset()
|
|
Clone() (session IUserSession) //克隆
|
|
ToString() string
|
|
}
|
|
|
|
// 对protobuf格式的数据进行反序列化
|
|
func ProtoUnmarshal(msg *pb.UserMessage, req proto.Message) (ok bool) {
|
|
err := msg.Data.UnmarshalTo(req)
|
|
if err != nil {
|
|
fmt.Printf("UnmarshalTo %s.%s %v\n", msg.MainType, msg.SubType, err)
|
|
return
|
|
}
|
|
return true
|
|
}
|
|
|
|
// 对protobuf格式的数据进行序列化
|
|
func ProtoMarshal(rsp proto.Message, msg *pb.UserMessage) (ok bool) {
|
|
any, err := anypb.New(rsp)
|
|
if err != nil {
|
|
fmt.Printf("Any New %s.%s %v", msg.MainType, msg.SubType, err)
|
|
return
|
|
}
|
|
msg.Data = any
|
|
return true
|
|
}
|
|
|
|
//参数 权重数组 返回值 数组下标
|
|
func GetRandW(sz []int32) int32 {
|
|
if len(sz) > 0 {
|
|
var _totalW int64 // 总权重
|
|
var _tmpW int64 // 临时权重
|
|
for _, v := range sz {
|
|
_totalW += int64(v)
|
|
}
|
|
// 随机权重
|
|
n, _ := rand.Int(rand.Reader, big.NewInt(_totalW))
|
|
for i, v := range sz {
|
|
_tmpW += int64(v)
|
|
if n.Int64() < _tmpW {
|
|
return int32(i)
|
|
}
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// / 参数 权重数组 返回值 数组下标
|
|
func GetRandWs(sz []int32, num int32) []int {
|
|
results := make([]int, 0)
|
|
if len(sz) > 0 {
|
|
var _totalW int64 // 总权重
|
|
var _tmpW int64 // 临时权重
|
|
for _, v := range sz {
|
|
_totalW += int64(v)
|
|
}
|
|
|
|
if int(num) > len(sz) {
|
|
num = int32(len(sz))
|
|
}
|
|
|
|
for i := 0; i < int(num); i++ {
|
|
// 随机权重
|
|
_tmpW = 0
|
|
n, _ := rand.Int(rand.Reader, big.NewInt(_totalW))
|
|
for i, v := range sz {
|
|
jump := false
|
|
for _, v1 := range results {
|
|
if i == v1 {
|
|
jump = true
|
|
break
|
|
}
|
|
}
|
|
if !jump {
|
|
_tmpW += int64(v)
|
|
if n.Int64() < _tmpW {
|
|
results = append(results, i)
|
|
_totalW -= int64(v)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
func RandShuffle(leng int) []int {
|
|
if leng < 0 {
|
|
return make([]int, 0)
|
|
}
|
|
slist := make([]int, leng)
|
|
for i, _ := range slist {
|
|
slist[i] = i
|
|
}
|
|
for i := leng - 1; i > 0; i-- {
|
|
j, _ := rand.Int(rand.Reader, big.NewInt(int64(i+1)))
|
|
slist[i], slist[j.Int64()] = slist[j.Int64()], slist[i]
|
|
}
|
|
return slist
|
|
}
|
|
|
|
func GetRandNum(min, max int32) int32 {
|
|
if max < min {
|
|
return 0
|
|
}
|
|
if max == min {
|
|
return min
|
|
}
|
|
|
|
n, _ := rand.Int(rand.Reader, big.NewInt(int64(max-min+1))) //+1 是因为 rand方法范围是[0, max)
|
|
return int32(n.Int64()) + min
|
|
}
|
|
|
|
// /通过uid获取用户所在区服
|
|
func UidToSTag(uid string) (stag string, err error) {
|
|
s := strings.SplitN(uid, "_", 2)
|
|
if len(s) < 2 {
|
|
err = fmt.Errorf("uid 格式异常:%v", uid)
|
|
return
|
|
}
|
|
stag = s[0]
|
|
return
|
|
}
|
|
|
|
func GetUserBaseInfo(user *pb.DBUser) *pb.BaseUserInfo {
|
|
info := &pb.BaseUserInfo{
|
|
Uid: user.Uid,
|
|
Sid: user.Sid,
|
|
Name: user.Name,
|
|
Gender: user.Gender,
|
|
Skin: user.CurSkin,
|
|
Aframe: user.Curaframe,
|
|
Title: user.Curtitle,
|
|
Lv: user.Lv,
|
|
}
|
|
return info
|
|
}
|
|
|
|
func GetRobotBaseInfo(robot *cfg.GameRobotData) *pb.BaseUserInfo {
|
|
info := &pb.BaseUserInfo{
|
|
Uid: fmt.Sprintf("ai_%s", id.NewXId()),
|
|
Name: robot.Name,
|
|
Gender: robot.Sex,
|
|
Skin: robot.Showid,
|
|
Lv: robot.Lvshow,
|
|
}
|
|
return info
|
|
}
|