diff --git a/server/channelserver/handlers_campaign.go b/server/channelserver/handlers_campaign.go index bd6ee0552..4cc61a1d3 100644 --- a/server/channelserver/handlers_campaign.go +++ b/server/channelserver/handlers_campaign.go @@ -2,16 +2,128 @@ package channelserver import ( "erupe-ce/common/byteframe" + ps "erupe-ce/common/pascalstring" + "erupe-ce/common/stringsupport" "erupe-ce/network/mhfpacket" + "time" ) +type CampaignEvent struct { + ID uint32 + Unk0 uint32 + MinHR int16 + MaxHR int16 + MinSR int16 + MaxSR int16 + MinGR int16 + MaxGR int16 + Unk1 uint16 + Unk2 uint8 + Unk3 uint8 + Unk4 uint16 + Unk5 uint16 + Start time.Time + End time.Time + Unk6 uint8 + String0 string + String1 string + String2 string + String3 string + Link string + Prefix string + Categories []uint16 +} + +type CampaignCategory struct { + ID uint16 + Type uint8 + Title string + Description string +} + +type CampaignLink struct { + CategoryID uint16 + CampaignID uint32 +} + func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateCampaign) bf := byteframe.NewByteFrame() - bf.WriteUint8(0) - bf.WriteUint8(0) - bf.WriteUint8(0) - bf.WriteUint8(0) + + events := []CampaignEvent{} + categories := []CampaignCategory{} + var campaignLinks []CampaignLink + + if len(events) > 255 { + bf.WriteUint8(255) + bf.WriteUint16(uint16(len(events))) + } else { + bf.WriteUint8(uint8(len(events))) + } + for _, event := range events { + bf.WriteUint32(event.ID) + bf.WriteUint32(event.Unk0) + bf.WriteInt16(event.MinHR) + bf.WriteInt16(event.MaxHR) + bf.WriteInt16(event.MinSR) + bf.WriteInt16(event.MaxSR) + bf.WriteInt16(event.MinGR) + bf.WriteInt16(event.MaxGR) + bf.WriteUint16(event.Unk1) + bf.WriteUint8(event.Unk2) + bf.WriteUint8(event.Unk3) + bf.WriteUint16(event.Unk4) + bf.WriteUint16(event.Unk5) + bf.WriteUint32(uint32(event.Start.Unix())) + bf.WriteUint32(uint32(event.End.Unix())) + bf.WriteUint8(event.Unk6) + ps.Uint8(bf, event.String0, true) + ps.Uint8(bf, event.String1, true) + ps.Uint8(bf, event.String2, true) + ps.Uint8(bf, event.String3, true) + ps.Uint8(bf, event.Link, true) + for i := range event.Categories { + campaignLinks = append(campaignLinks, CampaignLink{event.Categories[i], event.ID}) + } + } + + if len(events) > 255 { + bf.WriteUint8(255) + bf.WriteUint16(uint16(len(events))) + } else { + bf.WriteUint8(uint8(len(events))) + } + for _, event := range events { + bf.WriteUint32(event.ID) + bf.WriteUint8(1) // Always 1? + bf.WriteBytes([]byte(event.Prefix)) + } + + if len(categories) > 255 { + bf.WriteUint8(255) + bf.WriteUint16(uint16(len(categories))) + } else { + bf.WriteUint8(uint8(len(categories))) + } + for _, category := range categories { + bf.WriteUint16(category.ID) + bf.WriteUint8(category.Type) + bf.WriteUint8(uint8(len(category.Title))) + bf.WriteUint8(uint8(len(category.Description))) + bf.WriteBytes(stringsupport.UTF8ToSJIS(category.Title)) + bf.WriteBytes(stringsupport.UTF8ToSJIS(category.Description)) + } + + if len(campaignLinks) > 255 { + bf.WriteUint8(255) + bf.WriteUint16(uint16(len(campaignLinks))) + } else { + bf.WriteUint8(uint8(len(campaignLinks))) + } + for _, link := range campaignLinks { + bf.WriteUint16(link.CategoryID) + bf.WriteUint32(link.CampaignID) + } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } @@ -25,7 +137,9 @@ func handleMsgMhfStateCampaign(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfApplyCampaign(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfApplyCampaign) - doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + bf := byteframe.NewByteFrame() + bf.WriteUint32(1) + doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfEnumerateItem(s *Session, p mhfpacket.MHFPacket) {