mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-25 09:03:10 +01:00
feat(quest): add .json fallback in loadQuestFile for event quest board
JSON-authored quests were serveable via MSG_SYS_GET_FILE but invisible on the event quest board because loadQuestFile only read .bin files. CompileQuestJSON already produces the uncompressed binary layout that the event-board parser expects, so no decompression step is needed. Also update rengoku priority tests to match the .bin-first convention fixed in the previous commit.
This commit is contained in:
@@ -251,12 +251,22 @@ func loadQuestFile(s *Session, questId int) []byte {
|
|||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%05dd0.bin", questId)))
|
base := filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%05dd0", questId))
|
||||||
if err != nil {
|
var decrypted []byte
|
||||||
|
if data, err := os.ReadFile(base + ".bin"); err == nil {
|
||||||
|
decrypted = decryption.UnpackSimple(data)
|
||||||
|
} else if jsonData, err := os.ReadFile(base + ".json"); err == nil {
|
||||||
|
compiled, err := CompileQuestJSON(jsonData)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("loadQuestFile: failed to compile quest JSON",
|
||||||
|
zap.Int("questId", questId), zap.Error(err))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
decrypted = compiled
|
||||||
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
decrypted := decryption.UnpackSimple(file)
|
|
||||||
if s.server.erupeConfig.RealClientMode <= cfg.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport {
|
if s.server.erupeConfig.RealClientMode <= cfg.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport {
|
||||||
decrypted = BackportQuest(decrypted, s.server.erupeConfig.RealClientMode)
|
decrypted = BackportQuest(decrypted, s.server.erupeConfig.RealClientMode)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,13 +156,14 @@ func TestBuildRengokuBinary_ValidationErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestLoadRengokuBinary_JSONPreferredOverBin writes both a JSON file and a
|
// TestLoadRengokuBinary_BinPreferredOverJSON writes both a JSON file and a
|
||||||
// .bin file and verifies that the JSON source is used (different monster IDs).
|
// .bin file and verifies that the .bin source is used (consistent with the
|
||||||
func TestLoadRengokuBinary_JSONPreferredOverBin(t *testing.T) {
|
// quest and scenario loaders).
|
||||||
|
func TestLoadRengokuBinary_BinPreferredOverJSON(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
logger, _ := zap.NewDevelopment()
|
logger, _ := zap.NewDevelopment()
|
||||||
|
|
||||||
// Write a valid rengoku_data.json
|
// Write a valid rengoku_data.json (would produce a much larger binary).
|
||||||
cfg := sampleRengokuConfig()
|
cfg := sampleRengokuConfig()
|
||||||
jsonBytes, err := json.Marshal(cfg)
|
jsonBytes, err := json.Marshal(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -172,8 +173,7 @@ func TestLoadRengokuBinary_JSONPreferredOverBin(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also write a minimal (but incompletely valid) rengoku_data.bin that
|
// Write a minimal valid-magic .bin — should be preferred over JSON.
|
||||||
// would be returned if JSON loading was skipped.
|
|
||||||
binData := make([]byte, 16) // 16-byte ECD header, zero payload
|
binData := make([]byte, 16) // 16-byte ECD header, zero payload
|
||||||
binData[0], binData[1], binData[2], binData[3] = 0x65, 0x63, 0x64, 0x1A
|
binData[0], binData[1], binData[2], binData[3] = 0x65, 0x63, 0x64, 0x1A
|
||||||
if err := os.WriteFile(filepath.Join(dir, "rengoku_data.bin"), binData, 0644); err != nil {
|
if err := os.WriteFile(filepath.Join(dir, "rengoku_data.bin"), binData, 0644); err != nil {
|
||||||
@@ -182,36 +182,35 @@ func TestLoadRengokuBinary_JSONPreferredOverBin(t *testing.T) {
|
|||||||
|
|
||||||
result := loadRengokuBinary(dir, logger)
|
result := loadRengokuBinary(dir, logger)
|
||||||
if result == nil {
|
if result == nil {
|
||||||
t.Fatal("expected non-nil result from JSON loading")
|
t.Fatal("expected non-nil result")
|
||||||
}
|
}
|
||||||
// The JSON-built binary is longer than the 16-byte stub .bin.
|
// The JSON-built binary would be much larger; 16 bytes confirms .bin was used.
|
||||||
if len(result) <= 16 {
|
if len(result) != 16 {
|
||||||
t.Errorf("result is %d bytes — looks like .bin was used instead of JSON", len(result))
|
t.Errorf("result is %d bytes — looks like JSON was used instead of .bin", len(result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestLoadRengokuBinary_JSONFallsThroughOnBadJSON verifies that a malformed
|
// TestLoadRengokuBinary_JSONFallbackWhenNoBin verifies that when no .bin file
|
||||||
// JSON file causes loadRengokuBinary to fall back to the .bin file.
|
// is present, loadRengokuBinary falls back to rengoku_data.json.
|
||||||
func TestLoadRengokuBinary_JSONFallsThroughOnBadJSON(t *testing.T) {
|
func TestLoadRengokuBinary_JSONFallbackWhenNoBin(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
logger, _ := zap.NewDevelopment()
|
logger, _ := zap.NewDevelopment()
|
||||||
|
|
||||||
if err := os.WriteFile(filepath.Join(dir, "rengoku_data.json"), []byte("{invalid json"), 0644); err != nil {
|
cfg := sampleRengokuConfig()
|
||||||
t.Fatal(err)
|
jsonBytes, err := json.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(dir, "rengoku_data.json"), jsonBytes, 0644); err != nil {
|
||||||
// Write a valid minimal .bin
|
|
||||||
binData := make([]byte, 16)
|
|
||||||
binData[0], binData[1], binData[2], binData[3] = 0x65, 0x63, 0x64, 0x1A
|
|
||||||
if err := os.WriteFile(filepath.Join(dir, "rengoku_data.bin"), binData, 0644); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := loadRengokuBinary(dir, logger)
|
result := loadRengokuBinary(dir, logger)
|
||||||
if result == nil {
|
if result == nil {
|
||||||
t.Fatal("expected fallback to .bin, got nil")
|
t.Fatal("expected fallback to JSON, got nil")
|
||||||
}
|
}
|
||||||
if len(result) != 16 {
|
// JSON-built result is much larger than 16 bytes.
|
||||||
t.Errorf("expected 16-byte .bin result, got %d bytes", len(result))
|
if len(result) <= 16 {
|
||||||
|
t.Errorf("result is %d bytes — JSON fallback likely did not run", len(result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user