mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-25 17:12:52 +01:00
feat(scenario): add JSON scenario support and JKR type-3 compressor
Closes #172. Scenario files in bin/scenarios/ can now be authored as .json instead of .bin — the server compiles them to wire format on load, falling back to .bin if no .json is present. - Add ParseScenarioBinary / CompileScenarioJSON in scenario_json.go; supports sub-header format (strings as UTF-8, metadata as base64), inline format, and raw JKR blobs. - Add PackSimple JKR type-3 (LZ77) compressor in jpk_compress.go, ported from ReFrontier JPKEncodeLz.cs; round-trip tested against UnpackSimple. - Fix off-by-one in processDecode (jpk.go): last literal byte was silently dropped for data that does not end on a back-reference. - Wire loadScenarioBinary into handleMsgSysGetFile replacing the inline os.ReadFile call; mirrors the existing loadQuestBinary pattern. - Rewrite docs/scenario-format.md with full container/sub-header spec and JSON schema examples.
This commit is contained in:
@@ -106,10 +106,9 @@ func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
|
||||
)
|
||||
}
|
||||
filename := fmt.Sprintf("%d_0_0_0_S%d_T%d_C%d", pkt.ScenarioIdentifer.CategoryID, pkt.ScenarioIdentifer.MainID, pkt.ScenarioIdentifer.Flags, pkt.ScenarioIdentifer.ChapterID)
|
||||
// Read the scenario file.
|
||||
data, err := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("scenarios/%s.bin", filename)))
|
||||
data, err := loadScenarioBinary(s, filename)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to open scenario file", zap.String("binPath", s.server.erupeConfig.BinPath), zap.String("filename", filename))
|
||||
s.logger.Error("Failed to open scenario file", zap.String("binPath", s.server.erupeConfig.BinPath), zap.String("filename", filename), zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, nil)
|
||||
return
|
||||
}
|
||||
@@ -168,6 +167,26 @@ func loadQuestBinary(s *Session, filename string) ([]byte, error) {
|
||||
return compiled, nil
|
||||
}
|
||||
|
||||
// loadScenarioBinary loads a scenario file by name, trying .bin first then .json.
|
||||
// For .json files it compiles the JSON to the MHF binary wire format.
|
||||
func loadScenarioBinary(s *Session, filename string) ([]byte, error) {
|
||||
base := filepath.Join(s.server.erupeConfig.BinPath, "scenarios", filename)
|
||||
|
||||
if data, err := os.ReadFile(base + ".bin"); err == nil {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
jsonData, err := os.ReadFile(base + ".json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compiled, err := CompileScenarioJSON(jsonData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("compile scenario JSON %s: %w", filename, err)
|
||||
}
|
||||
return compiled, nil
|
||||
}
|
||||
|
||||
func seasonConversion(s *Session, questFile string) string {
|
||||
// Try the seasonal override file (e.g., 00001d2 for season 2)
|
||||
filename := fmt.Sprintf("%s%d", questFile[:6], s.server.Season())
|
||||
|
||||
Reference in New Issue
Block a user