diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 33061acd3..0e1d119f0 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -646,7 +646,12 @@ func handleMsgSysReserveStage(s *Session, p mhfpacket.MHFPacket) { stage.Lock() defer stage.Unlock() - if uint16(len(stage.reservedClientSlots)) < stage.maxPlayers { + // Quick fix to allow readying up while party is full, more investigation needed + // Reserve stage is also sent when a player is ready, probably need to parse the + // request a little more thoroughly. + if _, exists := stage.reservedClientSlots[s.charID]; exists { + s.QueueAck(pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + } else if uint16(len(stage.reservedClientSlots)) < stage.maxPlayers { // Add the charID to the stage's reservation map stage.reservedClientSlots[s.charID] = nil @@ -906,9 +911,9 @@ func handleMsgSysCheckSemaphore(s *Session, p mhfpacket.MHFPacket) {} func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {} func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgSysLoadRegister) - data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - doSizedAckResp(s, pkt.AckHandle, data) + pkt := p.(*mhfpacket.MsgSysLoadRegister) + data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + doSizedAckResp(s, pkt.AckHandle, data) } func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} @@ -1338,12 +1343,12 @@ func handleMsgMhfEntryRookieGuild(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { // local files are easier for now, probably best would be to generate dynamically pkt := p.(*mhfpacket.MsgMhfEnumerateQuest) - data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("questlists/list_%d.bin",pkt.QuestList))) + data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("questlists/list_%d.bin", pkt.QuestList))) if err != nil { - fmt.Printf("questlists/list_%d.bin",pkt.QuestList) + fmt.Printf("questlists/list_%d.bin", pkt.QuestList) stubEnumerateNoResults(s, pkt.AckHandle) } else { - doSizedAckResp(s, pkt.AckHandle, data) + doSizedAckResp(s, pkt.AckHandle, data) } // Update the client's rights as well: updateRights(s) @@ -1415,7 +1420,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { stubEnumerateNoResults(s, pkt.AckHandle) } else if pkt.ShopType == 7 { // GCP conversion store - if pkt.ShopID == 0{ + if pkt.ShopID == 0 { // Items to GCP exchange. Gou Tickets, Shiten Tickets, GP Tickets data, _ := hex.DecodeString("000300033a9186fb000033860000000a000100000000000000000000000000000000097fdb1c0000067e0000000a0001000000000000000000000000000000001374db29000027c300000064000100000000000000000000000000000000") doSizedAckResp(s, pkt.AckHandle, data) @@ -1425,7 +1430,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { } else if pkt.ShopType == 8 { // Dive Defense sections // 00 = normal level limited exchange store, 05 = GCP skill store, 07 = limited quantity exchange - if pkt.ShopID == 5{ + if pkt.ShopID == 5 { // diva defense skill level limited store data, _ := hex.DecodeString("001f001f2c9365c1000000010000001e000a0000000000000000000a0000000000001979f1c2000000020000003c000a0000000000000000000a0000000000003e5197df000000030000003c000a0000000000000000000a000000000000219337c0000000040000001e000a0000000000000000000a00000000000009b24c9d000000140000001e000a0000000000000000000a0000000000001f1d496e000000150000001e000a0000000000000000000a0000000000003b918fcb000000160000003c000a0000000000000000000a0000000000000b7fd81c000000170000003c000a0000000000000000000a0000000000001374f239000000180000003c000a0000000000000000000a00000000000026950cba0000001c0000003c000a0000000000000000000a0000000000003797eae70000001d0000003c000a012b000000000000000a00000000000015758ad8000000050000003c00000000000000000000000a0000000000003c7035050000000600000050000a0000000000000001000a00000000000024f3b5560000000700000050000a0000000000000001000a00000000000000b600330000000800000050000a0000000000000001000a0000000000002efdce840000001900000050000a0000000000000001000a0000000000002d9365f10000001a00000050000a0000000000000001000a0000000000001979f3420000001f00000050000a012b000000000001000a0000000000003f5397cf0000002000000050000a012b000000000001000a000000000000319337c00000002100000050000a012b000000000001000a00000000000008b04cbd0000000900000064000a0000000000000002000a0000000000000b1d4b6e0000000a00000064000a0000000000000002000a0000000000003b918feb0000000b00000064000a0000000000000002000a0000000000001b7fd81c0000000c00000064000a0000000000000002000a0000000000001276f2290000000d00000064000a0000000000000002000a00000000000022950cba0000000e000000c8000a0000000000000002000a0000000000003697ead70000000f000001f4000a0000000000000003000a00000000000005758a5800000010000003e8000a0000000000000003000a0000000000003c7035250000001b000001f4000a0000000000010003000a00000000000034f3b5d60000001e00000064000a012b000000000003000a00000000000000b600030000002200000064000a0000000000010003000a000000000000") doSizedAckResp(s, pkt.AckHandle, data) @@ -1703,36 +1708,36 @@ func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetWeeklySchedule) //japanese timestamps as client needs to be in japanese locale var t = time.Now().In(time.FixedZone("UTC+9", 9*60*60)) - year,month,day := t.Date() + year, month, day := t.Date() midnight := time.Date(year, month, day, 0, 0, 0, 0, t.Location()).Add(time.Hour) // ActiveFeatures is a bit field, 0x3FFF is all 14 active features. // Long term it should probably be made persistent and simply cycle a couple daily // Times seem to need to be midnight which is likely why matching timezone was required originally eventSchedules := []struct { - StartTime time.Time - ActiveFeatures uint32 - Unk1 uint16 + StartTime time.Time + ActiveFeatures uint32 + Unk1 uint16 }{ { - StartTime: midnight.Add(-24*time.Hour), // midnight of previous day. - ActiveFeatures: 0x3FFF, - Unk1: 0, + StartTime: midnight.Add(-24 * time.Hour), // midnight of previous day. + ActiveFeatures: 0x3FFF, + Unk1: 0, }, { - StartTime: midnight, // midnight of this day. - ActiveFeatures: 0x3FFF, - Unk1: 0, + StartTime: midnight, // midnight of this day. + ActiveFeatures: 0x3FFF, + Unk1: 0, }, { - StartTime: midnight.Add(24*time.Hour), // midnight of following day. - ActiveFeatures: 0x3FFF, - Unk1: 0, + StartTime: midnight.Add(24 * time.Hour), // midnight of following day. + ActiveFeatures: 0x3FFF, + Unk1: 0, }, } resp := byteframe.NewByteFrame() - resp.WriteUint8(uint8(len(eventSchedules))) // Entry count, client only parses the first 7 or 8. - resp.WriteUint32(uint32(t.Add(-5*time.Minute).Unix())) // 5 minutes ago server time + resp.WriteUint8(uint8(len(eventSchedules))) // Entry count, client only parses the first 7 or 8. + resp.WriteUint32(uint32(t.Add(-5 * time.Minute).Unix())) // 5 minutes ago server time for _, es := range eventSchedules { resp.WriteUint32(uint32(es.StartTime.Unix())) resp.WriteUint32(es.ActiveFeatures) @@ -2261,7 +2266,7 @@ func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetEarthValue) var earthValues []struct{ Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 } - if pkt.ReqType == 3{ + if pkt.ReqType == 3 { earthValues = []struct { Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 }{ @@ -2280,7 +2285,7 @@ func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) { Unk2: 0x012C, }, } - } else if pkt.ReqType == 2{ + } else if pkt.ReqType == 2 { earthValues = []struct { Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 }{ @@ -2294,19 +2299,19 @@ func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) { Unk1: 0x0737, }, } - }else if pkt.ReqType == 1{ - earthValues = []struct { - Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 - }{ - // JP simply sent 01 and 02 respectively - { - Unk0: 0x01, - Unk1: 0x0138, - }, - { - Unk0: 0x02, - Unk1: 0x63, - }, + } else if pkt.ReqType == 1 { + earthValues = []struct { + Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 + }{ + // JP simply sent 01 and 02 respectively + { + Unk0: 0x01, + Unk1: 0x0138, + }, + { + Unk0: 0x02, + Unk1: 0x63, + }, } } @@ -2581,23 +2586,23 @@ func handleMsgMhfUseKeepLoginBoost(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetUdSchedule) var t = time.Now().In(time.FixedZone("UTC+9", 9*60*60)) - year,month,day := t.Date() + year, month, day := t.Date() midnight := time.Date(year, month, day, 0, 0, 0, 0, t.Location()).Add(time.Hour) // Events with time limits are Festival with Sign up, Soul Week and Winners Weeks // Diva Defense with Prayer, Interception and Song weeks // Mezeporta Festival with simply 'available' being a weekend thing resp := byteframe.NewByteFrame() - resp.WriteUint32(0x1d5fda5c) // Unk (1d5fda5c, 0b5397df) - resp.WriteUint32(uint32(midnight.Add(-24*21*time.Hour).Unix())) // Week 1 Timestamp, Festi start? - resp.WriteUint32(uint32(midnight.Add(-24*14*time.Hour).Unix())) // Week 2 Timestamp - resp.WriteUint32(uint32(midnight.Add(-24*14*time.Hour).Unix())) // Week 2 Timestamp - resp.WriteUint32(uint32(midnight.Add(24*7*time.Hour).Unix())) // Diva Defense Interception - resp.WriteUint32(uint32(midnight.Add(24*7*time.Hour).Unix())) // Diva Defense Interception - resp.WriteUint32(uint32(midnight.Add(24*14*time.Hour).Unix())) // Diva Defense Greeting Song - resp.WriteUint16(0x19) // Unk - resp.WriteUint16(0x2d) // Unk - resp.WriteUint16(0x02) // Unk - resp.WriteUint16(0x02) // Unk + resp.WriteUint32(0x1d5fda5c) // Unk (1d5fda5c, 0b5397df) + resp.WriteUint32(uint32(midnight.Add(-24 * 21 * time.Hour).Unix())) // Week 1 Timestamp, Festi start? + resp.WriteUint32(uint32(midnight.Add(-24 * 14 * time.Hour).Unix())) // Week 2 Timestamp + resp.WriteUint32(uint32(midnight.Add(-24 * 14 * time.Hour).Unix())) // Week 2 Timestamp + resp.WriteUint32(uint32(midnight.Add(24 * 7 * time.Hour).Unix())) // Diva Defense Interception + resp.WriteUint32(uint32(midnight.Add(24 * 7 * time.Hour).Unix())) // Diva Defense Interception + resp.WriteUint32(uint32(midnight.Add(24 * 14 * time.Hour).Unix())) // Diva Defense Greeting Song + resp.WriteUint16(0x19) // Unk + resp.WriteUint16(0x2d) // Unk + resp.WriteUint16(0x02) // Unk + resp.WriteUint16(0x02) // Unk doSizedAckResp(s, pkt.AckHandle, resp.Data()) } @@ -2629,10 +2634,10 @@ func handleMsgMhfGetUdInfo(s *Session, p mhfpacket.MHFPacket) { } func handleMsgMhfGetKijuInfo(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfGetKijuInfo) - // Temporary canned response - data, _ := hex.DecodeString("04965C959782CC8B468EEC00000000000000000000000000000000000000000000815C82A082E782B582DC82A982BA82CC82AB82B682E3815C0A965C959782C682CD96D282E98E7682A281420A95B782AD8ED282C997458B4382F0975E82A682E98142000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001018BAD8C8282CC8B468EEC00000000000000000000000000000000000000000000815C82AB82E582A482B082AB82CC82AB82B682E3815C0A8BAD8C8282C682CD8BAD82A290BA904681420A95B782AD8ED282CC97CD82F08CA482AC909F82DC82B78142200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003138C8B8F5782CC8B468EEC00000000000000000000000000000000000000000000815C82AF82C182B582E382A482CC82AB82B682E3815C0A8C8B8F5782C682CD8A6D8CC582BD82E9904D978A81420A8F5782DF82E982D982C782C98EEB906C82BD82BF82CC90B8905F97CD82C682C882E9814200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041189CC8CEC82CC8B468EEC00000000000000000000000000000000000000000000815C82A482BD82DC82E082E882CC82AB82B682E3815C0A89CC8CEC82C682CD89CC955082CC8CEC82E881420A8F5782DF82E982D982C782C98EEB906C82BD82BF82CC8E7882A682C682C882E9814220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000212") - doSizedAckResp(s, pkt.AckHandle, data) + pkt := p.(*mhfpacket.MsgMhfGetKijuInfo) + // Temporary canned response + data, _ := hex.DecodeString("04965C959782CC8B468EEC00000000000000000000000000000000000000000000815C82A082E782B582DC82A982BA82CC82AB82B682E3815C0A965C959782C682CD96D282E98E7682A281420A95B782AD8ED282C997458B4382F0975E82A682E98142000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001018BAD8C8282CC8B468EEC00000000000000000000000000000000000000000000815C82AB82E582A482B082AB82CC82AB82B682E3815C0A8BAD8C8282C682CD8BAD82A290BA904681420A95B782AD8ED282CC97CD82F08CA482AC909F82DC82B78142200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003138C8B8F5782CC8B468EEC00000000000000000000000000000000000000000000815C82AF82C182B582E382A482CC82AB82B682E3815C0A8C8B8F5782C682CD8A6D8CC582BD82E9904D978A81420A8F5782DF82E982D982C782C98EEB906C82BD82BF82CC90B8905F97CD82C682C882E9814200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041189CC8CEC82CC8B468EEC00000000000000000000000000000000000000000000815C82A482BD82DC82E082E882CC82AB82B682E3815C0A89CC8CEC82C682CD89CC955082CC8CEC82E881420A8F5782DF82E982D982C782C98EEB906C82BD82BF82CC8E7882A682C682C882E9814220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000212") + doSizedAckResp(s, pkt.AckHandle, data) } func handleMsgMhfSetKiju(s *Session, p mhfpacket.MHFPacket) {} @@ -2865,7 +2870,7 @@ func handleMsgMhfGetUdTacticsPoint(s *Session, p mhfpacket.MHFPacket) { } func handleMsgMhfAddUdTacticsPoint(s *Session, p mhfpacket.MHFPacket) { -pkt := p.(*mhfpacket.MsgMhfAddUdTacticsPoint) + pkt := p.(*mhfpacket.MsgMhfAddUdTacticsPoint) stubEnumerateNoResults(s, pkt.AckHandle) }