package channelserver import ( "encoding/hex" "fmt" "io" "os" "path/filepath" "erupe-ce/common/byteframe" "erupe-ce/network/mhfpacket" "go.uber.org/zap" ) func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysGetFile) if pkt.IsScenario { if s.server.erupeConfig.DevModeOptions.QuestDebugTools && s.server.erupeConfig.DevMode { s.logger.Debug( "Scenario", zap.Uint8("CategoryID", pkt.ScenarioIdentifer.CategoryID), zap.Uint32("MainID", pkt.ScenarioIdentifer.MainID), zap.Uint8("ChapterID", pkt.ScenarioIdentifer.ChapterID), zap.Uint8("Flags", pkt.ScenarioIdentifer.Flags), ) } 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))) if err != nil { s.logger.Error(fmt.Sprintf("Failed to open file: %s/scenarios/%s.bin", s.server.erupeConfig.BinPath, filename)) // This will crash the game. doAckBufSucceed(s, pkt.AckHandle, data) return } doAckBufSucceed(s, pkt.AckHandle, data) } else { if _, err := os.Stat(filepath.Join(s.server.erupeConfig.BinPath, "quest_override.bin")); err == nil { data, err := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "quest_override.bin")) if err != nil { panic(err) } doAckBufSucceed(s, pkt.AckHandle, data) } else { if s.server.erupeConfig.DevModeOptions.QuestDebugTools && s.server.erupeConfig.DevMode { s.logger.Debug( "Quest", zap.String("Filename", pkt.Filename), ) } // Get quest file. data, err := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%s.bin", pkt.Filename))) if err != nil { s.logger.Error(fmt.Sprintf("Failed to open file: %s/quests/%s.bin", s.server.erupeConfig.BinPath, pkt.Filename)) // This will crash the game. doAckBufSucceed(s, pkt.AckHandle, data) return } doAckBufSucceed(s, pkt.AckHandle, data) } } } func handleMsgMhfLoadFavoriteQuest(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadFavoriteQuest) var data []byte err := s.server.db.QueryRow("SELECT savefavoritequest FROM characters WHERE id = $1", s.charID).Scan(&data) if err == nil && len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { doAckBufSucceed(s, pkt.AckHandle, []byte{0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) } } func handleMsgMhfSaveFavoriteQuest(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSaveFavoriteQuest) dumpSaveData(s, pkt.Data, "favquest") s.server.db.Exec("UPDATE characters SET savefavoritequest=$1 WHERE id=$2", pkt.Data, s.charID) doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateQuest) var totalCount, returnedCount uint16 bf := byteframe.NewByteFrame() bf.WriteUint16(0) err := filepath.Walk(fmt.Sprintf("%s/events/", s.server.erupeConfig.BinPath), func(path string, info os.FileInfo, err error) error { if err != nil { return err } else if info.IsDir() { return nil } data, err := os.ReadFile(path) if err != nil { return err } else { if len(data) > 850 || len(data) < 400 { return nil // Could be more or less strict with size limits } else { totalCount++ if totalCount > pkt.Offset && len(bf.Data()) < 60000 { returnedCount++ bf.WriteBytes(data) return nil } } } return nil }) if err != nil || totalCount == 0 { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 18)) return } vsQuestItems := []uint16{1580, 1581, 1582, 1583, 1584, 1585, 1587, 1588, 1589, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604} vsQuestBets := []struct { IsTicket bool Quantity uint32 }{ {true, 5}, {false, 1000}, {false, 5000}, {false, 10000}, } data, _ := hex.DecodeString("06E601CF051406E6D4D4D40007CA02F006E6D4D4D4000685051506E6D4D4D40007CA051206E6D4D4D40007CA051306E6D4D4D40007CA02DC06E6D4D4D40006E202D806E6D4D4D40006E202A406E6D4D4D40006E5026806E6D4D4D40006E3027406E6D4D4D40006E3027006E6D4D4D40006E4026506E6D4D4D40006E602E006E6D4D4D40006EE02E706E6D4D4D40006E70B4006E6D4D4D40006E602E206E6D4D4D400068202E506E6D4D4D400068206C706E6D4D4D40006E706B606E6D4D4D40006E706D706E6D4D4D40006E706F206E6D4D4D40006E706DD06E6D4D4D40006E706D306E6D4D4D40006E706FC06E6D4D4D40006E706B806E6D4D4D40006E706CE06E6D4D4D40006E706FD06E6D4D4D40006E706A506E6D4D4D40006E7051906E6D4D4D40006EE02E606E6D4D4D40006700B4106E6D4D4D40006E60B4E06E6D4D4D40006E60B4F06E6D4D4D40006E60B4C06E6D4D4D40006E60B4D06E6D4D4D40006E60B4A06E6D4D4D40006E60B4B06E6D4D4D40006E60B4806E6D4D4D40006E60B4906E6D4D4D40006E60B5606E6D4D4D40006E60B5706E6D4D4D40006E60B5406E6D4D4D40006E60B2606E6D4D4D40006E60B2706E6D4D4D40006E602DE06E6D4D4D40006E702DF06E6D4D4D40006E70B2406E6D4D4D40006E60B2506E6D4D4D40006E60A3006E6D4D4D400062E0A3106E6D4D4D400062E0A3E06E6D4D4D400062E0B2206E6D4D4D40006E60B2306E6D4D4D40006E60B2006E6D4D4D40006E60B2106E6D4D4D40006E60B2E06E6D4D4D40006E60B2F06E6D4D4D40006E6051A06E6D4D4D4000682051B06E6D4D4D400077602CD06E6D4D4D40006BC0B2C06E6D4D4D40006E60A3F06E6D4D4D400062E0A3C06E6D4D4D400062E0A3D06E6D4D4D400062E0A3A06E6D4D4D400062E0A3B06E6D4D4D400062E0A3806E6D4D4D400062E0A3906E6D4D4D400062E0A0606E6D4D4D400062E0A0706E6D4D4D400062E0A0406E6D4D4D400062E0A0506E6D4D4D400062E0A0206E6D4D4D400062E0A0306E6D4D4D400062E0A0006E6D4D4D400062E0A0106E6D4D4D400062E0A0E06E6D4D4D400062E0A0F06E6D4D4D400062E0A0C06E6D4D4D400062E0A0D06E6D4D4D400062E0A0A06E6D4D4D400062E0A0B06E6D4D4D400062E0A0806E6D4D4D400062E0A0906E6D4D4D400062E0A1606E6D4D4D40007CA0A1706E6D4D4D40007CA0A1406E6D4D4D40007CA0A1506E6D4D4D40007CA0A1206E6D4D4D40007CA0A1306E6D4D4D40007CA0A1006E6D4D4D40007CA0A1106E6D4D4D40007CA0A1E06E6D4D4D40007CA0A1F06E6D4D4D40007CA0A1C06E6D4D4D40007CA0A1D06E6D4D4D40007CA0A1A06E6D4D4D40007CA0A1B06E6D4D4D40007CA0A1806E6D4D4D40007CA0A1906E6D4D4D40007CA0BE606E6D4D4D40007CA0BE706E6D4D4D40007CA0BE406E6D4D4D40007CA0BE506E6D4D4D40007CA0BE206E6D4D4D40007CA0B2D06E6D4D4D40006E60B2A06E6D4D4D40006E60BE306E6D4D4D40007CA02D606E6D4D4D40007CA029F06E6D4D4D400062E0B9406E6D4D4D40006820BE006E6D4D4D40007CA0BE106E6D4D4D40007CA0BEE06E6D4D4D40007CA0BEF06E6D4D4D40007CA02C106E6D4D4D400C5B602CE06E6D4D4D400C5B602CF06E6D4D4D400674E02CC06E6D4D4D400674E051006E6D4D4D400062E02FA06E6D4D4D400062E02CA06E6D4D4D40006B602CB06E6D4D4D40006A0051106E6D4D4D400062E02FD06E6D4D4D400062E0B9506E6D4D4D40006820B9206E6D4D4D40006820B9306E6D4D4D40006820B9006E6D4D4D40006820B9106E6D4D4D40006820B9E06E6D4D4D40006820B9F06E6D4D4D40006820BEC06E6D4D4D40006820BED06E6D4D4D40006820BEA06E6D4D4D40006820BEB06E6D4D4D40006820BE806E6D4D4D40006820BE906E6D4D4D40006820BF606E6D4D4D40006820BF706E6D4D4D40006820BF406E6D4D4D40006820BF506E6D4D4D40006820BF206E6D4D4D40006820BF306E6D4D4D40006820BF006E6D4D4D40006820BF106E6D4D4D400068202DB06E6D4D4D40006E70B9C06E6D4D4D40006820BFE06E6D4D4D40006820BFF06E6D4D4D400068202A706E6D4D4D40006E70B9D06E6D4D4D40006820BFC06E6D4D4D400068202D106E6D4D4D40006E702DD06E6D4D4D40006E402DA06E6D4D4D40006EC02D906E6D4D4D40006E402A606E6D4D4D40006EC02A506E6D4D4D40006E402A206E6D4D4D40006EC02A106E6D4D4D40006E402AE06E6D4D4D40006EC02AD06E6D4D4D40006E402AA06E6D4D4D40006EC02A906E6D4D4D40006E402B606E6D4D4D40006EC0BFD06E6D4D4D40006820BFA06E6D4D4D40006820BFB06E6D4D4D40006820BF806E6D4D4D40006820BF906E6D4D4D40006820BC606E6D4D4D40006820BC706E6D4D4D40006820BC406E6D4D4D40006820BC506E6D4D4D40006820BC206E6D4D4D40006820BC306E6D4D4D40006820BC006E6D4D4D40006820BC106E6D4D4D40006820BCE06E6D4D4D40006820BCF06E6D4D4D40006820BCC06E6D4D4D40006820BCD06E6D4D4D40006820BCA06E6D4D4D40006820BCB06E6D4D4D40006820BC806E6D4D4D40006820BC906E6D4D4D40006820BD606E6D4D4D40006820BD706E6D4D4D40006820BD406E6D4D4D40006820BD506E6D4D4D40006820BD206E6D4D4D40006820BD306E6D4D4D40006820BD006E6D4D4D40006820BD106E6D4D4D40006820BDE06E6D4D4D40006820BDF06E6D4D4D40006820BDC06E6D4D4D40006820BDD06E6D4D4D40006820BDA06E6D4D4D40006820BDB06E6D4D4D40006820B9A06E6D4D4D40006820BD806E6D4D4D40006820BD906E6D4D4D40006820BA606E6D4D4D40006820BA706E6D4D4D40006820BA406E6D4D4D40006820BA506E6D4D4D40006820BA206E6D4D4D40006820BA306E6D4D4D40006820BA006E6D4D4D40006820BA106E6D4D4D40006820BAE06E6D4D4D40006820BAF06E6D4D4D40006820BAC06E6D4D4D40006820BBE06E6D4D4D40006820BBF06E6D4D4D40006820BBC06E6D4D4D40006820BBD06E6D4D4D40006820BBA06E6D4D4D40006820BBB06E6D4D4D40006820BB806E6D4D4D40006820BB906E6D4D4D40006820B8606E6D4D4D40006820B8706E6D4D4D40006820B8406E6D4D4D40006820B8506E6D4D4D40006820B8206E6D4D4D400068202D706E6D4D4D40007CA02D406E6D4D4D40007CA026E06E6D4D4D40007CA0B9B06E6D4D4D40006820B9806E6D4D4D40006820B6A06E6D4D4D40006820B6B06E6D4D4D4000682029C06E6D4D4D40006E60B6806E6D4D4D4000682029D06E6D4D4D40006E60B6906E6D4D4D40006820A6E06E6D4D4D40006E60A6F06E6D4D4D40006E60A6C06E6D4D4D40006E60A6D06E6D4D4D40006E60A6A06E6D4D4D40006E60A6B06E6D4D4D40006E60A6806E6D4D4D40006E60A6906E6D4D4D40006E60A7606E6D4D4D40006E60A7706E6D4D4D40006E602E406E6D4D4D40005010A7406E6D4D4D40006E60A7506E6D4D4D40006E602D006E6D4D4D40006E60A7206E6D4D4D40006E6026606E6D4D4D400028C0A4406E6D4D4D40006E60A4506E6D4D4D40006E6026C06E6D4D4D40006E7026D06E6D4D4D40006E5026A06E6D4D4D40006E3026B06E6D4D4D40006E70A4206E6D4D4D40006E6026906E6D4D4D40006E7027606E6D4D4D40006E5027706E6D4D4D40006E50A4306E6D4D4D40006E6027506E6D4D4D40006E7027206E6D4D4D40006E7027306E6D4D4D40006E70A4006E6D4D4D40006E60A4106E6D4D4D40006E60A4E06E6D4D4D40006E60A4F06E6D4D4D40006E60A4C06E6D4D4D40006E60A4D06E6D4D4D40006E60A4A06E6D4D4D40006E60A4B06E6D4D4D40006E60A4806E6D4D4D40006E6029E06E6D4D4D40006E602A306E6D4D4D40006E402A006E6D4D4D40006E302AF06E6D4D4D40006E402AC06E6D4D4D40006E302AB06E6D4D4D40006E402A806E6D4D4D40006E3027106E6D4D4D40006E2027E06E6D4D4D40006EC027F06E6D4D4D40006E2027C06E6D4D4D40006EC027D06E6D4D4D40006E40B7606E6D4D4D40006820B7706E6D4D4D40006820B7406E6D4D4D40006820B7506E6D4D4D40006820B7206E6D4D4D40006820B7306E6D4D4D40006820B7006E6D4D4D40006820B7106E6D4D4D40006820B7E06E6D4D4D40006820B3C06E6D4D4D40006E60D3406E6D4D4D40006820D3506E6D4D4D40006820B3D06E6D4D4D40006E6026706E6D4D4D40006E60D5E06E6D4D4D40006820D5F06E6D4D4D40006820D5C06E6D4D4D40006820D5D06E6D4D4D40006820D5A06E6D4D4D40006820D5B06E6D4D4D40006820D5806E6D4D4D40006820D5906E6D4D4D40006820D2606E6D4D4D40006820D2706E6D4D4D40006820D2406E6D4D4D40006820D2506E6D4D4D40006820D2206E6D4D4D40006820D3206E6D4D4D40006820D3306E6D4D4D40006820D3006E6D4D4D40006820D3106E6D4D4D40006820D3E06E6D4D4D40006820D2306E6D4D4D40006820D2006E6D4D4D40006820D2106E6D4D4D40006820D2E06E6D4D4D40006820D2F06E6D4D4D40006820D2C06E6D4D4D40006820D2D06E6D4D4D40006820D2A06E6D4D4D40006820D2B06E6D4D4D40006820D2806E6D4D4D40006820D2906E6D4D4D40006820D3606E6D4D4D40006820D3706E6D4D4D400068202E306E6D4D4D40006F802E106E6D4D4D40006820D3F06E6D4D4D40006820D0A06E6D4D4D40006820D0B06E6D4D4D40006820D0806E6D4D4D40006820D0906E6D4D4D40006820D1606E6D4D4D40006820D1706E6D4D4D40006820D1406E6D4D4D40006820D1506E6D4D4D40006820D1206E6D4D4D40006820D3C06E6D4D4D400068202B406E6D4D4D40006E60D1306E6D4D4D40006820D1006E6D4D4D40006820D1106E6D4D4D40006820D1E06E6D4D4D40006820AE006E6D4D4D40006820AE106E6D4D4D40006820AEE06E6D4D4D40006820AEF06E6D4D4D40006820AEC06E6D4D4D40006820AED06E6D4D4D40006820AEA06E6D4D4D40006820AEB06E6D4D4D40006820AE806E6D4D4D40006820AE906E6D4D4D40006820AF606E6D4D4D4000682026406E6D4D4D40006E60AF706E6D4D4D40006820B3A06E6D4D4D40006E60AB206E6D4D4D40006E60B3B06E6D4D4D40006E60D3D06E6D4D4D40006820D3A06E6D4D4D40006820D3B06E6D4D4D40006820AB306E6D4D4D40006E60AB006E6D4D4D40006E60AB106E6D4D4D40006E60ABE06E6D4D4D40006E60ABF06E6D4D4D40006E60ABC06E6D4D4D40006E60ABD06E6D4D4D40006E60ABA06E6D4D4D40006E60ABB06E6D4D4D40006E60AB806E6D4D4D40006E60AB906E6D4D4D40006E60A8606E6D4D4D40006E60A8806E6D4D4D40006E60A8906E6D4D4D40006E60A9606E6D4D4D40006E60A9706E6D4D4D40006E60A9406E6D4D4D40006E60A9506E6D4D4D40006E60A9206E6D4D4D40006E60A9306E6D4D4D40006E60A9006E6D4D4D40006E60A9106E6D4D4D40006E60A9E06E6D4D4D40006E60A9F06E6D4D4D40006E60A9C06E6D4D4D40006E60D3806E6D4D4D40006820D3906E6D4D4D40006820D0606E6D4D4D40006820D0706E6D4D4D40006820D0406E6D4D4D40006820D0506E6D4D4D40006820D0206E6D4D4D40006820D0306E6D4D4D40006820D0006E6D4D4D40006820D0106E6D4D4D40006820D0E06E6D4D4D40006820D0F06E6D4D4D40006820D0C06E6D4D4D40006820D0D06E6D4D4D40006820B3806E6D4D4D40006E60B3906E6D4D4D40006E60B0606E6D4D4D40006E60B0706E6D4D4D40006E60B0406E6D4D4D40006E60B0506E6D4D4D40006E60B0206E6D4D4D40006E60B0306E6D4D4D40006E60B0006E6D4D4D40006E60B1206E6D4D4D40006E60B1306E6D4D4D40006E60B1006E6D4D4D40006E60B1106E6D4D4D40006E60B1E06E6D4D4D40006E60B1F06E6D4D4D40006E60B1C06E6D4D4D40006E60B1D06E6D4D4D40006E60B1A06E6D4D4D40006E60B1B06E6D4D4D40006E60B1806E6D4D4D40006E60B1906E6D4D4D40006E608E606E6D4D4D40006E6029B06E6D4D4D40006F20AF406E6D4D4D4000682026006E6D4D4D40006E70AC606E6D4D4D40006820AC706E6D4D4D40006820AC406E6D4D4D40006820AC506E6D4D4D40006820AC206E6D4D4D40006820AC306E6D4D4D40006820AC006E6D4D4D40006820AC106E6D4D4D40006820ACE06E6D4D4D40006820ACF06E6D4D4D40006820ACC06E6D4D4D40006820ACD06E6D4D4D40006820ACA06E6D4D4D4000682027A06E6D4D4D40006E30ADC06E6D4D4D40006820ADD06E6D4D4D40006820ADA06E6D4D4D40006820ADB06E6D4D4D40006820AD806E6D4D4D40006820AD906E6D4D4D40006820AA606E6D4D4D40006820AA706E6D4D4D40006820AA406E6D4D4D40006820AA506E6D4D4D40006820AA206E6D4D4D40006820AA306E6D4D4D40006820AA006E6D4D4D4000682") bf.WriteBytes(data) bf.WriteUint16(uint16(len(vsQuestItems))) bf.WriteUint32(uint32(len(vsQuestBets))) bf.WriteUint16(0) // Unk for i := range vsQuestItems { bf.WriteUint16(vsQuestItems[i]) } for i := range vsQuestBets { bf.WriteBool(vsQuestBets[i].IsTicket) bf.WriteUint8(9) bf.WriteUint16(7) bf.WriteUint32(vsQuestBets[i].Quantity) } bf.WriteUint16(totalCount) bf.WriteUint16(pkt.Offset) bf.Seek(0, io.SeekStart) bf.WriteUint16(returnedCount) doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfEnterTournamentQuest(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetUdBonusQuestInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetUdBonusQuestInfo) udBonusQuestInfos := []struct { Unk0 uint8 Unk1 uint8 StartTime uint32 // Unix timestamp (seconds) EndTime uint32 // Unix timestamp (seconds) Unk4 uint32 Unk5 uint8 Unk6 uint8 }{} // Blank stub array. resp := byteframe.NewByteFrame() resp.WriteUint8(uint8(len(udBonusQuestInfos))) for _, q := range udBonusQuestInfos { resp.WriteUint8(q.Unk0) resp.WriteUint8(q.Unk1) resp.WriteUint32(q.StartTime) resp.WriteUint32(q.EndTime) resp.WriteUint32(q.Unk4) resp.WriteUint8(q.Unk5) resp.WriteUint8(q.Unk6) } doAckBufSucceed(s, pkt.AckHandle, resp.Data()) }