Implement scenario getfile packet and counter stub

This commit is contained in:
Andrew Gutekanst
2020-02-21 14:59:10 -05:00
parent 8cea6235c8
commit fe786617d4
4 changed files with 117 additions and 12 deletions

2
.gitignore vendored
View File

@@ -2,5 +2,7 @@ www/tw/
www/jp/ www/jp/
bin/quests/*.bin bin/quests/*.bin
bin/scenarios/*.bin
bin/debug/*.bin
savedata/ savedata/
Erupe.exe Erupe.exe

View File

@@ -6,7 +6,9 @@ import (
) )
// MsgMhfInfoScenarioCounter represents the MSG_MHF_INFO_SCENARIO_COUNTER // MsgMhfInfoScenarioCounter represents the MSG_MHF_INFO_SCENARIO_COUNTER
type MsgMhfInfoScenarioCounter struct{} type MsgMhfInfoScenarioCounter struct {
AckHandle uint32
}
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
func (m *MsgMhfInfoScenarioCounter) Opcode() network.PacketID { func (m *MsgMhfInfoScenarioCounter) Opcode() network.PacketID {
@@ -15,7 +17,8 @@ func (m *MsgMhfInfoScenarioCounter) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfInfoScenarioCounter) Parse(bf *byteframe.ByteFrame) error { func (m *MsgMhfInfoScenarioCounter) Parse(bf *byteframe.ByteFrame) error {
panic("Not implemented") m.AckHandle = bf.ReadUint32()
return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -6,10 +6,24 @@ import (
) )
type scenarioFileIdentifer struct { type scenarioFileIdentifer struct {
Unk0 uint8 CategoryID uint8
Unk1 uint32 MainID uint32
Unk2 uint8 ChapterID uint8
Unk3 uint8 /*
Flags represent the following bit flags:
11111111 -> Least significant bit on the right.
||||||||
|||||||0x1: Chunk0-type, recursive chunks, quest name/description + 0x14 byte unk info
||||||0x2: Chunk1-type, recursive chunks, npc dialog? + 0x2C byte unk info
|||||0x4: UNK NONE FOUND. (Guessing from the following that this might be a chunk2-type)
||||0x8: Chunk0-type, NO RECURSIVE CHUNKS ([0x1] prefixed?), Episode listing
|||0x10: Chunk1-type, NO RECURSIVE CHUNKS, JKR blob, npc dialog?
||0x20: Chunk2-type, NO RECURSIVE CHUNKS, JKR blob, Menu options or quest titles?
|0x40: UNK NONE FOUND
0x80: UNK NONE FOUND
*/
Flags uint8
} }
// MsgSysGetFile represents the MSG_SYS_GET_FILE // MsgSysGetFile represents the MSG_SYS_GET_FILE
@@ -30,6 +44,11 @@ func (m *MsgSysGetFile) Opcode() network.PacketID {
func (m *MsgSysGetFile) Parse(bf *byteframe.ByteFrame) error { func (m *MsgSysGetFile) Parse(bf *byteframe.ByteFrame) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.IsScenario = bf.ReadBool() m.IsScenario = bf.ReadBool()
m.FilenameLength = bf.ReadUint8()
if m.FilenameLength > 0 {
m.Filename = string(bf.ReadBytes(uint(m.FilenameLength)))
}
if m.IsScenario { if m.IsScenario {
m.ScenarioIdentifer = scenarioFileIdentifer{ m.ScenarioIdentifer = scenarioFileIdentifer{
bf.ReadUint8(), bf.ReadUint8(),
@@ -37,9 +56,6 @@ func (m *MsgSysGetFile) Parse(bf *byteframe.ByteFrame) error {
bf.ReadUint8(), bf.ReadUint8(),
bf.ReadUint8(), bf.ReadUint8(),
} }
} else {
m.FilenameLength = bf.ReadUint8()
m.Filename = string(bf.ReadBytes(uint(m.FilenameLength)))
} }
return nil return nil
} }

View File

@@ -249,6 +249,12 @@ func handleMsgSysCastedBinary(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysGetFile) pkt := p.(*mhfpacket.MsgSysGetFile)
// Debug print the request.
fmt.Printf("%+v\n", pkt)
if pkt.IsScenario {
fmt.Printf("%+v\n", pkt.ScenarioIdentifer)
}
if !pkt.IsScenario { if !pkt.IsScenario {
// Get quest file. // Get quest file.
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%s.bin", stripNullTerminator(pkt.Filename)))) data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%s.bin", stripNullTerminator(pkt.Filename))))
@@ -258,7 +264,34 @@ func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
doSizedAckResp(s, pkt.AckHandle, data) doSizedAckResp(s, pkt.AckHandle, data)
} else { } else {
s.logger.Fatal("scenario getfile not implemented.")
/*
// mhf-fake-client format
filename := fmt.Sprintf(
"%d_%d_%d_%d",
pkt.ScenarioIdentifer.CategoryID,
pkt.ScenarioIdentifer.MainID,
pkt.ScenarioIdentifer.ChapterID,
pkt.ScenarioIdentifer.Flags,
)
*/
// Fist's format:
filename := fmt.Sprintf(
"%d_0_0_0_S%d_T%d_C%d",
pkt.ScenarioIdentifer.CategoryID,
pkt.ScenarioIdentifer.MainID,
pkt.ScenarioIdentifer.Flags, // Fist had as "type" and is the "T%d"
pkt.ScenarioIdentifer.ChapterID,
)
// Read the scenario file.
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("scenarios/%s.bin", filename)))
if err != nil {
panic(err)
}
doSizedAckResp(s, pkt.AckHandle, data)
} }
} }
@@ -1175,7 +1208,58 @@ func handleMsgMhfPaymentAchievement(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgMhfDisplayedAchievement(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfDisplayedAchievement(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfInfoScenarioCounter)
scenarioCounter := []struct {
Unk0 uint32 // Main ID?
Unk1 uint8
Unk2 uint8
}{
{
Unk0: 0x00000000,
Unk1: 1,
Unk2: 4,
},
{
Unk0: 0x00000001,
Unk1: 1,
Unk2: 4,
},
{
Unk0: 0x00000002,
Unk1: 1,
Unk2: 4,
},
{
Unk0: 0x00000003,
Unk1: 1,
Unk2: 4,
},
}
resp := byteframe.NewByteFrame()
resp.WriteUint8(uint8(len(scenarioCounter))) // Entry count
for _, entry := range scenarioCounter {
resp.WriteUint32(entry.Unk0)
resp.WriteUint8(entry.Unk1)
resp.WriteUint8(entry.Unk2)
}
doSizedAckResp(s, pkt.AckHandle, resp.Data())
// DEBUG, DELETE ME!
/*
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "debug/info_scenario_counter_resp.bin"))
if err != nil {
panic(err)
}
doSizedAckResp(s, pkt.AckHandle, data)
*/
}
func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfSaveScenarioData) pkt := p.(*mhfpacket.MsgMhfSaveScenarioData)