package service import ( "blazing/common/data/share" "blazing/cool" "blazing/modules/config/service" "blazing/modules/player/model" "context" "encoding/binary" "encoding/hex" "fmt" "strings" "time" "github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/os/gtime" "github.com/google/uuid" csmap "github.com/mhmtszr/concurrent-swiss-map" ) // 是否注册,如果注册过,那么就会产生用户player信息 func (s *InfoService) IsReg() bool { m := s.PModel(s.Model) record, _ := m.Exist() return record } // 实现注册,id+昵称+颜色 func (s *InfoService) Reg(nick string, color uint32) { if s.IsReg() { return } t := model.NewPlayer() t.PlayerID = uint64(s.userid) //设置用户信息 t.Data = model.NewPlayerInfo() t.Data.Nick = nick t.Data.UserID = s.userid t.Data.Color = color t.Data.RegisterTime = uint32(time.Now().Unix()) //写入注册时间 _, err := cool.DBM(s.Model).Data(t).FieldsEx("id").Insert() if err != nil { glog.Error(context.Background(), err) return } //go s.InitTask() } func (s *InfoService) Person(userid uint32) (out *model.PlayerEX) { cool.DBM(s.Model).Where("player_id", userid).Scan(&out) return } func (s *InfoService) GetCache() *model.PlayerInfo { ret, _ := cool.CacheManager.Get(context.TODO(), fmt.Sprintf("player: %d", s.userid)) if ret == nil { return nil } var rets *model.PlayerInfo ret.Struct(&rets) return rets } func (s *InfoService) SetLogin() *model.PlayerInfo { m := cool.DBM(s.Model).Where("player_id", s.userid) var tt *model.PlayerEX m.Scan(&tt) if tt == nil { return nil } tt.Data.AllPetNumber = uint32(NewPetService(s.userid).PetCount(0)) if !IsToday(tt.LastResetTime) { //判断是否是今天 //每天login时候检查重置时间,然后把电池,任务,挖矿重置 //挖矿需要单独存,因为防止多开挖矿 tt.LastResetTime = gtime.Now() //每天login时候检查重置时间,然后把电池,任务,挖矿重置 //挖矿需要单独存,因为防止多开挖矿 tt.Data.TimeToday = 0 //重置电池 for _, v := range service.NewTaskService().GetDaily() { tt.Data.SetTask(int(v.TaskId), model.Unaccepted) } for i := 0; i < 50; i++ { //每日任务区段 tt.Data.DailyResArr[i] = 0 //重置每日任务 } //defer t.Service.Talk_Reset() _, err := m.Save(tt) if err != nil { panic(err) } } ret := tt.Data return &ret } var User = csmap.New[string, uint32]( // set the number of map shards. the default value is 32. csmap.WithShardCount[string, uint32](32), // set the total capacity, every shard map has total capacity/shard count capacity. the default value is 0. // csmap.WithSize[string, int](1000), ) // 生成session // GetSessionId 生成并返回会话ID、UUID字符串及可能的错误 // 会话ID由accountID(4字节) + UUID(16字节) + 随机数(4字节)组成,最终编码为十六进制字符串 func (s *InfoService) Gensession() string { uuidV7, _ := uuid.NewV7() // 移除UUID中的连字符,便于后续处理 uuidStr := strings.ReplaceAll(uuidV7.String(), "-", "") // 解码UUID字符串为字节数组(32位十六进制字符串对应16字节) uuidBytes, _ := hex.DecodeString(uuidStr) // 将accountID转换为4字节大端序字节数组 accountBytes := make([]byte, 4) binary.BigEndian.PutUint32(accountBytes, uint32(s.userid)) // 预分配缓冲区(总长度:4+16+4=24字节),减少内存分配 sessionBytes := make([]byte, 0, 24) sessionBytes = append(sessionBytes, accountBytes...) sessionBytes = append(sessionBytes, uuidBytes...) //sessionBytes = append(sessionBytes, grand.B(4)...) // 编码为十六进制字符串作为最终会话ID sessionID := hex.EncodeToString(sessionBytes) User.Store(string(uuidStr), uint32(s.userid)) //share.ShareManager.SaveSession(string(uuidStr), uint32(s.userid)) return sessionID } func (s *InfoService) Kick(id uint32) error { cool.Logger.Info(context.TODO(), "服务器收到踢人") useid1, err := share.ShareManager.GetUserOnline(id) if err != nil { return err } cl, ok := cool.GetClient(useid1) if ok { err := cl.KickPerson(id) //实现指定服务器踢人 if err != nil { return err } } return nil } func (s *InfoService) Save(data model.PlayerInfo) { m := s.PModel(s.Model) var tt model.PlayerEX m.Scan(&tt) tt.Data = data _, err := m.Save(tt) if err != nil { panic(err) } } type InfoService struct { BaseService } func NewInfoService(id uint32) *InfoService { return &InfoService{ BaseService: BaseService{userid: id, Service: &cool.Service{Model: model.NewPlayer(), UniqueKey: map[string]string{ "player_id": "角色名称不能重复", }, PageQueryOp: &cool.QueryOp{ FieldEQ: []string{"player_id"}, }}, }, } }