package data import ( "crypto/md5" "github.com/oylshe1314/framework/errors" "github.com/oylshe1314/framework/server" "github.com/oylshe1314/framework/util" "os" "path/filepath" "reflect" "strings" ) type Server interface { Reload() error } type loader interface { load(buf []byte) error } type checker interface { check() error } type extend interface { init() error } type Tables struct { dir string tables //AchievementExtend AchievementTableExtend //AdExtend AdTableExtend //BattlePassRewardExtend BattlePassRewardTableExtend //BattlePassSeasonExtend BattlePassSeasonTableExtend //ChargeExtend ChargeTableExtend //ChargeGiftExtend ChargeGiftTableExtend //CopyArenaRewardExtend CopyArenaRewardTableExtend //CopyChapterExtend CopyChapterTableExtend //CopyMaterialExtend CopyMaterialTableExtend //CopySpeedExtend CopySpeedTableExtend //CopySpeedRewardExtend CopySpeedRewardTableExtend //DropExtend DropTableExtend //FunctionOpenExtend FunctionOpenTableExtend //FunctionOpen1Extend FunctionOpen1TableExtend //LoginRewardExtend LoginRewardTableExtend //PlanetCivilizationExtend PlanetCivilizationTableExtend //TaskExtend TaskTableExtend //RigCharacterExtend RigCharacterTableExtend //RigCharacterStarExtend RigCharacterStarTableExtend //RigComponentExtend RigComponentTableExtend //RigComponentStarExtend RigComponentStarTableExtend //RigCoreExtend RigCoreTableExtend //RigEquipExtend RigEquipTableExtend //RigPendantExtend RigPendantTableExtend //RigRemainsExtend RigRemainsTableExtend //RigSmelterExtend RigSmelterTableExtend //RigTrammelsExtend RigTrammelsTableExtend //SceneMapExtend SceneMapTableExtend //ShopExtend ShopTableExtend //ShopPoolExtend ShopPoolTableExtend //SkillExtend SkillTableExtend //TalentLevelExtend TalentLevelTableExtend //WarshipLevelExtend WarshipLevelTableExtend //WarshipSkillExtend WarshipSkillTableExtend //WarshipStarExtend WarshipStarTableExtend //WordBanExtend WordBanTableExtend } func NewTables(dir string) *Tables { return &Tables{dir: dir} } func (this *Tables) Init() error { allHash, _, err := util.HashAll(md5.New(), true, nil, []string{this.dir}, nil) if err != nil { return err } server.DataHash = allHash[0] var tt = reflect.TypeOf(&this.tables).Elem() var tv = reflect.ValueOf(&this.tables).Elem() var fn = tt.NumField() for i := 0; i < fn; i++ { var sf = tt.Field(i) var fv = tv.Field(i) var vi = fv.Addr().Interface() l, ok := vi.(loader) if !ok { continue } var buf []byte buf, err = os.ReadFile(filepath.Join(this.dir, sf.Name+".json")) if err != nil { return err } err = l.load(buf) if err != nil { return err } c, ok := vi.(checker) if ok { err = c.check() if err != nil { return err } } } var mt = reflect.TypeOf(this).Elem() var mv = reflect.ValueOf(this).Elem() fn = mt.NumField() for i := 0; i < fn; i++ { var sf = mt.Field(i) var fv = mv.Field(i) if sf.Anonymous || !sf.IsExported() { continue } if !strings.HasSuffix(sf.Name, "Extend") { continue } if sf.Type.Kind() != reflect.Struct { if sf.Type.Kind() != reflect.Pointer { continue } var ft = sf.Type.Elem() if ft.Kind() != reflect.Struct { continue } var tp = reflect.New(ft) fv.Set(tp) fv = fv.Elem() } var base = sf.Name[:len(sf.Name)-6] var bfv = tv.FieldByName(base) if !bfv.IsValid() { return errors.Errorf("could not find the field '%s' of the origin table '%sTable' in the structure 'tables'", base, base) } var sfv = fv.FieldByName(base + "Table") if !sfv.IsValid() { return errors.Errorf("should have an anonymous pointer field in the extending table '%s' point to the origin table '%sTable'", sf.Type.Name(), base) } if sfv.Type().Kind() != reflect.Pointer { return errors.Errorf("the anonymous field of the origin table '%sTable' in the extending table '%s' should be a pointer", base, sf.Type.Name()) } sfv.Set(bfv.Addr()) ext, ok := fv.Addr().Interface().(extend) if !ok { continue } err = ext.init() if err != nil { return errors.Errorf("the extending table '%s' init failed, %v", sf.Type.Name(), err) } } return nil }