package gamedata import ( "encoding/json" "errors" "fmt" "io" "os" "path/filepath" "strconv" "server/conf" "server/game/mod/item" "server/pkg/github.com/name5566/leaf/log" "server/pkg/github.com/name5566/leaf/recordfile" "github.com/fsnotify/fsnotify" ) var watcher *fsnotify.Watcher var ConfPath = "./gamedata/config/" func init() { if conf.Server.GameConfPath != "" { ConfPath = conf.Server.GameConfPath } watcher, _ = fsnotify.NewWatcher() watcher.Add(ConfPath + "reload") go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Rename == fsnotify.Rename { for k := range G_AllConfigsJsonData { InitCfg(k) log.Debug("配置已重新加载:%s", k) } } case err, ok := <-watcher.Errors: if !ok { return } fmt.Println("错误:", err) } } }() } func Reload() { for k := range G_AllConfigsJsonData { InitCfg(k) log.Debug("配置已重新加载:%s", k) } } func readRfNew(st interface{}, ralativePath string) *recordfile.RecordFile { rf, err := recordfile.New(st) if err != nil { log.Fatal("%v", err) } fn := ralativePath + ".txt" err = rf.Read(ConfPath + fn) if err != nil { log.Fatal("%v: %v", fn, err) } return rf } func InitCfg(cfgname string) { // 读取文件内容 filePath := ConfPath + cfgname + ".json" absPath, _ := filepath.Abs(filePath) file, err := os.Open(absPath) if err != nil { log.Debug("打开文件失败:%v", err) return } defer file.Close() // 读取文件内容到字节数组 byteValue, err := io.ReadAll(file) if err != nil { log.Debug("读取文件失败:%v", err) return } // 移除 BOM if len(byteValue) >= 3 && byteValue[0] == 0xEF && byteValue[1] == 0xBB && byteValue[2] == 0xBF { byteValue = byteValue[3:] } var data map[string]interface{} // 反序列化JSON数据 err = json.Unmarshal(byteValue, &data) if err != nil { log.Debug("config name:%s,反序列化失败:%v", cfgname, err) return } rf := new(ConfigData) convertedData := make(map[string]interface{}) for k, v := range data { convertedData[k] = v } rf.SetData(convertedData) G_AllConfigsJsonData[cfgname] = rf } func GetValue(a interface{}, key string) interface{} { if a == nil { return nil } if v, ok := a.(map[string]interface{})[key]; ok { return v } return nil } func GetIntValue(a interface{}, key string) int { if a == nil { return 0 } if v, ok := a.(map[string]interface{})[key]; ok { if v == nil { return 0 } return Int(v) } return 0 } func GetIntSliceValue(a interface{}, key string) []int { if a == nil { return nil } if v, ok := a.(map[string]interface{})[key]; ok { if v == nil { return nil } var r []int for _, v := range v.([]interface{}) { r = append(r, int(v.(float64))) } return r } return nil } func GetFloatValue(a interface{}, key string) float64 { if a == nil { return 0 } if v, ok := a.(map[string]interface{})[key]; ok { if v == nil { return 0 } return v.(float64) } return 0 } func GetItemList(a interface{}, key string) []*item.Item { if a == nil { return nil } if v, ok := a.(map[string]interface{})[key]; ok { if v == nil { return nil } return item.ParseItem(v) } return nil } func GetStringValue(a interface{}, key string) string { if a == nil { return "" } if v, ok := a.(map[string]interface{})[key]; ok { if v == nil { return "" } return String(v) } return "" } func GetData(cfgname string) (map[string]interface{}, error) { if v, ok := G_AllConfigsJsonData[cfgname]; ok { return v.GetData(), nil } return make(map[string]interface{}), errors.New("not found") } func GetDataByKey(cfgname, key string) (map[string]interface{}, error) { if v, ok := G_AllConfigsJsonData[cfgname]; ok { if v, ok := v.GetData()[key]; ok { return v.(map[string]interface{}), nil } } return make(map[string]interface{}), errors.New("not found") } func GetDataByIntKey(cfgname string, key int) (map[string]interface{}, error) { keyStr := strconv.Itoa(key) if v, ok := G_AllConfigsJsonData[cfgname]; ok { if v, ok := v.GetData()[keyStr]; ok { return v.(map[string]interface{}), nil } } return make(map[string]interface{}), errors.New("not found") } func Int(a interface{}) int { if a == nil { return 0 } switch v := a.(type) { case int: return v case int32: return int(v) case int64: return int(v) case float64: return int(v) case string: r, err := strconv.Atoi(v) if err != nil { return 0 } return r } return 0 } func String(a interface{}) string { if a == nil { return "" } switch v := a.(type) { case int: return strconv.Itoa(v) case int32: return strconv.Itoa(int(v)) case int64: return strconv.Itoa(int(v)) case float64: return strconv.FormatFloat(v, 'f', -1, 64) case string: return v } return "" }