diff --git a/config.json b/config.json index 9d8f99dd5..9f8eed32f 100644 --- a/config.json +++ b/config.json @@ -2,6 +2,7 @@ "Host": "127.0.0.1", "BinPath": "bin", "DisableSoftCrash": false, + "FeaturedWeapons": 2, "devmode": true, "devmodeoptions": { "EnableLauncherServer": false, diff --git a/config/config.go b/config/config.go index 6b8bb743f..ca67b1f9c 100644 --- a/config/config.go +++ b/config/config.go @@ -15,6 +15,7 @@ type Config struct { Host string `mapstructure:"Host"` BinPath string `mapstructure:"BinPath"` DisableSoftCrash bool // Disables the 'Press Return to exit' dialog allowing scripts to reboot the server automatically + FeaturedWeapons int // Number of Active Feature weapons to generate daily DevMode bool DevModeOptions DevModeOptions diff --git a/patch-schema/active-feature.sql b/patch-schema/active-feature.sql new file mode 100644 index 000000000..f8b835100 --- /dev/null +++ b/patch-schema/active-feature.sql @@ -0,0 +1,9 @@ +BEGIN; + +CREATE TABLE IF NOT EXISTS public.feature_weapon +( + start_time timestamp without time zone NOT NULL, + featured integer NOT NULL +); + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_event.go b/server/channelserver/handlers_event.go index b6765f998..95227709f 100644 --- a/server/channelserver/handlers_event.go +++ b/server/channelserver/handlers_event.go @@ -53,38 +53,46 @@ func handleMsgMhfEnumerateEvent(s *Session, p mhfpacket.MHFPacket) { } type activeFeature struct { - StartTime time.Time - ActiveFeatures uint32 - Unk1 uint16 + StartTime time.Time `db:"start_time"` + ActiveFeatures uint32 `db:"featured"` } func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetWeeklySchedule) - persistentEventSchedule := make([]activeFeature, 8) // generate day after weekly restart - for x := -1; x < 7; x++ { - feat := generateActiveWeapons(14) // number of active weapons - // TODO: only generate this once per restart (server should be restarted weekly) - // then load data from db instead of regenerating - persistentEventSchedule[x+1] = activeFeature{ - StartTime: Time_Current_Midnight().Add(time.Duration(24*x) * time.Hour), - ActiveFeatures: uint32(feat), - Unk1: 0, + + var features []activeFeature + rows, _ := s.server.db.Queryx(`SELECT start_time, featured FROM feature_weapon WHERE start_time=$1 OR start_time=$2`, Time_Current_Midnight().Add(-24*time.Hour), Time_Current_Midnight()) + for rows.Next() { + var feature activeFeature + rows.StructScan(&feature) + features = append(features, feature) + } + + if len(features) < 2 { + if len(features) == 0 { + feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons) + feature.StartTime = Time_Current_Midnight().Add(-24 * time.Hour) + features = append(features, feature) + s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures) } + feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons) + feature.StartTime = Time_Current_Midnight() + features = append(features, feature) + s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures) } - resp := byteframe.NewByteFrame() - resp.WriteUint8(uint8(len(persistentEventSchedule))) // Entry count, client only parses the first 7 or 8. - resp.WriteUint32(uint32(Time_Current_Adjusted().Add(-5 * time.Minute).Unix())) // 5 minutes ago server time - - for _, es := range persistentEventSchedule { - resp.WriteUint32(uint32(es.StartTime.Unix())) - resp.WriteUint32(es.ActiveFeatures) - resp.WriteUint16(es.Unk1) + bf := byteframe.NewByteFrame() + bf.WriteUint8(2) + bf.WriteUint32(uint32(Time_Current_Adjusted().Add(-5 * time.Minute).Unix())) + for _, feature := range features { + bf.WriteUint32(uint32(feature.StartTime.Unix())) + bf.WriteUint32(feature.ActiveFeatures) + bf.WriteUint16(0) } - doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } -func generateActiveWeapons(count int) int { +func generateFeatureWeapons(count int) activeFeature { nums := make([]int, 0) var result int r := rand.New(rand.NewSource(time.Now().UnixNano())) @@ -104,7 +112,7 @@ func generateActiveWeapons(count int) int { for _, num := range nums { result += int(math.Pow(2, float64(num))) } - return result + return activeFeature{ActiveFeatures: uint32(result)} } type loginBoost struct {