feat(cache): 添加复合键缓存操作支持 添加了基于 uint32+string 组合键的缓存操作方法,包括 GetByCompoundKey、SetByCompoundKey、DelByCompoundKey 和 ContainsByCompoundKey 方法,用于处理用户ID和会话ID的组合缓存场景 fix(vscode): 添加 cSpell 配置支持 struc 词汇 refactor(session): 移除过时的会话管理方法 移除了基于单一字符串键的会话管理方法,因为已迁移到使用 复合键的缓存操作方式 ```
270 lines
7.0 KiB
Go
270 lines
7.0 KiB
Go
package item
|
||
|
||
import (
|
||
"blazing/common/data/xmlres"
|
||
"blazing/modules/player/model"
|
||
"errors"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
"github.com/gogf/gf/v2/util/grand"
|
||
)
|
||
|
||
type PetItemHandler func(itemid uint32, ctx *model.PetInfo) bool
|
||
|
||
// RangeHandler 范围ID处理器(用于ID区间匹配)
|
||
type RangeHandler struct {
|
||
Start uint32
|
||
End uint32
|
||
Handler PetItemHandler
|
||
}
|
||
|
||
// SetHandler 集合ID处理器(用于离散ID匹配)
|
||
type SetHandler struct {
|
||
IDs []uint32
|
||
Handler PetItemHandler
|
||
}
|
||
|
||
// PetItemHandlerRegistry 道具处理器注册器
|
||
type PetItemHandlerRegistry struct {
|
||
exactHandlers map[uint32]PetItemHandler // 精确ID映射
|
||
rangeHandlers []RangeHandler // 范围ID映射
|
||
setHandlers []SetHandler // 集合ID映射
|
||
}
|
||
|
||
// 全局注册器实例
|
||
var PetItemRegistry = &PetItemHandlerRegistry{
|
||
exactHandlers: make(map[uint32]PetItemHandler),
|
||
}
|
||
|
||
// -------------------------- 4. 注册器方法 --------------------------
|
||
// RegisterExact 注册精确ID的处理函数
|
||
func (r *PetItemHandlerRegistry) RegisterExact(itemID uint32, handler PetItemHandler) {
|
||
r.exactHandlers[itemID] = handler
|
||
}
|
||
|
||
// RegisterRange 注册ID范围的处理函数
|
||
func (r *PetItemHandlerRegistry) RegisterRange(start, end uint32, handler PetItemHandler) {
|
||
r.rangeHandlers = append(r.rangeHandlers, RangeHandler{
|
||
Start: start,
|
||
End: end,
|
||
Handler: handler,
|
||
})
|
||
}
|
||
|
||
// RegisterSet 注册ID集合的处理函数
|
||
func (r *PetItemHandlerRegistry) RegisterSet(ids []uint32, handler PetItemHandler) {
|
||
r.setHandlers = append(r.setHandlers, SetHandler{
|
||
IDs: ids,
|
||
Handler: handler,
|
||
})
|
||
}
|
||
|
||
// GetHandler 根据ItemID获取对应的处理函数
|
||
func (r *PetItemHandlerRegistry) GetHandler(itemID uint32) PetItemHandler {
|
||
// 1. 优先匹配精确ID
|
||
if handler, ok := r.exactHandlers[itemID]; ok {
|
||
return handler
|
||
}
|
||
|
||
// 2. 匹配范围ID
|
||
for _, rh := range r.rangeHandlers {
|
||
if itemID >= rh.Start && itemID <= rh.End {
|
||
return rh.Handler
|
||
}
|
||
}
|
||
|
||
// 3. 匹配集合ID
|
||
for _, sh := range r.setHandlers {
|
||
for _, id := range sh.IDs {
|
||
if itemID == id {
|
||
return sh.Handler
|
||
}
|
||
}
|
||
}
|
||
|
||
// 4. 无匹配的处理器
|
||
return nil
|
||
}
|
||
func nvfunc(itemid uint32, onpet *model.PetInfo) bool {
|
||
// 1. 取出配置(保留你原有的取值方式)
|
||
itemConf := xmlres.ItemsMAP[int(itemid)]
|
||
|
||
// 2. 分割NatureSet(保留你原有的写法)
|
||
rr := strings.Split(*itemConf.NatureSet, " ")
|
||
|
||
// 3. 分割NatureProbs(新增概率解析)
|
||
var probList []string
|
||
if itemConf.NatureProbs != nil {
|
||
probList = strings.Split(*itemConf.NatureProbs, " ")
|
||
}
|
||
|
||
// 4. 按概率选值(核心改造:替换原有随机逻辑)
|
||
selectedVal, err := randomByProbs(rr, probList)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
|
||
// 5. 赋值(保留你原有的类型转换)
|
||
onpet.Nature = gconv.Uint32(selectedVal)
|
||
return true
|
||
}
|
||
|
||
// -------------------------- 6. 初始化注册器(注册所有处理器) --------------------------
|
||
func init() {
|
||
|
||
PetItemRegistry.RegisterRange(300037, 300041, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.Ev[itemid-300037+1] = 0
|
||
return true
|
||
|
||
})
|
||
|
||
PetItemRegistry.RegisterExact(300042, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.Ev[0] = 0
|
||
return true
|
||
})
|
||
PetItemRegistry.RegisterExact(300650, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.Ev = [6]uint32{}
|
||
return true
|
||
})
|
||
PetItemRegistry.RegisterExact(300025, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.Nature = (onpet.Nature + uint32(grand.Intn(25))) % 25
|
||
return true
|
||
})
|
||
|
||
PetItemRegistry.RegisterRange(300081, 300086, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.Nature = gconv.Uint32(*xmlres.ItemsMAP[int(itemid)].Nature)
|
||
return true
|
||
|
||
})
|
||
|
||
PetItemRegistry.RegisterRange(300602, 300605, nvfunc)
|
||
|
||
//特判转换
|
||
PetItemRegistry.RegisterSet([]uint32{300119, 300120}, nvfunc)
|
||
|
||
PetItemRegistry.RegisterExact(300790, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
r := grand.Intn(2)
|
||
if r == 0 {
|
||
if onpet.Dv > 0 {
|
||
onpet.Dv--
|
||
}
|
||
|
||
} else {
|
||
if onpet.Dv < 31 {
|
||
onpet.Dv++
|
||
}
|
||
|
||
}
|
||
return true
|
||
})
|
||
//基因重组
|
||
PetItemRegistry.RegisterExact(300024, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
|
||
onpet.Downgrade(1)
|
||
onpet.NextLvExp = 0
|
||
onpet.Update(false)
|
||
onpet.Ev = [6]uint32{}
|
||
onpet.Dv = uint32(grand.Intn(32))
|
||
onpet.Nature = (onpet.Nature + uint32(grand.Intn(25))) % 25
|
||
//onpet.CalculatePetPane()
|
||
return true
|
||
})
|
||
|
||
PetItemRegistry.RegisterExact(300668, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
|
||
onpet.Dv = uint32(grand.Intn(32))
|
||
return true
|
||
})
|
||
PetItemRegistry.RegisterExact(300791, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
if onpet.Dv >= 31 {
|
||
onpet.Dv = 31
|
||
return true
|
||
}
|
||
onpet.Dv = 31
|
||
return true
|
||
})
|
||
PetItemRegistry.RegisterExact(300702, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
if onpet.Dv >= 31 {
|
||
onpet.Dv = 31
|
||
return true
|
||
}
|
||
onpet.Dv = onpet.Dv + uint32(grand.Intn(31-int(onpet.Dv))+1)
|
||
|
||
if onpet.Dv >= 31 {
|
||
onpet.Dv = 31
|
||
//return true
|
||
}
|
||
return true
|
||
})
|
||
PetItemRegistry.RegisterExact(300053, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
_, _, ok := onpet.GetEffect(1)
|
||
if !ok {
|
||
onpet.RnadEffect()
|
||
return true
|
||
}
|
||
|
||
return false
|
||
})
|
||
PetItemRegistry.RegisterExact(300054, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
_, _, ok := onpet.GetEffect(1)
|
||
if ok {
|
||
onpet.RnadEffect()
|
||
return true
|
||
}
|
||
return false
|
||
})
|
||
}
|
||
|
||
// 替换你原有性格转换的代码段,新增概率解析+权重随机逻辑
|
||
// 注:保留你原有的变量名(如rr)、函数调用(grand.Intn),仅扩展概率逻辑
|
||
|
||
// 先定义一个辅助函数:按概率从列表中选值(贴合你的代码风格)
|
||
func randomByProbs(natureSet []string, probs []string) (string, error) {
|
||
// 1. 若概率配置为空/长度不匹配,降级为等概率随机(兼容原有逻辑)
|
||
if len(probs) == 0 || len(natureSet) != len(probs) {
|
||
if len(natureSet) == 0 {
|
||
return "", errors.New("natureSet is empty")
|
||
}
|
||
// 修复你原有代码的索引越界问题:grand.Intn(len(rr))-1 → 改为grand.Intn(len(rr))
|
||
// 因为grand.Intn(n)返回0~n-1,直接作为索引即可,无需-1
|
||
return natureSet[grand.Intn(len(natureSet))], nil
|
||
}
|
||
|
||
// 2. 解析概率为int数组,校验非负
|
||
probInts := make([]int, len(probs))
|
||
totalProb := 0
|
||
for i, p := range probs {
|
||
val, err := strconv.Atoi(p)
|
||
if err != nil || val < 0 {
|
||
return "", errors.New("invalid prob value: " + p)
|
||
}
|
||
probInts[i] = val
|
||
totalProb += val
|
||
}
|
||
|
||
// 3. 总概率为0,降级为等概率
|
||
if totalProb == 0 {
|
||
return natureSet[grand.Intn(len(natureSet))], nil
|
||
}
|
||
|
||
// 4. 计算前缀和(权重随机核心)
|
||
prefixSum := make([]int, len(probInts))
|
||
prefixSum[0] = probInts[0]
|
||
for i := 1; i < len(probInts); i++ {
|
||
prefixSum[i] = prefixSum[i-1] + probInts[i]
|
||
}
|
||
|
||
// 5. 生成随机数匹配前缀和
|
||
randVal := grand.Intn(totalProb)
|
||
for i, sum := range prefixSum {
|
||
if randVal < sum {
|
||
return natureSet[i], nil
|
||
}
|
||
}
|
||
|
||
// 理论上不会走到这里
|
||
return natureSet[0], nil
|
||
}
|