fix(DB/Quest): Correct Report to Kadrak gating (#27418)

This commit is contained in:
tomfranz2000-glitch
2026-09-16 20:12:10 +02:00
committed by GitHub
parent 34d9caf53a
commit f8cc92b5c0
3 changed files with 155 additions and 1 deletions
@@ -0,0 +1,17 @@
--
UPDATE `quest_template_addon` SET `ExclusiveGroup` = 0 WHERE `ID` IN (6541, 6542);
DELETE FROM `conditions`
WHERE `SourceTypeOrReferenceId` = 19 AND `SourceGroup` = 0 AND `SourceEntry` = 6541 AND `SourceId` = 0
AND `ElseGroup` = 0 AND `ConditionTypeOrReference` = 47 AND `ConditionTarget` = 0
AND `ConditionValue1` = 6542 AND `ConditionValue2` = 65 AND `ConditionValue3` = 0;
DELETE FROM `conditions`
WHERE `SourceTypeOrReferenceId` = 19 AND `SourceGroup` = 0 AND `SourceEntry` = 6542 AND `SourceId` = 0
AND `ElseGroup` = 0 AND `ConditionTypeOrReference` = 47 AND `ConditionTarget` = 0
AND `ConditionValue1` = 6541 AND `ConditionValue2` = 65 AND `ConditionValue3` = 0;
/* DELETE safety: exact full condition primary keys removed above. */
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`,
`ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`,
`NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(19, 0, 6541, 0, 0, 47, 0, 6542, 65, 0, 0, 0, 0, '', 'Quest 6541 available while quest 6542 is not taken or rewarded'),
(19, 0, 6542, 0, 0, 47, 0, 6541, 65, 0, 0, 0, 0, '', 'Quest 6542 available while quest 6541 is not taken or rewarded');
+1 -1
View File
@@ -153,7 +153,7 @@ go test -tags=e2e ./local/... -count=1 -v -timeout 30m -parallel 1
| social/group | form / leave / leader / loot method / disband | P2 | covered | — |
| social/loot | need/greed / master loot; below-half kill; a roll that ends on the timer names the roll in its terminating packet, and the member who never voted gets one PASS | P1 | covered (`TestAC_26862_*`, `TestAC_27299_*`); chest mid-roll `blocked-harness` (GO 194821 UseGameObject); pass-on-loot delete `blocked-harness` (item-survive after ALL_PASSED) | #26894 #26862 #27299 #22000 |
| social/trade | item+gold accept; cancel; walk-OOR TARGET_TO_FAR | P1 | covered | #25723 |
| quests/lifecycle | STAY_ALIVE fail on death; status after save/relog | P1 | covered (`TestAC_26549_*`) | #26549 |
| quests/lifecycle | STAY_ALIVE fail on death; status after save/relog; questgiver accept gating | P1 | covered (`TestAC_26549_*`, `TestAC_27417_*`) | #26549 #27417 |
| quests/escort | find spawned unit; follow-NPC despawns on logout | P2 | covered (`TestAC_24450_*`) | #24450 |
| quests/frostmourne | scrying-orb vision runs; Muradin leaves the cavern and despawns; quest 12478 COMPLETE | P2 | covered (`TestAC_25760_*`); dialogue order and duplicate line `blocked-harness` (no monster-say capture) | #25760 |
| quests/objectives | a mob that drops a quest item advertises it, so the client shows the objective on hover (`creature_questitem` -> `SMSG_CREATURE_QUERY_RESPONSE.questItems`) | P2 | covered (`TestAC_27553_*`), decoding the response through a raw packet hook since the harness has no dispatch case for it | #27553 |
@@ -0,0 +1,137 @@
//go:build e2e
package lifecycle_test
import (
"testing"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/azerothcore/AzerothGhost/e2e/e2eharness"
"github.com/azerothcore/azerothcore-wotlk/e2e/internal/meta"
)
const (
questReportToKadrakBarrens uint32 = 6541
questReportToKadrakStonetalon uint32 = 6542
creatureThork uint32 = 3429
creatureDarnTalongrip uint32 = 11821
creatureKadrak uint32 = 8582
)
// Issue: https://github.com/azerothcore/azerothcore-wotlk/issues/27417
func TestAC_27417_ReportToKadrakGating(t *testing.T) {
meta.Begin(t, meta.TestMeta{
Tags: []string{"short", "quests", "issue", "serial"},
Runtime: "short",
Issue: 27417,
Category: "quests/lifecycle",
})
tests := []struct {
name string
prefix string
firstQuest uint32
firstStarter uint32
secondQuest uint32
secondStarter uint32
}{
{
"BarrensThenStonetalon", "KadrakA",
questReportToKadrakBarrens, creatureThork,
questReportToKadrakStonetalon, creatureDarnTalongrip,
},
{
"StonetalonThenBarrens", "KadrakB",
questReportToKadrakStonetalon, creatureDarnTalongrip,
questReportToKadrakBarrens, creatureThork,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
bot := e2eharness.NewSolo(t, e2eharness.ScenarioOpts{
Prefix: tc.prefix,
Race: e2eharness.RaceOrc,
Class: e2eharness.ClassWarrior,
Level: 17,
})
bot.TeleportPad(t, e2eharness.PackagePad(t))
firstStarterGUID := bot.Spawn(t, tc.firstStarter, 10*time.Second)
secondStarterGUID := bot.Spawn(t, tc.secondStarter, 10*time.Second)
kadrakGUID := bot.Spawn(t, creatureKadrak, 10*time.Second)
bot.GM(t, ".gm off")
bot.FlushWorld(t)
acceptReportQuest(t, bot, firstStarterGUID, tc.firstQuest, true)
acceptReportQuest(t, bot, secondStarterGUID, tc.secondQuest, false)
rewardReportQuest(t, bot, kadrakGUID, tc.firstQuest)
acceptReportQuest(t, bot, secondStarterGUID, tc.secondQuest, true)
rewardReportQuest(t, bot, kadrakGUID, tc.secondQuest)
t.Logf("PASS quests %d then %d completed sequentially", tc.firstQuest, tc.secondQuest)
})
}
}
func acceptReportQuest(
t *testing.T,
bot *e2eharness.ScenarioBot,
starterGUID uint64,
questID uint32,
wantAccepted bool,
) {
t.Helper()
if err := bot.World.QuestgiverHello(starterGUID); err != nil {
e2eharness.HarnessFailf(t, "questgiver hello quest=%d: %v", questID, err)
}
if err := bot.World.QuestgiverAcceptQuest(starterGUID, questID); err != nil {
e2eharness.HarnessFailf(t, "accept quest=%d: %v", questID, err)
}
bot.FlushWorld(t)
status, accepted := bot.QuestStatusAfterSave(t, questID)
if !wantAccepted {
if accepted {
e2eharness.ConfirmedBugf(t, 27417, "quest %d accepted with sibling active (status=%s)",
questID, e2eharness.QuestStatusName(status))
}
return
}
if !accepted {
e2eharness.ConfirmedBugf(t, 27417, "quest %d was not accepted", questID)
}
if status != e2eharness.QuestStatusIncomplete && status != e2eharness.QuestStatusComplete {
e2eharness.Assertf(t, "quest %d accepted with unexpected status=%s", questID,
e2eharness.QuestStatusName(status))
}
}
func rewardReportQuest(t *testing.T, bot *e2eharness.ScenarioBot, kadrakGUID uint64, questID uint32) {
t.Helper()
if err := bot.World.QuestgiverHello(kadrakGUID); err != nil {
e2eharness.HarnessFailf(t, "Kadrak hello quest=%d: %v", questID, err)
}
if err := bot.World.QuestgiverCompleteQuest(kadrakGUID, questID); err != nil {
e2eharness.HarnessFailf(t, "complete quest=%d: %v", questID, err)
}
bot.FlushWorld(t)
if err := bot.World.QuestgiverChooseReward(kadrakGUID, questID, 0); err != nil {
e2eharness.HarnessFailf(t, "choose reward quest=%d: %v", questID, err)
}
bot.FlushWorld(t)
bot.Save(t)
var rewarded int
if err := bot.CharDB.QueryRow(
"SELECT COUNT(*) FROM character_queststatus_rewarded WHERE guid = ? AND quest = ?",
bot.GUID, questID,
).Scan(&rewarded); err != nil {
e2eharness.HarnessFailf(t, "query rewarded quest=%d: %v", questID, err)
}
if rewarded != 1 {
e2eharness.ConfirmedBugf(t, 27417, "quest %d was not rewarded", questID)
}
}