mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-15 00:15:08 +01:00
Merge pull request #81 from Malckyor/main
Implement auto-cycle event quests
This commit is contained in:
7
patch-schema/12-event_quest_cycling.sql
Normal file
7
patch-schema/12-event_quest_cycling.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.event_quests ADD COLUMN IF NOT EXISTS start_time timestamp with time zone NOT NULL DEFAULT (CURRENT_DATE + interval '0 second');
|
||||||
|
ALTER TABLE IF EXISTS public.event_quests ADD COLUMN IF NOT EXISTS active_duration int DEFAULT 4;
|
||||||
|
ALTER TABLE IF EXISTS public.event_quests ADD COLUMN IF NOT EXISTS inactive_duration int DEFAULT 3;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -156,9 +156,10 @@ func loadQuestFile(s *Session, questId int) []byte {
|
|||||||
|
|
||||||
func makeEventQuest(s *Session, rows *sql.Rows) ([]byte, error) {
|
func makeEventQuest(s *Session, rows *sql.Rows) ([]byte, error) {
|
||||||
var id, mark uint32
|
var id, mark uint32
|
||||||
var questId, flags int
|
var questId, activeDuration, inactiveDuration, flags int
|
||||||
var maxPlayers, questType uint8
|
var maxPlayers, questType uint8
|
||||||
rows.Scan(&id, &maxPlayers, &questType, &questId, &mark, &flags)
|
var startTime time.Time
|
||||||
|
rows.Scan(&id, &maxPlayers, &questType, &questId, &mark, &flags, &startTime, &activeDuration, &inactiveDuration)
|
||||||
|
|
||||||
data := loadQuestFile(s, questId)
|
data := loadQuestFile(s, questId)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
@@ -229,14 +230,61 @@ func makeEventQuest(s *Session, rows *sql.Rows) ([]byte, error) {
|
|||||||
return bf.Data(), nil
|
return bf.Data(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func calculateNumberOfCycles(duration time.Duration, lastStartTime time.Time) int {
|
||||||
|
timeDifference := time.Now().Sub(lastStartTime)
|
||||||
|
numberOfCycles := int(timeDifference.Nanoseconds() / int64(duration))
|
||||||
|
return numberOfCycles
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateQuest)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateQuest)
|
||||||
var totalCount, returnedCount uint16
|
var totalCount, returnedCount uint16
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
|
|
||||||
rows, _ := s.server.db.Query("SELECT id, COALESCE(max_players, 4) AS max_players, quest_type, quest_id, COALESCE(mark, 0) AS mark, COALESCE(flags, -1) FROM event_quests ORDER BY quest_id")
|
currentTime := time.Now()
|
||||||
|
|
||||||
|
// Check the event_quests table to load the quests with rotation system
|
||||||
|
rows, err := s.server.db.Query("SELECT id, COALESCE(max_players, 4) AS max_players, quest_type, quest_id, COALESCE(mark, 0) AS mark, COALESCE(flags, -1), start_time, COALESCE(active_duration, 1) AS active_duration, COALESCE(inactive_duration, 0) AS inactive_duration FROM event_quests ORDER BY quest_id")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
// Commit event quest changes to a transaction instead of doing it one by one for to help with performance
|
||||||
|
transaction, _ := s.server.db.Begin()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
var id, mark uint32
|
||||||
|
var questId int
|
||||||
|
var maxPlayers, flags, questType, activeDuration, inactiveDuration uint8
|
||||||
|
var startTime time.Time
|
||||||
|
|
||||||
|
err := rows.Scan(&id, &maxPlayers, &questType, &questId, &mark, &flags, &startTime, &activeDuration, &inactiveDuration)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of cycles necessary to align quest with the correct date range.
|
||||||
|
cycleCount := calculateNumberOfCycles(time.Duration(activeDuration+inactiveDuration)*24*time.Hour, startTime)
|
||||||
|
|
||||||
|
// Calculate the rotation time based on start time, active duration, and inactive duration.
|
||||||
|
rotationTime := startTime.Add(time.Duration(activeDuration+inactiveDuration) * 24 * time.Duration(cycleCount) * time.Hour)
|
||||||
|
if currentTime.After(rotationTime) {
|
||||||
|
// take the rotationTime and normalize it to midnight as to align with the ingame message for event quest rotation.
|
||||||
|
newRotationTime := time.Date(rotationTime.Year(), rotationTime.Month(), rotationTime.Day(), 0, 0, 0, 0, rotationTime.Location())
|
||||||
|
newRotationTime = newRotationTime.Add(time.Duration(TimeMidnight().Add(13 * time.Hour).Nanosecond()))
|
||||||
|
|
||||||
|
_, err := transaction.Exec("UPDATE event_quests SET start_time = $1 WHERE id = $2", newRotationTime, id)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback() // Rollback if an error occurs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
startTime = newRotationTime // Set the new start time so the quest can be used/removed immediately.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the quest is currently active
|
||||||
|
if currentTime.After(startTime) && currentTime.Sub(startTime) <= time.Duration(activeDuration)*24*time.Hour {
|
||||||
data, err := makeEventQuest(s, rows)
|
data, err := makeEventQuest(s, rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@@ -253,6 +301,10 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit transaction so to write to the database.
|
||||||
|
transaction.Commit()
|
||||||
|
|
||||||
type tuneValue struct {
|
type tuneValue struct {
|
||||||
ID uint16
|
ID uint16
|
||||||
|
|||||||
Reference in New Issue
Block a user