From fbecbfa5712a29cb30f874361ba25139c0f6f095 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 10 Jun 2023 23:09:50 +1000 Subject: [PATCH] rewrite Earth packet handlers --- network/mhfpacket/msg_mhf_get_gem_info.go | 18 +- server/channelserver/handlers.go | 201 ++++++++++++++++------ server/channelserver/handlers_caravan.go | 50 ++---- server/channelserver/handlers_tower.go | 126 +++++++------- 4 files changed, 240 insertions(+), 155 deletions(-) diff --git a/network/mhfpacket/msg_mhf_get_gem_info.go b/network/mhfpacket/msg_mhf_get_gem_info.go index 36eb7948e..28638bfd2 100644 --- a/network/mhfpacket/msg_mhf_get_gem_info.go +++ b/network/mhfpacket/msg_mhf_get_gem_info.go @@ -11,8 +11,13 @@ import ( // MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO type MsgMhfGetGemInfo struct { AckHandle uint32 - Unk uint32 - Unk1 []byte + Unk0 uint32 + Unk1 uint32 + Unk2 int32 + Unk3 int32 + Unk4 int32 + Unk5 int32 + Unk6 int32 } // Opcode returns the ID associated with this packet type. @@ -23,8 +28,13 @@ func (m *MsgMhfGetGemInfo) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk = bf.ReadUint32() - m.Unk1 = bf.ReadBytes(24) + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + m.Unk3 = bf.ReadInt32() + m.Unk4 = bf.ReadInt32() + m.Unk5 = bf.ReadInt32() + m.Unk6 = bf.ReadInt32() return nil } diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 3f19cd99c..26cd3355b 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -38,6 +38,18 @@ func stubGetNoResults(s *Session, ackHandle uint32) { doAckBufSucceed(s, ackHandle, resp.Data()) } +func doAckEarthSucceed(s *Session, ackHandle uint32, data []*byteframe.ByteFrame) { + bf := byteframe.NewByteFrame() + bf.WriteUint32(uint32(s.server.erupeConfig.DevModeOptions.EarthIDOverride)) + bf.WriteUint32(0) + bf.WriteUint32(0) + bf.WriteUint32(uint32(len(data))) + for i := range data { + bf.WriteBytes(data[i].Data()) + } + doAckBufSucceed(s, ackHandle, bf.Data()) +} + func doAckBufSucceed(s *Session, ackHandle uint32, data []byte) { s.QueueSendMHF(&mhfpacket.MsgSysAck{ AckHandle: ackHandle, @@ -1648,18 +1660,15 @@ func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) { } } - bf := byteframe.NewByteFrame() - bf.WriteUint32(uint32(s.server.erupeConfig.DevModeOptions.EarthIDOverride)) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(uint32(len(earthValues))) + var data []*byteframe.ByteFrame for _, i := range earthValues { + bf := byteframe.NewByteFrame() for _, j := range i.Value { bf.WriteUint32(j) } + data = append(data, bf) } - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfDebugPostValue(s *Session, p mhfpacket.MHFPacket) {} @@ -1672,56 +1681,142 @@ func handleMsgMhfGetRandFromTable(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetSenyuDailyCount(s *Session, p mhfpacket.MHFPacket) {} +type SeibattleTimetable struct { + Start time.Time + End time.Time +} + +type SeibattleKeyScore struct { + Unk0 uint8 + Unk1 int32 +} + +type SeibattleCareer struct { + Unk0 uint16 + Unk1 uint16 + Unk2 uint16 +} + +type SeibattleOpponent struct { + Unk0 int32 + Unk1 int8 +} + +type SeibattleConventionResult struct { + Unk0 uint32 + Unk1 uint16 + Unk2 uint16 + Unk3 uint16 + Unk4 uint16 +} + +type SeibattleCharScore struct { + Unk0 uint32 +} + +type SeibattleCurResult struct { + Unk0 uint32 + Unk1 uint16 + Unk2 uint16 + Unk3 uint16 +} + +type Seibattle struct { + Timetable []SeibattleTimetable + KeyScore []SeibattleKeyScore + Career []SeibattleCareer + Opponent []SeibattleOpponent + ConventionResult []SeibattleConventionResult + CharScore []SeibattleCharScore + CurResult []SeibattleCurResult +} + func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetSeibattle) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) // Unk - bf.WriteUint32(0) // Unk - bf.WriteUint32(0) // Unk - bf.WriteUint32(1) // Entries - - switch pkt.Type { - case 1: // Timetable - bf.Seek(-4, 1) - bf.WriteUint32(3) - - bf.WriteUint32(uint32(TimeMidnight().Unix())) - bf.WriteUint32(uint32(TimeMidnight().Add(time.Hour * 8).Unix())) - - bf.WriteUint32(uint32(TimeMidnight().Add(time.Hour * 8).Unix())) - bf.WriteUint32(uint32(TimeMidnight().Add(time.Hour * 16).Unix())) - - bf.WriteUint32(uint32(TimeMidnight().Add(time.Hour * 16).Unix())) - bf.WriteUint32(uint32(TimeMidnight().Add(time.Hour * 24).Unix())) - case 2: // Reward - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 16)) - return - case 3: // Key score? - bf.WriteUint8(0) - bf.WriteInt32(0) - case 4: // Career? - bf.WriteUint16(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - case 5: // Opponent? - bf.WriteInt32(1) - bf.WriteInt8(1) - case 6: // Convention result? - bf.WriteUint32(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - case 7: // Char score? - bf.WriteUint32(0) - case 8: // Cur result? - bf.WriteUint32(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - bf.WriteUint16(0) + var data []*byteframe.ByteFrame + seibattle := Seibattle{ + Timetable: []SeibattleTimetable{ + {TimeMidnight(), TimeMidnight().Add(time.Hour * 8)}, + {TimeMidnight().Add(time.Hour * 8), TimeMidnight().Add(time.Hour * 16)}, + {TimeMidnight().Add(time.Hour * 16), TimeMidnight().Add(time.Hour * 24)}, + }, + KeyScore: []SeibattleKeyScore{ + {0, 0}, + }, + Career: []SeibattleCareer{ + {0, 0, 0}, + }, + Opponent: []SeibattleOpponent{ + {1, 1}, + }, + ConventionResult: []SeibattleConventionResult{ + {0, 0, 0, 0, 0}, + }, + CharScore: []SeibattleCharScore{ + {0}, + }, + CurResult: []SeibattleCurResult{ + {0, 0, 0, 0}, + }, } - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + switch pkt.Type { + case 1: + for _, timetable := range seibattle.Timetable { + bf := byteframe.NewByteFrame() + bf.WriteUint32(uint32(timetable.Start.Unix())) + bf.WriteUint32(uint32(timetable.End.Unix())) + data = append(data, bf) + } + case 3: // Key score? + for _, keyScore := range seibattle.KeyScore { + bf := byteframe.NewByteFrame() + bf.WriteUint8(keyScore.Unk0) + bf.WriteInt32(keyScore.Unk1) + data = append(data, bf) + } + case 4: // Career? + for _, career := range seibattle.Career { + bf := byteframe.NewByteFrame() + bf.WriteUint16(career.Unk0) + bf.WriteUint16(career.Unk1) + bf.WriteUint16(career.Unk2) + data = append(data, bf) + } + case 5: // Opponent? + for _, opponent := range seibattle.Opponent { + bf := byteframe.NewByteFrame() + bf.WriteInt32(opponent.Unk0) + bf.WriteInt8(opponent.Unk1) + data = append(data, bf) + } + case 6: // Convention result? + for _, conventionResult := range seibattle.ConventionResult { + bf := byteframe.NewByteFrame() + bf.WriteUint32(conventionResult.Unk0) + bf.WriteUint16(conventionResult.Unk1) + bf.WriteUint16(conventionResult.Unk2) + bf.WriteUint16(conventionResult.Unk3) + bf.WriteUint16(conventionResult.Unk4) + data = append(data, bf) + } + case 7: // Char score? + for _, charScore := range seibattle.CharScore { + bf := byteframe.NewByteFrame() + bf.WriteUint32(charScore.Unk0) + data = append(data, bf) + } + case 8: // Cur result? + for _, curResult := range seibattle.CurResult { + bf := byteframe.NewByteFrame() + bf.WriteUint32(curResult.Unk0) + bf.WriteUint16(curResult.Unk1) + bf.WriteUint16(curResult.Unk2) + bf.WriteUint16(curResult.Unk3) + data = append(data, bf) + } + } + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_caravan.go b/server/channelserver/handlers_caravan.go index 547019e68..c90f44812 100644 --- a/server/channelserver/handlers_caravan.go +++ b/server/channelserver/handlers_caravan.go @@ -42,37 +42,32 @@ type Ryoudama struct { func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetRyoudama) - - bf := byteframe.NewByteFrame() - bf.WriteUint32(uint32(s.server.erupeConfig.DevModeOptions.EarthIDOverride)) - bf.WriteUint32(0) - bf.WriteUint32(0) - + var data []*byteframe.ByteFrame ryoudama := Ryoudama{Score: []int32{0}} switch pkt.Request2 { case 4: - bf.WriteUint32(uint32(len(ryoudama.Score))) for _, score := range ryoudama.Score { + bf := byteframe.NewByteFrame() bf.WriteInt32(score) + data = append(data, bf) } case 5: - bf.WriteUint32(uint32(len(ryoudama.CharInfo))) for _, info := range ryoudama.CharInfo { + bf := byteframe.NewByteFrame() bf.WriteUint32(info.CID) bf.WriteInt32(info.Unk0) bf.WriteBytes(stringsupport.PaddedString(info.Name, 14, true)) + data = append(data, bf) } case 6: - bf.WriteUint32(uint32(len(ryoudama.BoostInfo))) for _, info := range ryoudama.BoostInfo { + bf := byteframe.NewByteFrame() bf.WriteUint32(uint32(info.Start.Unix())) bf.WriteUint32(uint32(info.End.Unix())) + data = append(data, bf) } - default: - bf.WriteUint32(0) } - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {} @@ -90,30 +85,19 @@ func handleMsgMhfPostTinyBin(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfCaravanMyScore) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) // Entries - + var data []*byteframe.ByteFrame /* bf.WriteInt32(0) bf.WriteInt32(0) bf.WriteInt32(0) bf.WriteInt32(0) */ - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfCaravanRanking) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) // Entries - + var data []*byteframe.ByteFrame /* RYOUDAN bf.WriteInt32(1) bf.WriteUint32(2) @@ -124,22 +108,16 @@ func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt32(1) bf.WriteBytes(stringsupport.PaddedString("Test", 14, true)) */ - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfCaravanMyRank(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfCaravanMyRank) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) // Entries - + var data []*byteframe.ByteFrame /* bf.WriteInt32(0) bf.WriteInt32(0) bf.WriteInt32(0) */ - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index d5766772b..1bec51dde 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -8,50 +8,43 @@ import ( func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetTowerInfo) - var data []byte - var err error - /* - type: - 1 == TOWER_RANK_POINT, - 2 == GET_OWN_TOWER_SKILL - 3 == GET_OWN_TOWER_LEVEL_V3 - 4 == TOWER_TOUHA_HISTORY - 5 = ? + var data []*byteframe.ByteFrame + type TowerInfo struct { + TRP []uint64 + TowerSkill [][]byte // 132 bytes + TowerHistory [][]byte // 20 bytes + } - [] = type - req - resp + towerInfo := TowerInfo{ + TRP: []uint64{0}, + TowerSkill: [][]byte{make([]byte, 132)}, + TowerHistory: [][]byte{make([]byte, 20)}, + } - 01 1d 01 fc 00 09 [00 00 00 01] 00 00 00 02 00 00 00 00 - 00 12 01 fc 00 09 01 00 00 18 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 + // Example data + // towerInfo.TowerSkill[0], _ = hex.DecodeString("0000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - 01 1d 01 fc 00 0a [00 00 00 02] 00 00 00 00 00 00 00 00 - 00 12 01 fc 00 0a 01 00 00 94 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - 01 1d 01 ff 00 0f [00 00 00 04] 00 00 00 00 00 00 00 00 - 00 12 01 ff 00 0f 01 00 00 24 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - 01 1d 01 fc 00 0b [00 00 00 05] 00 00 00 00 00 00 00 00 - 00 12 01 fc 00 0b 01 00 00 10 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 00 - */ switch pkt.InfoType { - case mhfpacket.TowerInfoTypeTowerRankPoint: - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000") - case mhfpacket.TowerInfoTypeGetOwnTowerSkill: - //data, err = hex.DecodeString("0A218EAD000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - case mhfpacket.TowerInfoTypeGetOwnTowerLevelV3: - panic("No known response values for GetOwnTowerLevelV3") - case mhfpacket.TowerInfoTypeTowerTouhaHistory: - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000000000000000000000000000") - case mhfpacket.TowerInfoTypeUnk5: - data, err = hex.DecodeString("0A218EAD000000000000000000000000") + case 1: + for _, trp := range towerInfo.TRP { + bf := byteframe.NewByteFrame() + bf.WriteUint64(trp) + data = append(data, bf) + } + case 2: + for _, skills := range towerInfo.TowerSkill { + bf := byteframe.NewByteFrame() + bf.WriteBytes(skills) + data = append(data, bf) + } + case 4: + for _, history := range towerInfo.TowerHistory { + bf := byteframe.NewByteFrame() + bf.WriteBytes(history) + data = append(data, bf) + } } - - if err != nil { - stubGetNoResults(s, pkt.AckHandle) - } - doAckBufSucceed(s, pkt.AckHandle, data) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) { @@ -85,32 +78,37 @@ func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {} +type WeeklySeibatuRankingReward struct { + Unk0 int32 + Unk1 int32 + Unk2 uint32 + Unk3 int32 + Unk4 int32 + Unk5 int32 +} + func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(1) // Entries - - bf.WriteInt32(0) - bf.WriteInt32(0) - bf.WriteUint32(0) - bf.WriteInt32(0) - bf.WriteInt32(0) - bf.WriteInt32(0) - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + var data []*byteframe.ByteFrame + weeklySeibatuRankingRewards := []WeeklySeibatuRankingReward{ + {0, 0, 0, 0, 0, 0}, + } + for _, reward := range weeklySeibatuRankingRewards { + bf := byteframe.NewByteFrame() + bf.WriteInt32(reward.Unk0) + bf.WriteInt32(reward.Unk1) + bf.WriteUint32(reward.Unk2) + bf.WriteInt32(reward.Unk3) + bf.WriteInt32(reward.Unk4) + bf.WriteInt32(reward.Unk5) + data = append(data, bf) + } + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfPresentBox) - bf := byteframe.NewByteFrame() - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) // Entries - + var data []*byteframe.ByteFrame /* bf.WriteUint32(0) bf.WriteInt32(0) @@ -124,13 +122,17 @@ func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt32(0) bf.WriteInt32(0) */ - - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetGemInfo) - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + var data []*byteframe.ByteFrame + /* + bf.WriteUint16(0) + bf.WriteUint16(0) + */ + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {}