From bd42b5d0c24adfd454e0c80b95752768ca61b25b Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 01:27:46 +1100 Subject: [PATCH 01/27] various changes --- network/mhfpacket/msg_mhf_read_mercenary_m.go | 4 +- network/mhfpacket/msg_mhf_read_mercenary_w.go | 4 +- network/mhfpacket/msg_mhf_save_mercenary.go | 16 +++--- patch-schema/rasta-id.sql | 9 +++ server/channelserver/handlers_mercenary.go | 56 +++++++++++-------- 5 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 patch-schema/rasta-id.sql diff --git a/network/mhfpacket/msg_mhf_read_mercenary_m.go b/network/mhfpacket/msg_mhf_read_mercenary_m.go index 75c973a74..957b35f3a 100644 --- a/network/mhfpacket/msg_mhf_read_mercenary_m.go +++ b/network/mhfpacket/msg_mhf_read_mercenary_m.go @@ -12,7 +12,7 @@ import ( type MsgMhfReadMercenaryM struct { AckHandle uint32 CharID uint32 - Unk0 uint32 + MercID uint32 } // Opcode returns the ID associated with this packet type. @@ -24,7 +24,7 @@ func (m *MsgMhfReadMercenaryM) Opcode() network.PacketID { func (m *MsgMhfReadMercenaryM) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.CharID = bf.ReadUint32() - m.Unk0 = bf.ReadUint32() + m.MercID = bf.ReadUint32() return nil } diff --git a/network/mhfpacket/msg_mhf_read_mercenary_w.go b/network/mhfpacket/msg_mhf_read_mercenary_w.go index c80afee14..fee9fc19d 100644 --- a/network/mhfpacket/msg_mhf_read_mercenary_w.go +++ b/network/mhfpacket/msg_mhf_read_mercenary_w.go @@ -11,7 +11,7 @@ import ( // MsgMhfReadMercenaryW represents the MSG_MHF_READ_MERCENARY_W type MsgMhfReadMercenaryW struct { AckHandle uint32 - Unk0 bool + GetPact bool Unk1 uint8 Unk2 uint16 // Hardcoded 0 in the binary } @@ -24,7 +24,7 @@ func (m *MsgMhfReadMercenaryW) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadBool() + m.GetPact = bf.ReadBool() m.Unk1 = bf.ReadUint8() m.Unk2 = bf.ReadUint16() return nil diff --git a/network/mhfpacket/msg_mhf_save_mercenary.go b/network/mhfpacket/msg_mhf_save_mercenary.go index 3aa2b0311..8a9ddb9f8 100644 --- a/network/mhfpacket/msg_mhf_save_mercenary.go +++ b/network/mhfpacket/msg_mhf_save_mercenary.go @@ -10,11 +10,10 @@ import ( // MsgMhfSaveMercenary represents the MSG_MHF_SAVE_MERCENARY type MsgMhfSaveMercenary struct { - AckHandle uint32 - GCP uint32 - Unk0 uint32 - MercData []byte - Unk1 uint32 + AckHandle uint32 + GCP uint32 + PactMercID uint32 + MercData []byte } // Opcode returns the ID associated with this packet type. @@ -27,9 +26,10 @@ func (m *MsgMhfSaveMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie m.AckHandle = bf.ReadUint32() bf.ReadUint32() // lenData m.GCP = bf.ReadUint32() - m.Unk0 = bf.ReadUint32() - m.MercData = bf.ReadBytes(uint(bf.ReadUint32())) - m.Unk1 = bf.ReadUint32() + m.PactMercID = bf.ReadUint32() + dataSize := bf.ReadUint32() + _ = bf.ReadUint32() // Merc index? + m.MercData = bf.ReadBytes(uint(dataSize)) return nil } diff --git a/patch-schema/rasta-id.sql b/patch-schema/rasta-id.sql new file mode 100644 index 000000000..14541e378 --- /dev/null +++ b/patch-schema/rasta-id.sql @@ -0,0 +1,9 @@ +BEGIN; + +UPDATE characters SET savemercenary = NULL; + +ALTER TABLE characters ADD rasta_id INT; + +ALTER TABLE characters ADD pact_id INT; + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index bdeb924de..e6ba0b707 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "os" "path/filepath" + "time" ) // THERE ARE [PARTENER] [MERCENARY] [OTOMO AIRU] @@ -114,12 +115,6 @@ func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } -/////////////////////////////////////////// - -/////////////////////////////////////////// -/// MERCENARY // -/////////////////////////////////////////// - func handleMsgMhfMercenaryHuntdata(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfMercenaryHuntdata) if pkt.Unk0 == 1 { @@ -149,15 +144,11 @@ func handleMsgMhfEnumerateMercenaryLog(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfCreateMercenary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfCreateMercenary) - bf := byteframe.NewByteFrame() - var nextID uint32 - s.server.db.QueryRow("SELECT nextval('rasta_id_seq')").Scan(&nextID) - - bf.WriteUint32(nextID) // New MercID - bf.WriteUint32(0xDEADBEEF) // Unk - + _ = s.server.db.QueryRow("SELECT nextval('rasta_id_seq')").Scan(&nextID) + s.server.db.Exec("UPDATE characters SET rasta_id=$1 WHERE id=$2", nextID, s.charID) + bf.WriteUint32(nextID) doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) } @@ -165,29 +156,48 @@ func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSaveMercenary) dumpSaveData(s, pkt.MercData, "mercenary") if len(pkt.MercData) > 0 { - s.server.db.Exec("UPDATE characters SET savemercenary=$1 WHERE id=$2", pkt.MercData, s.charID) + temp := byteframe.NewByteFrameFromBytes(pkt.MercData) + s.server.db.Exec("UPDATE characters SET savemercenary=$1, rasta_id=$2 WHERE id=$3", pkt.MercData, temp.ReadUint32(), s.charID) } - s.server.db.Exec("UPDATE characters SET gcp=$1 WHERE id=$2", pkt.GCP, s.charID) + s.server.db.Exec("UPDATE characters SET gcp=$1, pact_id=$2 WHERE id=$3", pkt.GCP, pkt.PactMercID, s.charID) doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfReadMercenaryW) - if pkt.Unk0 { - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) + if pkt.GetPact { + var pactID uint32 + s.server.db.QueryRow("SELECT pact_id FROM characters WHERE id=$1", s.charID).Scan(&pactID) + if pactID > 0 { + var name string + var cid uint32 + s.server.db.QueryRow("SELECT name, id FROM characters WHERE rasta_id = $1", pactID).Scan(&name, &cid) + bf := byteframe.NewByteFrame() + bf.WriteBool(true) + bf.WriteUint32(pactID) + bf.WriteUint32(cid) + bf.WriteBool(true) + bf.WriteUint32(uint32(Time_Current_Adjusted().Unix())) + bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * 7).Unix())) + bf.WriteBytes(stringsupport.PaddedString(name, 18, true)) + bf.WriteBool(false) + } else { + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) + } return } var data []byte var gcp uint32 - s.server.db.QueryRow("SELECT savemercenary FROM characters WHERE id = $1", s.charID).Scan(&data) - s.server.db.QueryRow("SELECT COALESCE(gcp, 0) FROM characters WHERE id = $1", s.charID).Scan(&gcp) + s.server.db.QueryRow("SELECT savemercenary FROM characters WHERE id=$1", s.charID).Scan(&data) + s.server.db.QueryRow("SELECT COALESCE(gcp, 0) FROM characters WHERE id=$1", s.charID).Scan(&gcp) resp := byteframe.NewByteFrame() + resp.WriteUint16(0) if len(data) == 0 { - resp.WriteBytes(make([]byte, 3)) + resp.WriteBool(false) } else { - resp.WriteBytes(data[1:]) - resp.WriteUint32(0) // Unk + resp.WriteBool(true) + resp.WriteBytes(data) } resp.WriteUint32(gcp) doAckBufSucceed(s, pkt.AckHandle, resp.Data()) @@ -201,7 +211,7 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { if len(data) == 0 { resp.WriteBool(false) } else { - resp.WriteBytes(data[4:]) + resp.WriteBytes(data) } doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } From 753d21521112f51738d3cbbe75ef7fd56d601c0e Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 02:18:23 +1100 Subject: [PATCH 02/27] fix reading and cancelling rasta contracts --- .../mhfpacket/msg_mhf_contract_mercenary.go | 21 +++++++++++++------ server/channelserver/handlers_mercenary.go | 13 ++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/network/mhfpacket/msg_mhf_contract_mercenary.go b/network/mhfpacket/msg_mhf_contract_mercenary.go index 24919981b..60b935861 100644 --- a/network/mhfpacket/msg_mhf_contract_mercenary.go +++ b/network/mhfpacket/msg_mhf_contract_mercenary.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfContractMercenary represents the MSG_MHF_CONTRACT_MERCENARY -type MsgMhfContractMercenary struct{} +type MsgMhfContractMercenary struct { + AckHandle uint32 + PactMercID uint32 + CID uint32 + Unk bool +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfContractMercenary) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfContractMercenary) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfContractMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.PactMercID = bf.ReadUint32() + m.CID = bf.ReadUint32() + m.Unk = bf.ReadBool() + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index e6ba0b707..3f79d5502 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -181,6 +181,7 @@ func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * 7).Unix())) bf.WriteBytes(stringsupport.PaddedString(name, 18, true)) bf.WriteBool(false) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } else { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) } @@ -216,13 +217,11 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } -func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {} - -/////////////////////////////////////////// - -/////////////////////////////////////////// -/// OTOMO AIRU // -/////////////////////////////////////////// +func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfContractMercenary) + s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} func handleMsgMhfLoadOtomoAirou(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadOtomoAirou) From 1382e99fc6f59fdbfb7b6ce7146e84fbd0bd7e36 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 12:22:07 +1100 Subject: [PATCH 03/27] further decode merc packets --- network/mhfpacket/msg_mhf_contract_mercenary.go | 4 ++-- network/mhfpacket/msg_mhf_read_mercenary_w.go | 4 ++-- server/channelserver/handlers_mercenary.go | 16 +++++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/network/mhfpacket/msg_mhf_contract_mercenary.go b/network/mhfpacket/msg_mhf_contract_mercenary.go index 60b935861..a139dabb9 100644 --- a/network/mhfpacket/msg_mhf_contract_mercenary.go +++ b/network/mhfpacket/msg_mhf_contract_mercenary.go @@ -13,7 +13,7 @@ type MsgMhfContractMercenary struct { AckHandle uint32 PactMercID uint32 CID uint32 - Unk bool + Cancel bool } // Opcode returns the ID associated with this packet type. @@ -26,7 +26,7 @@ func (m *MsgMhfContractMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx. m.AckHandle = bf.ReadUint32() m.PactMercID = bf.ReadUint32() m.CID = bf.ReadUint32() - m.Unk = bf.ReadBool() + m.Cancel = bf.ReadBool() return nil } diff --git a/network/mhfpacket/msg_mhf_read_mercenary_w.go b/network/mhfpacket/msg_mhf_read_mercenary_w.go index fee9fc19d..3aa9597d9 100644 --- a/network/mhfpacket/msg_mhf_read_mercenary_w.go +++ b/network/mhfpacket/msg_mhf_read_mercenary_w.go @@ -11,7 +11,7 @@ import ( // MsgMhfReadMercenaryW represents the MSG_MHF_READ_MERCENARY_W type MsgMhfReadMercenaryW struct { AckHandle uint32 - GetPact bool + Op uint8 Unk1 uint8 Unk2 uint16 // Hardcoded 0 in the binary } @@ -24,7 +24,7 @@ func (m *MsgMhfReadMercenaryW) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.GetPact = bf.ReadBool() + m.Op = bf.ReadUint8() m.Unk1 = bf.ReadUint8() m.Unk2 = bf.ReadUint16() return nil diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index 3f79d5502..f13687d04 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -165,7 +165,7 @@ func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfReadMercenaryW) - if pkt.GetPact { + if pkt.Op > 0 { var pactID uint32 s.server.db.QueryRow("SELECT pact_id FROM characters WHERE id=$1", s.charID).Scan(&pactID) if pactID > 0 { @@ -177,10 +177,12 @@ func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(pactID) bf.WriteUint32(cid) bf.WriteBool(true) - bf.WriteUint32(uint32(Time_Current_Adjusted().Unix())) - bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * 7).Unix())) + bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -8).Unix())) + bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -1).Unix())) bf.WriteBytes(stringsupport.PaddedString(name, 18, true)) - bf.WriteBool(false) + if pkt.Op == 1 { + bf.WriteBool(false) + } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } else { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) @@ -219,7 +221,11 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfContractMercenary) - s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) + if pkt.Cancel { + s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) + } else { + s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, s.charID) + } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From c37755f7c3283a2d46b9da36f89e640d91caad83 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 14:40:27 +1100 Subject: [PATCH 04/27] further decode merc packets --- .../mhfpacket/msg_mhf_contract_mercenary.go | 4 +- server/channelserver/handlers_mercenary.go | 44 +++++++++++++------ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/network/mhfpacket/msg_mhf_contract_mercenary.go b/network/mhfpacket/msg_mhf_contract_mercenary.go index a139dabb9..1dad97253 100644 --- a/network/mhfpacket/msg_mhf_contract_mercenary.go +++ b/network/mhfpacket/msg_mhf_contract_mercenary.go @@ -13,7 +13,7 @@ type MsgMhfContractMercenary struct { AckHandle uint32 PactMercID uint32 CID uint32 - Cancel bool + Op uint8 } // Opcode returns the ID associated with this packet type. @@ -26,7 +26,7 @@ func (m *MsgMhfContractMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx. m.AckHandle = bf.ReadUint32() m.PactMercID = bf.ReadUint32() m.CID = bf.ReadUint32() - m.Cancel = bf.ReadBool() + m.Op = bf.ReadUint8() return nil } diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index f13687d04..6eea2a9a6 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -166,27 +166,42 @@ func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfReadMercenaryW) if pkt.Op > 0 { + bf := byteframe.NewByteFrame() var pactID uint32 + var name string + var cid uint32 + s.server.db.QueryRow("SELECT pact_id FROM characters WHERE id=$1", s.charID).Scan(&pactID) if pactID > 0 { - var name string - var cid uint32 s.server.db.QueryRow("SELECT name, id FROM characters WHERE rasta_id = $1", pactID).Scan(&name, &cid) - bf := byteframe.NewByteFrame() - bf.WriteBool(true) + bf.WriteUint8(1) // numLends bf.WriteUint32(pactID) bf.WriteUint32(cid) - bf.WriteBool(true) + bf.WriteBool(false) // ? bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -8).Unix())) bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -1).Unix())) bf.WriteBytes(stringsupport.PaddedString(name, 18, true)) - if pkt.Op == 1 { - bf.WriteBool(false) - } - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } else { - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) + bf.WriteUint8(0) } + + if pkt.Op < 2 { + var loans uint8 + temp := byteframe.NewByteFrame() + rows, _ := s.server.db.Query("SELECT name, id, pact_id FROM characters WHERE pact_id=(SELECT rasta_id FROM characters WHERE id=$1)", s.charID) + for rows.Next() { + loans++ + rows.Scan(&name, &cid, &pactID) + temp.WriteUint32(pactID) + temp.WriteUint32(cid) + temp.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -8).Unix())) + temp.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -1).Unix())) + temp.WriteBytes(stringsupport.PaddedString(name, 18, true)) + } + bf.WriteUint8(loans) + bf.WriteBytes(temp.Data()) + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) return } var data []byte @@ -221,10 +236,13 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfContractMercenary) - if pkt.Cancel { - s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) - } else { + switch pkt.Op { + case 0: s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, s.charID) + case 1: // Cancel lend + s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) + case 2: // Cancel loan + s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", pkt.CID) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From 6181f7e5a4a6385b4d6821318c489df5be6d1a15 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 20:57:28 +1100 Subject: [PATCH 05/27] fix GetEarthStatus response --- server/channelserver/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 0194e18e6..536a12c48 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1621,7 +1621,7 @@ func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { s.QueueAck(pkt.AckHandle, resp.Data()) */ - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckBufSucceed(s, pkt.AckHandle, []byte{}) } func handleMsgMhfRegistSpabiTime(s *Session, p mhfpacket.MHFPacket) {} From de20a0668bf5b278a0c2aab8ad11bd96a6fc251e Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 20:59:16 +1100 Subject: [PATCH 06/27] clean up various mercenary handlers --- server/channelserver/handlers_mercenary.go | 47 +++------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index bdeb924de..e5c7e63d3 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -13,37 +13,25 @@ import ( "path/filepath" ) -// THERE ARE [PARTENER] [MERCENARY] [OTOMO AIRU] - -/////////////////////////////////////////// -/// PARTENER // -/////////////////////////////////////////// - func handleMsgMhfLoadPartner(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadPartner) - // load partner from database var data []byte err := s.server.db.QueryRow("SELECT partner FROM characters WHERE id = $1", s.charID).Scan(&data) - if err != nil { - s.logger.Fatal("Failed to get partner savedata from db", zap.Error(err)) - } if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { + s.logger.Warn("Failed to load partner data", zap.Error(err)) doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) } - // TODO(Andoryuuta): Figure out unusual double ack. One sized, one not. doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } func handleMsgMhfSavePartner(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSavePartner) - dumpSaveData(s, pkt.RawDataPayload, "partner") - _, err := s.server.db.Exec("UPDATE characters SET partner=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update partner savedata in db", zap.Error(err)) + s.logger.Warn("Failed to save partner data", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } @@ -58,13 +46,10 @@ func handleMsgMhfLoadHunterNavi(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadHunterNavi) var data []byte err := s.server.db.QueryRow("SELECT hunternavi FROM characters WHERE id = $1", s.charID).Scan(&data) - if err != nil { - s.logger.Fatal("Failed to get hunter navigation savedata from db", zap.Error(err)) - } - if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { + s.logger.Warn("Failed to load navi data", zap.Error(err)) // set first byte to 1 to avoid pop up every time without save body := make([]byte, 0x226) body[0] = 1 @@ -74,16 +59,12 @@ func handleMsgMhfLoadHunterNavi(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSaveHunterNavi) - - dumpSaveData(s, pkt.RawDataPayload, "hunternavi") - if pkt.IsDataDiff { var data []byte - // Load existing save err := s.server.db.QueryRow("SELECT hunternavi FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get hunternavi savedata from db", zap.Error(err)) + s.logger.Warn("Failed to save navi data", zap.Error(err)) } // Check if we actually had any hunternavi data, using a blank buffer if not. @@ -96,30 +77,22 @@ func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { // Perform diff and compress it to write back to db s.logger.Info("Diffing...") saveOutput := deltacomp.ApplyDataDiff(pkt.RawDataPayload, data) - _, err = s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", saveOutput, s.charID) if err != nil { - s.logger.Fatal("Failed to update hunternavi savedata in db", zap.Error(err)) + s.logger.Warn("Failed to save navi data", zap.Error(err)) } - s.logger.Info("Wrote recompressed hunternavi back to DB.") } else { dumpSaveData(s, pkt.RawDataPayload, "hunternavi") // simply update database, no extra processing _, err := s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update hunternavi savedata in db", zap.Error(err)) + s.logger.Warn("Failed to save navi data", zap.Error(err)) } } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } -/////////////////////////////////////////// - -/////////////////////////////////////////// -/// MERCENARY // -/////////////////////////////////////////// - func handleMsgMhfMercenaryHuntdata(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfMercenaryHuntdata) if pkt.Unk0 == 1 { @@ -208,12 +181,6 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {} -/////////////////////////////////////////// - -/////////////////////////////////////////// -/// OTOMO AIRU // -/////////////////////////////////////////// - func handleMsgMhfLoadOtomoAirou(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadOtomoAirou) var data []byte @@ -411,5 +378,3 @@ func GetCatDetails(bf *byteframe.ByteFrame) []CatDefinition { } return cats } - -/////////////////////////////////////////// From 068b7ba72d2078dd63acdd0a2fbc902dca939dee Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 21:35:01 +1100 Subject: [PATCH 07/27] clean up various save handlers --- server/channelserver/handlers_house.go | 12 ++--- server/channelserver/handlers_mercenary.go | 17 +++---- server/channelserver/handlers_plate.go | 58 ++++++++++++++-------- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index b3aadf372..c979208d2 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -246,17 +246,13 @@ func handleMsgMhfLoadDecoMyset(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT decomyset FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get preset decorations savedata from db", zap.Error(err)) + s.logger.Error("Failed to load decomyset", zap.Error(err)) } if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) - //doAckBufSucceed(s, pkt.AckHandle, data) } else { - // set first byte to 1 to avoid pop up every time without save - body := make([]byte, 0x226) - body[0] = 1 - doAckBufSucceed(s, pkt.AckHandle, body) + doAckBufSucceed(s, pkt.AckHandle, []byte{0x01, 0x00}) } } @@ -267,7 +263,7 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload[1:]) // skip first unk byte err := s.server.db.QueryRow("SELECT decomyset FROM characters WHERE id = $1", s.charID).Scan(&loadData) if err != nil { - s.logger.Fatal("Failed to get preset decorations savedata from db", zap.Error(err)) + s.logger.Error("Failed to load decomyset", zap.Error(err)) } else { numSets := bf.ReadUint8() // sets being written // empty save @@ -313,7 +309,7 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, loadData, "decomyset") _, err := s.server.db.Exec("UPDATE characters SET decomyset=$1 WHERE id=$2", loadData, s.charID) if err != nil { - s.logger.Fatal("Failed to update decomyset savedata in db", zap.Error(err)) + s.logger.Error("Failed to save decomyset", zap.Error(err)) } } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index 5a8808b54..3a855485f 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -21,7 +21,7 @@ func handleMsgMhfLoadPartner(s *Session, p mhfpacket.MHFPacket) { if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { - s.logger.Warn("Failed to load partner data", zap.Error(err)) + s.logger.Error("Failed to load partner", zap.Error(err)) doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) @@ -32,7 +32,7 @@ func handleMsgMhfSavePartner(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, pkt.RawDataPayload, "partner") _, err := s.server.db.Exec("UPDATE characters SET partner=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Warn("Failed to save partner data", zap.Error(err)) + s.logger.Error("Failed to save partner", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } @@ -50,10 +50,8 @@ func handleMsgMhfLoadHunterNavi(s *Session, p mhfpacket.MHFPacket) { if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { - s.logger.Warn("Failed to load navi data", zap.Error(err)) - // set first byte to 1 to avoid pop up every time without save + s.logger.Error("Failed to load hunternavi", zap.Error(err)) body := make([]byte, 0x226) - body[0] = 1 doAckBufSucceed(s, pkt.AckHandle, body) } } @@ -65,14 +63,13 @@ func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { // Load existing save err := s.server.db.QueryRow("SELECT hunternavi FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Warn("Failed to save navi data", zap.Error(err)) + s.logger.Error("Failed to load hunternavi", zap.Error(err)) } // Check if we actually had any hunternavi data, using a blank buffer if not. // This is requried as the client will try to send a diff after character creation without a prior MsgMhfSaveHunterNavi packet. if len(data) == 0 { data = make([]byte, 0x226) - data[0] = 1 // set first byte to 1 to avoid pop up every time without save } // Perform diff and compress it to write back to db @@ -80,15 +77,15 @@ func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { saveOutput := deltacomp.ApplyDataDiff(pkt.RawDataPayload, data) _, err = s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", saveOutput, s.charID) if err != nil { - s.logger.Warn("Failed to save navi data", zap.Error(err)) + s.logger.Error("Failed to save hunternavi", zap.Error(err)) } - s.logger.Info("Wrote recompressed hunternavi back to DB.") + s.logger.Info("Wrote recompressed hunternavi back to DB") } else { dumpSaveData(s, pkt.RawDataPayload, "hunternavi") // simply update database, no extra processing _, err := s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Warn("Failed to save navi data", zap.Error(err)) + s.logger.Error("Failed to save hunternavi", zap.Error(err)) } } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) diff --git a/server/channelserver/handlers_plate.go b/server/channelserver/handlers_plate.go index 172a5f134..7138535bb 100644 --- a/server/channelserver/handlers_plate.go +++ b/server/channelserver/handlers_plate.go @@ -12,28 +12,28 @@ func handleMsgMhfLoadPlateData(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT platedata FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Error("Failed to get plate data savedata from db", zap.Error(err)) + s.logger.Error("Failed to load platedata", zap.Error(err)) } if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + doAckBufSucceed(s, pkt.AckHandle, []byte{}) } } func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSavePlateData) - dumpSaveData(s, pkt.RawDataPayload, "platedata") - if pkt.IsDataDiff { var data []byte // Load existing save err := s.server.db.QueryRow("SELECT platedata FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get platedata savedata from db", zap.Error(err)) + s.logger.Error("Failed to load platedata", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } if len(data) > 0 { @@ -41,7 +41,9 @@ func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) { s.logger.Info("Decompressing...") data, err = nullcomp.Decompress(data) if err != nil { - s.logger.Fatal("Failed to decompress savedata from db", zap.Error(err)) + s.logger.Error("Failed to decompress platedata", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } } else { // create empty save if absent @@ -52,20 +54,25 @@ func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) { s.logger.Info("Diffing...") saveOutput, err := nullcomp.Compress(deltacomp.ApplyDataDiff(pkt.RawDataPayload, data)) if err != nil { - s.logger.Fatal("Failed to diff and compress platedata savedata", zap.Error(err)) + s.logger.Error("Failed to diff and compress platedata", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } _, err = s.server.db.Exec("UPDATE characters SET platedata=$1 WHERE id=$2", saveOutput, s.charID) if err != nil { - s.logger.Fatal("Failed to update platedata savedata in db", zap.Error(err)) + s.logger.Error("Failed to save platedata", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } - s.logger.Info("Wrote recompressed platedata back to DB.") + s.logger.Info("Wrote recompressed platedata back to DB") } else { + dumpSaveData(s, pkt.RawDataPayload, "platedata") // simply update database, no extra processing _, err := s.server.db.Exec("UPDATE characters SET platedata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update platedata savedata in db", zap.Error(err)) + s.logger.Error("Failed to save platedata", zap.Error(err)) } } @@ -77,28 +84,28 @@ func handleMsgMhfLoadPlateBox(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT platebox FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Error("Failed to get sigil box savedata from db", zap.Error(err)) + s.logger.Error("Failed to load platebox", zap.Error(err)) } if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) } else { - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + doAckBufSucceed(s, pkt.AckHandle, []byte{}) } } func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSavePlateBox) - dumpSaveData(s, pkt.RawDataPayload, "platebox") - if pkt.IsDataDiff { var data []byte // Load existing save err := s.server.db.QueryRow("SELECT platebox FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get sigil box savedata from db", zap.Error(err)) + s.logger.Error("Failed to load platebox", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } // Decompress @@ -107,7 +114,9 @@ func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) { s.logger.Info("Decompressing...") data, err = nullcomp.Decompress(data) if err != nil { - s.logger.Fatal("Failed to decompress savedata from db", zap.Error(err)) + s.logger.Error("Failed to decompress platebox", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } } else { // create empty save if absent @@ -118,20 +127,25 @@ func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) { s.logger.Info("Diffing...") saveOutput, err := nullcomp.Compress(deltacomp.ApplyDataDiff(pkt.RawDataPayload, data)) if err != nil { - s.logger.Fatal("Failed to diff and compress savedata", zap.Error(err)) + s.logger.Error("Failed to diff and compress platebox", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } _, err = s.server.db.Exec("UPDATE characters SET platebox=$1 WHERE id=$2", saveOutput, s.charID) if err != nil { - s.logger.Fatal("Failed to update platebox savedata in db", zap.Error(err)) + s.logger.Error("Failed to save platebox", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } - s.logger.Info("Wrote recompressed platebox back to DB.") + s.logger.Info("Wrote recompressed platebox back to DB") } else { + dumpSaveData(s, pkt.RawDataPayload, "platebox") // simply update database, no extra processing _, err := s.server.db.Exec("UPDATE characters SET platebox=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update platedata savedata in db", zap.Error(err)) + s.logger.Error("Failed to save platebox", zap.Error(err)) } } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) @@ -142,7 +156,7 @@ func handleMsgMhfLoadPlateMyset(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT platemyset FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get presets sigil savedata from db", zap.Error(err)) + s.logger.Error("Failed to load platemyset", zap.Error(err)) } if len(data) > 0 { @@ -159,7 +173,7 @@ func handleMsgMhfSavePlateMyset(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, pkt.RawDataPayload, "platemyset") _, err := s.server.db.Exec("UPDATE characters SET platemyset=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update platemyset savedata in db", zap.Error(err)) + s.logger.Error("Failed to save platemyset", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } From 7ed3702cc0822cb733eaed670fc9ed7e5917d367 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 21:37:16 +1100 Subject: [PATCH 08/27] make cafe overflow errors not fatal --- server/channelserver/handlers_cafe.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/channelserver/handlers_cafe.go b/server/channelserver/handlers_cafe.go index c8e84e087..b623efae6 100644 --- a/server/channelserver/handlers_cafe.go +++ b/server/channelserver/handlers_cafe.go @@ -15,7 +15,7 @@ func handleMsgMhfAcquireCafeItem(s *Session, p mhfpacket.MHFPacket) { var netcafePoints uint32 err := s.server.db.QueryRow("UPDATE characters SET netcafe_points = netcafe_points - $1 WHERE id = $2 RETURNING netcafe_points", pkt.PointCost, s.charID).Scan(&netcafePoints) if err != nil { - s.logger.Fatal("Failed to get netcafe points from db", zap.Error(err)) + s.logger.Error("Failed to get netcafe points from db", zap.Error(err)) } resp := byteframe.NewByteFrame() resp.WriteUint32(netcafePoints) @@ -27,7 +27,7 @@ func handleMsgMhfUpdateCafepoint(s *Session, p mhfpacket.MHFPacket) { var netcafePoints uint32 err := s.server.db.QueryRow("SELECT COALESCE(netcafe_points, 0) FROM characters WHERE id = $1", s.charID).Scan(&netcafePoints) if err != nil { - s.logger.Fatal("Failed to get netcate points from db", zap.Error(err)) + s.logger.Error("Failed to get netcate points from db", zap.Error(err)) } resp := byteframe.NewByteFrame() resp.WriteUint32(netcafePoints) @@ -49,7 +49,7 @@ func handleMsgMhfCheckDailyCafepoint(s *Session, p mhfpacket.MHFPacket) { var dailyTime time.Time err := s.server.db.QueryRow("SELECT COALESCE(daily_time, $2) FROM characters WHERE id = $1", s.charID, time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)).Scan(&dailyTime) if err != nil { - s.logger.Fatal("Failed to get daily_time savedata from db", zap.Error(err)) + s.logger.Error("Failed to get daily_time savedata from db", zap.Error(err)) } var bondBonus, bonusQuests, dailyQuests uint32 From 29d62634fa930e94fa143f98ac9be67a50ab6ef7 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 22:32:52 +1100 Subject: [PATCH 09/27] clean up various save handlers --- server/channelserver/handlers.go | 3 +-- server/channelserver/handlers_house.go | 8 +++---- server/channelserver/handlers_mercenary.go | 26 +++++++++------------- server/channelserver/handlers_plate.go | 25 +++++---------------- 4 files changed, 19 insertions(+), 43 deletions(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 536a12c48..39bf41ebd 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1834,8 +1834,7 @@ func handleMsgMhfGetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT minidata FROM characters WHERE id = $1", pkt.CharID).Scan(&data) if err != nil { - data = make([]byte, 0x400) // returning empty might avoid a client softlock - //s.logger.Fatal("Failed to get minidata from db", zap.Error(err)) + data = make([]byte, 1) } doAckBufSucceed(s, pkt.AckHandle, data) } diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index c979208d2..ab150f180 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -248,12 +248,10 @@ func handleMsgMhfLoadDecoMyset(s *Session, p mhfpacket.MHFPacket) { if err != nil { s.logger.Error("Failed to load decomyset", zap.Error(err)) } - - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { - doAckBufSucceed(s, pkt.AckHandle, []byte{0x01, 0x00}) + if len(data) == 0 { + data = []byte{0x01, 0x00} } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index 3a855485f..b20b55ff4 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -18,12 +18,11 @@ func handleMsgMhfLoadPartner(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadPartner) var data []byte err := s.server.db.QueryRow("SELECT partner FROM characters WHERE id = $1", s.charID).Scan(&data) - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { + if len(data) == 0 { s.logger.Error("Failed to load partner", zap.Error(err)) - doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + data = make([]byte, 9) } + doAckBufSucceed(s, pkt.AckHandle, data) doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } @@ -47,13 +46,11 @@ func handleMsgMhfLoadHunterNavi(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadHunterNavi) var data []byte err := s.server.db.QueryRow("SELECT hunternavi FROM characters WHERE id = $1", s.charID).Scan(&data) - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { + if len(data) == 0 { s.logger.Error("Failed to load hunternavi", zap.Error(err)) - body := make([]byte, 0x226) - doAckBufSucceed(s, pkt.AckHandle, body) + data = make([]byte, 0x226) } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) { @@ -227,14 +224,11 @@ func handleMsgMhfLoadOtomoAirou(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadOtomoAirou) var data []byte err := s.server.db.QueryRow("SELECT otomoairou FROM characters WHERE id = $1", s.charID).Scan(&data) - if err != nil { - s.logger.Fatal("Failed to get partnyaa savedata from db", zap.Error(err)) - } - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { - doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + if len(data) == 0 { + s.logger.Error("Failed to load otomoairou", zap.Error(err)) + data = make([]byte, 10) } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSaveOtomoAirou(s *Session, p mhfpacket.MHFPacket) { diff --git a/server/channelserver/handlers_plate.go b/server/channelserver/handlers_plate.go index 7138535bb..3f5688184 100644 --- a/server/channelserver/handlers_plate.go +++ b/server/channelserver/handlers_plate.go @@ -14,12 +14,7 @@ func handleMsgMhfLoadPlateData(s *Session, p mhfpacket.MHFPacket) { if err != nil { s.logger.Error("Failed to load platedata", zap.Error(err)) } - - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { - doAckBufSucceed(s, pkt.AckHandle, []byte{}) - } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) { @@ -86,12 +81,7 @@ func handleMsgMhfLoadPlateBox(s *Session, p mhfpacket.MHFPacket) { if err != nil { s.logger.Error("Failed to load platebox", zap.Error(err)) } - - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { - doAckBufSucceed(s, pkt.AckHandle, []byte{}) - } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) { @@ -155,16 +145,11 @@ func handleMsgMhfLoadPlateMyset(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadPlateMyset) var data []byte err := s.server.db.QueryRow("SELECT platemyset FROM characters WHERE id = $1", s.charID).Scan(&data) - if err != nil { + if len(data) == 0 { s.logger.Error("Failed to load platemyset", zap.Error(err)) + data = make([]byte, 0x780) } - - if len(data) > 0 { - doAckBufSucceed(s, pkt.AckHandle, data) - } else { - blankData := make([]byte, 0x780) - doAckBufSucceed(s, pkt.AckHandle, blankData) - } + doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgMhfSavePlateMyset(s *Session, p mhfpacket.MHFPacket) { From c6b770672ef33075dade377b1795bc7d69b98e1a Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 31 Jan 2023 23:54:24 +1100 Subject: [PATCH 10/27] swap placeholder data --- server/channelserver/handlers_quest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_quest.go b/server/channelserver/handlers_quest.go index 5ced41733..9caef6dbf 100644 --- a/server/channelserver/handlers_quest.go +++ b/server/channelserver/handlers_quest.go @@ -124,7 +124,7 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { {false, 10000}, } - data, _ := hex.DecodeString("7F2301CF7CD17F23111111007E0F7B357F23111111007F407CD07F23111111007E0F7CD77F23111111007E0F7CD67F23111111007E0F7B197F23111111007F277B1D7F23111111007F277B617F23111111007F207BAD7F23111111007F267BB17F23111111007F267BB57F23111111007F217BA07F23111111007F237B257F23111111007F2B7B227F23111111007F2272857F23111111007F237B277F23111111007F477B207F23111111007F477F027F23111111007F227F737F23111111007F227F127F23111111007F227F377F23111111007F227F187F23111111007F227F167F23111111007F227F397F23111111007F227F7D7F23111111007F227F0B7F23111111007F227F387F23111111007F227F607F23111111007F227CDC7F23111111007F2B7B237F23111111007FB572847F23111111007F23728B7F23111111007F23728A7F23111111007F2372897F23111111007F2372887F23111111007F23728F7F23111111007F23728E7F23111111007F23728D7F23111111007F23728C7F23111111007F2372937F23111111007F2372927F23111111007F2372917F23111111007F2372E37F23111111007F2372E27F23111111007F237B1B7F23111111007F227B1A7F23111111007F2272E17F23111111007F2372E07F23111111007F2373F57F23111111007FEB73F47F23111111007FEB73FB7F23111111007FEB72E77F23111111007F2372E67F23111111007F2372E57F23111111007F2372E47F23111111007F2372EB7F23111111007F2372EA7F23111111007F237CDF7F23111111007F477CDE7F23111111007EB37B087F23111111007F7972E97F23111111007F2373FA7F23111111007FEB73F97F23111111007FEB73F87F23111111007FEB73FF7F23111111007FEB73FE7F23111111007FEB73FD7F23111111007FEB73FC7F23111111007FEB73C37F23111111007FEB73C27F23111111007FEB73C17F23111111007FEB73C07F23111111007FEB73C77F23111111007FEB73C67F23111111007FEB73C57F23111111007FEB73C47F23111111007FEB73CB7F23111111007FEB73CA7F23111111007FEB73C97F23111111007FEB73C87F23111111007FEB73CF7F23111111007FEB73CE7F23111111007FEB73CD7F23111111007FEB73CC7F23111111007FEB73D37F23111111007E0F73D27F23111111007E0F73D17F23111111007E0F73D07F23111111007E0F73D77F23111111007E0F73D67F23111111007E0F73D57F23111111007E0F73D47F23111111007E0F73DB7F23111111007E0F73DA7F23111111007E0F73D97F23111111007E0F73D87F23111111007E0F73DF7F23111111007E0F73DE7F23111111007E0F73DD7F23111111007E0F73DC7F23111111007E0F72237F23111111007E0F72227F23111111007E0F72217F23111111007E0F72207F23111111007E0F72277F23111111007E0F72E87F23111111007F2372EF7F23111111007F2372267F23111111007E0F7B137F23111111007E0F7B5A7F23111111007FEB72517F23111111007F4772257F23111111007E0F72247F23111111007E0F722B7F23111111007E0F722A7F23111111007E0F7B047F2311111100BC737B0B7F2311111100BC737B0A7F23111111001E8B7B097F23111111001E8B7CD57F23111111007FEB7B3F7F23111111007FEB7B0F7F23111111007F737B0E7F23111111007F657CD47F23111111007FEB7B387F23111111007FEB72507F23111111007F4772577F23111111007F4772567F23111111007F4772557F23111111007F4772547F23111111007F47725B7F23111111007F47725A7F23111111007F4772297F23111111007F4772287F23111111007F47722F7F23111111007F47722E7F23111111007F47722D7F23111111007F47722C7F23111111007F4772337F23111111007F4772327F23111111007F4772317F23111111007F4772307F23111111007F4772377F23111111007F4772367F23111111007F4772357F23111111007F4772347F23111111007F477B1E7F23111111007F2272597F23111111007F47723B7F23111111007F47723A7F23111111007F477B627F23111111007F2272587F23111111007F4772397F23111111007F477B147F23111111007F227B187F23111111007F217B1F7F23111111007F297B1C7F23111111007F217B637F23111111007F297B607F23111111007F217B677F23111111007F297B647F23111111007F217B6B7F23111111007F297B687F23111111007F217B6F7F23111111007F297B6C7F23111111007F217B737F23111111007F2972387F23111111007F47723F7F23111111007F47723E7F23111111007F47723D7F23111111007F47723C7F23111111007F4772037F23111111007F4772027F23111111007F4772017F23111111007F4772007F23111111007F4772077F23111111007F4772067F23111111007F4772057F23111111007F4772047F23111111007F47720B7F23111111007F47720A7F23111111007F4772097F23111111007F4772087F23111111007F47720F7F23111111007F47720E7F23111111007F47720D7F23111111007F47720C7F23111111007F4772137F23111111007F4772127F23111111007F4772117F23111111007F4772107F23111111007F4772177F23111111007F4772167F23111111007F4772157F23111111007F4772147F23111111007F47721B7F23111111007F47721A7F23111111007F4772197F23111111007F4772187F23111111007F47721F7F23111111007F47721E7F23111111007F47725F7F23111111007F47721D7F23111111007F47721C7F23111111007F4772637F23111111007F4772627F23111111007F4772617F23111111007F4772607F23111111007F4772677F23111111007F4772667F23111111007F4772657F23111111007F4772647F23111111007F47726B7F23111111007F47726A7F23111111007F4772697F23111111007F47727B7F23111111007F47727A7F23111111007F4772797F23111111007F4772787F23111111007F47727F7F23111111007F47727E7F23111111007F47727D7F23111111007F47727C7F23111111007F4772437F23111111007F4772427F23111111007F4772417F23111111007F4772407F23111111007F4772477F23111111007F477B127F23111111007E0F7B117F23111111007E0F7BAB7F23111111007E0F725E7F23111111007F47725D7F23111111007F4772AF7F23111111007F4772AE7F23111111007F477B597F23111111007F2372AD7F23111111007F477B587F23111111007F2372AC7F23111111007F477B217F23111111007CC47B157F23111111007F237BA37F23111111007B497BA97F23111111007F227BA87F23111111007F207BAF7F23111111007F267BAE7F23111111007F227BAC7F23111111007F227BB37F23111111007F207BB27F23111111007F207BB07F23111111007F227BB77F23111111007F227BB67F23111111007F22738A7F23111111007F2173897F23111111007F2173887F23111111007F21738F7F23111111007F217B5B7F23111111007F23738E7F23111111007F21738D7F23111111007F217B667F23111111007F217B657F23111111007F267B6A7F23111111007F217B697F23111111007F267B6E7F23111111007F217B6D7F23111111007F267BB47F23111111007F277BBB7F23111111007F297BBA7F23111111007F277BB97F23111111007F297BB87F23111111007F2172B37F23111111007F4772B27F23111111007F4772B17F23111111007F4772B07F23111111007F4772B77F23111111007F4772B67F23111111007F4772B57F23111111007F4772B47F23111111007F4772BB7F23111111007F4772F97F23111111007F2372F87F23111111007F237BA27F23111111007F237B267F23111111007F29749B7F23111111007ED7749A7F23111111007ED774997F23111111007ED774987F23111111007ED7749F7F23111111007ED7749E7F23111111007ED77B247F23111111007F47749D7F23111111007ED7749C7F23111111007ED774E37F23111111007ED774E27F23111111007ED774E17F23111111007ED774E07F23111111007ED774E77F23111111007ED774E67F23111111007ED774E57F23111111007ED774E47F23111111007ED774EB7F23111111007ED774EA7F23111111007ED774E97F23111111007ED774E87F23111111007ED774EF7F23111111007ED774EE7F23111111007ED774ED7F23111111007ED774EC7F23111111007ED77B717F23111111007F2374F37F23111111007ED774F27F23111111007ED774F17F23111111007ED77BA17F23111111007F2372FF7F23111111007F2373777F23111111007F2372FE7F23111111007F2373767F23111111007F2373757F23111111007F2373747F23111111007F23737B7F23111111007F23737A7F23111111007F2373797F23111111007F2373787F23111111007F23737F7F23111111007F23737E7F23111111007F23737D7F23111111007F23737C7F23111111007F2373437F23111111007F23734D7F23111111007F23734C7F23111111007F2373537F23111111007F2373527F23111111007F2373517F23111111007F2373507F23111111007F2373577F23111111007F2373567F23111111007F2373557F23111111007F2373547F23111111007F23735B7F23111111007F23735A7F23111111007F2373597F23111111007F2372FD7F23111111007F2372FC7F23111111007F2372C37F23111111007F2372C27F23111111007F2372C17F23111111007F2372C07F23111111007F2372C77F23111111007F2372C67F23111111007F2372C57F23111111007F2372D77F23111111007F2372D67F23111111007F2372D57F23111111007F2372D47F23111111007F2372DB7F23111111007F2372DA7F23111111007F2372D97F23111111007F2372D87F23111111007F2372DF7F23111111007F2372DE7F23111111007F2372DD7F23111111007F2372DC7F23111111007F2371237F23111111007F237B5E7F23111111007F3774F07F23111111007ED774F77F23111111007ED774F67F23111111007ED77BA57F23111111007F2274F57F23111111007ED774F47F23111111007ED774FB7F23111111007ED774FA7F23111111007ED774F97F23111111007ED774F87F23111111007ED774FF7F23111111007ED774FE7F23111111007ED774FD7F23111111007ED774FC7F23111111007ED774C37F23111111007ED774C27F23111111007ED774C17F23111111007ED774C07F23111111007ED774C77F23111111007ED774C67F23111111007ED774C57F23111111007ED774C47F23111111007ED774CB7F23111111007ED774CA7F23111111007ED774C97F23111111007ED774C87F23111111007ED774CF7F23111111007EB374CE7F23111111007EB374CD7F23111111007EB374CC7F23111111007EB374D37F23111111007EB374D27F23111111007EB374D17F23111111007EB374D07F23111111007EB374D77F23111111007EB374D67F23111111007EB374D57F23111111007EB374D47F23111111007EB374DB7F23111111007EB37BBF7F23111111007F2673257F23111111007EB373247F23111111007EB3732B7F23111111007EB3732A7F23111111007EB373297F23111111007EB373287F23111111007EB3732F7F23111111007EB3732E7F23111111007EB3732D7F23111111007EB3732C7F23111111007EB373337F23111111007EB373327F23111111007EB373317F23111111007EB373037F23111111007CCB73027F23111111007CCB73017F23111111007CCB73007F23111111007CCB73077F23111111007CCB73067F23111111007CCB73057F23111111007CCB73047F23111111007CCB730B7F23111111007CCB730A7F23111111007CCB73097F23111111007CCB73087F23111111007CCB730F7F23111111007CCB73197F23111111007CCB73187F23111111007CCB731F7F23111111007CCB731E7F23111111007CCB731D7F23111111007CCB731C7F23111111007CCB73637F23111111007CCB73627F23111111007CCB73617F23111111007CCB73607F23111111007CCB73677F23111111007CCB73667F23111111007CCB73657F23111111007CCB73AB7F23111111007F2173AA7F23111111007F2173A97F23111111007F2173A87F23111111007F2173AF7F23111111007F2173AE7F23111111007F2173AD7F23111111007F2173AC7F23111111007F2173B37F23111111007F2173B27F23111111007F2173B17F23111111007F2173B07F23111111007F2173B77F23111111007F2173817F23111111007F2173807F23111111007F2173877F23111111007F2173867F23111111007F2173857F23111111007F2173847F23111111007F21738B7F23111111007F21") + data, _ := hex.DecodeString("06E601CF051406E6D4D4D40007CA02F006E6D4D4D4000685051506E6D4D4D40007CA051206E6D4D4D40007CA051306E6D4D4D40007CA02DC06E6D4D4D40006E202D806E6D4D4D40006E202A406E6D4D4D40006E5026806E6D4D4D40006E3027406E6D4D4D40006E3027006E6D4D4D40006E4026506E6D4D4D40006E602E006E6D4D4D40006EE02E706E6D4D4D40006E70B4006E6D4D4D40006E602E206E6D4D4D400068202E506E6D4D4D400068206C706E6D4D4D40006E706B606E6D4D4D40006E706D706E6D4D4D40006E706F206E6D4D4D40006E706DD06E6D4D4D40006E706D306E6D4D4D40006E706FC06E6D4D4D40006E706B806E6D4D4D40006E706CE06E6D4D4D40006E706FD06E6D4D4D40006E706A506E6D4D4D40006E7051906E6D4D4D40006EE02E606E6D4D4D40006700B4106E6D4D4D40006E60B4E06E6D4D4D40006E60B4F06E6D4D4D40006E60B4C06E6D4D4D40006E60B4D06E6D4D4D40006E60B4A06E6D4D4D40006E60B4B06E6D4D4D40006E60B4806E6D4D4D40006E60B4906E6D4D4D40006E60B5606E6D4D4D40006E60B5706E6D4D4D40006E60B5406E6D4D4D40006E60B2606E6D4D4D40006E60B2706E6D4D4D40006E602DE06E6D4D4D40006E702DF06E6D4D4D40006E70B2406E6D4D4D40006E60B2506E6D4D4D40006E60A3006E6D4D4D400062E0A3106E6D4D4D400062E0A3E06E6D4D4D400062E0B2206E6D4D4D40006E60B2306E6D4D4D40006E60B2006E6D4D4D40006E60B2106E6D4D4D40006E60B2E06E6D4D4D40006E60B2F06E6D4D4D40006E6051A06E6D4D4D4000682051B06E6D4D4D400077602CD06E6D4D4D40006BC0B2C06E6D4D4D40006E60A3F06E6D4D4D400062E0A3C06E6D4D4D400062E0A3D06E6D4D4D400062E0A3A06E6D4D4D400062E0A3B06E6D4D4D400062E0A3806E6D4D4D400062E0A3906E6D4D4D400062E0A0606E6D4D4D400062E0A0706E6D4D4D400062E0A0406E6D4D4D400062E0A0506E6D4D4D400062E0A0206E6D4D4D400062E0A0306E6D4D4D400062E0A0006E6D4D4D400062E0A0106E6D4D4D400062E0A0E06E6D4D4D400062E0A0F06E6D4D4D400062E0A0C06E6D4D4D400062E0A0D06E6D4D4D400062E0A0A06E6D4D4D400062E0A0B06E6D4D4D400062E0A0806E6D4D4D400062E0A0906E6D4D4D400062E0A1606E6D4D4D40007CA0A1706E6D4D4D40007CA0A1406E6D4D4D40007CA0A1506E6D4D4D40007CA0A1206E6D4D4D40007CA0A1306E6D4D4D40007CA0A1006E6D4D4D40007CA0A1106E6D4D4D40007CA0A1E06E6D4D4D40007CA0A1F06E6D4D4D40007CA0A1C06E6D4D4D40007CA0A1D06E6D4D4D40007CA0A1A06E6D4D4D40007CA0A1B06E6D4D4D40007CA0A1806E6D4D4D40007CA0A1906E6D4D4D40007CA0BE606E6D4D4D40007CA0BE706E6D4D4D40007CA0BE406E6D4D4D40007CA0BE506E6D4D4D40007CA0BE206E6D4D4D40007CA0B2D06E6D4D4D40006E60B2A06E6D4D4D40006E60BE306E6D4D4D40007CA02D606E6D4D4D40007CA029F06E6D4D4D400062E0B9406E6D4D4D40006820BE006E6D4D4D40007CA0BE106E6D4D4D40007CA0BEE06E6D4D4D40007CA0BEF06E6D4D4D40007CA02C106E6D4D4D400C5B602CE06E6D4D4D400C5B602CF06E6D4D4D400674E02CC06E6D4D4D400674E051006E6D4D4D400062E02FA06E6D4D4D400062E02CA06E6D4D4D40006B602CB06E6D4D4D40006A0051106E6D4D4D400062E02FD06E6D4D4D400062E0B9506E6D4D4D40006820B9206E6D4D4D40006820B9306E6D4D4D40006820B9006E6D4D4D40006820B9106E6D4D4D40006820B9E06E6D4D4D40006820B9F06E6D4D4D40006820BEC06E6D4D4D40006820BED06E6D4D4D40006820BEA06E6D4D4D40006820BEB06E6D4D4D40006820BE806E6D4D4D40006820BE906E6D4D4D40006820BF606E6D4D4D40006820BF706E6D4D4D40006820BF406E6D4D4D40006820BF506E6D4D4D40006820BF206E6D4D4D40006820BF306E6D4D4D40006820BF006E6D4D4D40006820BF106E6D4D4D400068202DB06E6D4D4D40006E70B9C06E6D4D4D40006820BFE06E6D4D4D40006820BFF06E6D4D4D400068202A706E6D4D4D40006E70B9D06E6D4D4D40006820BFC06E6D4D4D400068202D106E6D4D4D40006E702DD06E6D4D4D40006E402DA06E6D4D4D40006EC02D906E6D4D4D40006E402A606E6D4D4D40006EC02A506E6D4D4D40006E402A206E6D4D4D40006EC02A106E6D4D4D40006E402AE06E6D4D4D40006EC02AD06E6D4D4D40006E402AA06E6D4D4D40006EC02A906E6D4D4D40006E402B606E6D4D4D40006EC0BFD06E6D4D4D40006820BFA06E6D4D4D40006820BFB06E6D4D4D40006820BF806E6D4D4D40006820BF906E6D4D4D40006820BC606E6D4D4D40006820BC706E6D4D4D40006820BC406E6D4D4D40006820BC506E6D4D4D40006820BC206E6D4D4D40006820BC306E6D4D4D40006820BC006E6D4D4D40006820BC106E6D4D4D40006820BCE06E6D4D4D40006820BCF06E6D4D4D40006820BCC06E6D4D4D40006820BCD06E6D4D4D40006820BCA06E6D4D4D40006820BCB06E6D4D4D40006820BC806E6D4D4D40006820BC906E6D4D4D40006820BD606E6D4D4D40006820BD706E6D4D4D40006820BD406E6D4D4D40006820BD506E6D4D4D40006820BD206E6D4D4D40006820BD306E6D4D4D40006820BD006E6D4D4D40006820BD106E6D4D4D40006820BDE06E6D4D4D40006820BDF06E6D4D4D40006820BDC06E6D4D4D40006820BDD06E6D4D4D40006820BDA06E6D4D4D40006820BDB06E6D4D4D40006820B9A06E6D4D4D40006820BD806E6D4D4D40006820BD906E6D4D4D40006820BA606E6D4D4D40006820BA706E6D4D4D40006820BA406E6D4D4D40006820BA506E6D4D4D40006820BA206E6D4D4D40006820BA306E6D4D4D40006820BA006E6D4D4D40006820BA106E6D4D4D40006820BAE06E6D4D4D40006820BAF06E6D4D4D40006820BAC06E6D4D4D40006820BBE06E6D4D4D40006820BBF06E6D4D4D40006820BBC06E6D4D4D40006820BBD06E6D4D4D40006820BBA06E6D4D4D40006820BBB06E6D4D4D40006820BB806E6D4D4D40006820BB906E6D4D4D40006820B8606E6D4D4D40006820B8706E6D4D4D40006820B8406E6D4D4D40006820B8506E6D4D4D40006820B8206E6D4D4D400068202D706E6D4D4D40007CA02D406E6D4D4D40007CA026E06E6D4D4D40007CA0B9B06E6D4D4D40006820B9806E6D4D4D40006820B6A06E6D4D4D40006820B6B06E6D4D4D4000682029C06E6D4D4D40006E60B6806E6D4D4D4000682029D06E6D4D4D40006E60B6906E6D4D4D40006820A6E06E6D4D4D40006E60A6F06E6D4D4D40006E60A6C06E6D4D4D40006E60A6D06E6D4D4D40006E60A6A06E6D4D4D40006E60A6B06E6D4D4D40006E60A6806E6D4D4D40006E60A6906E6D4D4D40006E60A7606E6D4D4D40006E60A7706E6D4D4D40006E602E406E6D4D4D40005010A7406E6D4D4D40006E60A7506E6D4D4D40006E602D006E6D4D4D40006E60A7206E6D4D4D40006E6026606E6D4D4D400028C0A4406E6D4D4D40006E60A4506E6D4D4D40006E6026C06E6D4D4D40006E7026D06E6D4D4D40006E5026A06E6D4D4D40006E3026B06E6D4D4D40006E70A4206E6D4D4D40006E6026906E6D4D4D40006E7027606E6D4D4D40006E5027706E6D4D4D40006E50A4306E6D4D4D40006E6027506E6D4D4D40006E7027206E6D4D4D40006E7027306E6D4D4D40006E70A4006E6D4D4D40006E60A4106E6D4D4D40006E60A4E06E6D4D4D40006E60A4F06E6D4D4D40006E60A4C06E6D4D4D40006E60A4D06E6D4D4D40006E60A4A06E6D4D4D40006E60A4B06E6D4D4D40006E60A4806E6D4D4D40006E6029E06E6D4D4D40006E602A306E6D4D4D40006E402A006E6D4D4D40006E302AF06E6D4D4D40006E402AC06E6D4D4D40006E302AB06E6D4D4D40006E402A806E6D4D4D40006E3027106E6D4D4D40006E2027E06E6D4D4D40006EC027F06E6D4D4D40006E2027C06E6D4D4D40006EC027D06E6D4D4D40006E40B7606E6D4D4D40006820B7706E6D4D4D40006820B7406E6D4D4D40006820B7506E6D4D4D40006820B7206E6D4D4D40006820B7306E6D4D4D40006820B7006E6D4D4D40006820B7106E6D4D4D40006820B7E06E6D4D4D40006820B3C06E6D4D4D40006E60D3406E6D4D4D40006820D3506E6D4D4D40006820B3D06E6D4D4D40006E6026706E6D4D4D40006E60D5E06E6D4D4D40006820D5F06E6D4D4D40006820D5C06E6D4D4D40006820D5D06E6D4D4D40006820D5A06E6D4D4D40006820D5B06E6D4D4D40006820D5806E6D4D4D40006820D5906E6D4D4D40006820D2606E6D4D4D40006820D2706E6D4D4D40006820D2406E6D4D4D40006820D2506E6D4D4D40006820D2206E6D4D4D40006820D3206E6D4D4D40006820D3306E6D4D4D40006820D3006E6D4D4D40006820D3106E6D4D4D40006820D3E06E6D4D4D40006820D2306E6D4D4D40006820D2006E6D4D4D40006820D2106E6D4D4D40006820D2E06E6D4D4D40006820D2F06E6D4D4D40006820D2C06E6D4D4D40006820D2D06E6D4D4D40006820D2A06E6D4D4D40006820D2B06E6D4D4D40006820D2806E6D4D4D40006820D2906E6D4D4D40006820D3606E6D4D4D40006820D3706E6D4D4D400068202E306E6D4D4D40006F802E106E6D4D4D40006820D3F06E6D4D4D40006820D0A06E6D4D4D40006820D0B06E6D4D4D40006820D0806E6D4D4D40006820D0906E6D4D4D40006820D1606E6D4D4D40006820D1706E6D4D4D40006820D1406E6D4D4D40006820D1506E6D4D4D40006820D1206E6D4D4D40006820D3C06E6D4D4D400068202B406E6D4D4D40006E60D1306E6D4D4D40006820D1006E6D4D4D40006820D1106E6D4D4D40006820D1E06E6D4D4D40006820AE006E6D4D4D40006820AE106E6D4D4D40006820AEE06E6D4D4D40006820AEF06E6D4D4D40006820AEC06E6D4D4D40006820AED06E6D4D4D40006820AEA06E6D4D4D40006820AEB06E6D4D4D40006820AE806E6D4D4D40006820AE906E6D4D4D40006820AF606E6D4D4D4000682026406E6D4D4D40006E60AF706E6D4D4D40006820B3A06E6D4D4D40006E60AB206E6D4D4D40006E60B3B06E6D4D4D40006E60D3D06E6D4D4D40006820D3A06E6D4D4D40006820D3B06E6D4D4D40006820AB306E6D4D4D40006E60AB006E6D4D4D40006E60AB106E6D4D4D40006E60ABE06E6D4D4D40006E60ABF06E6D4D4D40006E60ABC06E6D4D4D40006E60ABD06E6D4D4D40006E60ABA06E6D4D4D40006E60ABB06E6D4D4D40006E60AB806E6D4D4D40006E60AB906E6D4D4D40006E60A8606E6D4D4D40006E60A8806E6D4D4D40006E60A8906E6D4D4D40006E60A9606E6D4D4D40006E60A9706E6D4D4D40006E60A9406E6D4D4D40006E60A9506E6D4D4D40006E60A9206E6D4D4D40006E60A9306E6D4D4D40006E60A9006E6D4D4D40006E60A9106E6D4D4D40006E60A9E06E6D4D4D40006E60A9F06E6D4D4D40006E60A9C06E6D4D4D40006E60D3806E6D4D4D40006820D3906E6D4D4D40006820D0606E6D4D4D40006820D0706E6D4D4D40006820D0406E6D4D4D40006820D0506E6D4D4D40006820D0206E6D4D4D40006820D0306E6D4D4D40006820D0006E6D4D4D40006820D0106E6D4D4D40006820D0E06E6D4D4D40006820D0F06E6D4D4D40006820D0C06E6D4D4D40006820D0D06E6D4D4D40006820B3806E6D4D4D40006E60B3906E6D4D4D40006E60B0606E6D4D4D40006E60B0706E6D4D4D40006E60B0406E6D4D4D40006E60B0506E6D4D4D40006E60B0206E6D4D4D40006E60B0306E6D4D4D40006E60B0006E6D4D4D40006E60B1206E6D4D4D40006E60B1306E6D4D4D40006E60B1006E6D4D4D40006E60B1106E6D4D4D40006E60B1E06E6D4D4D40006E60B1F06E6D4D4D40006E60B1C06E6D4D4D40006E60B1D06E6D4D4D40006E60B1A06E6D4D4D40006E60B1B06E6D4D4D40006E60B1806E6D4D4D40006E60B1906E6D4D4D40006E608E606E6D4D4D40006E6029B06E6D4D4D40006F20AF406E6D4D4D4000682026006E6D4D4D40006E70AC606E6D4D4D40006820AC706E6D4D4D40006820AC406E6D4D4D40006820AC506E6D4D4D40006820AC206E6D4D4D40006820AC306E6D4D4D40006820AC006E6D4D4D40006820AC106E6D4D4D40006820ACE06E6D4D4D40006820ACF06E6D4D4D40006820ACC06E6D4D4D40006820ACD06E6D4D4D40006820ACA06E6D4D4D4000682027A06E6D4D4D40006E30ADC06E6D4D4D40006820ADD06E6D4D4D40006820ADA06E6D4D4D40006820ADB06E6D4D4D40006820AD806E6D4D4D40006820AD906E6D4D4D40006820AA606E6D4D4D40006820AA706E6D4D4D40006820AA406E6D4D4D40006820AA506E6D4D4D40006820AA206E6D4D4D40006820AA306E6D4D4D40006820AA006E6D4D4D4000682") bf.WriteBytes(data) bf.WriteUint16(uint16(len(vsQuestItems))) From 218693ef40f153564a478d1b8679fec3f3af0f89 Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 2 Feb 2023 21:08:09 +1100 Subject: [PATCH 11/27] clean up various save handlers --- server/channelserver/handlers.go | 10 +++++++--- server/channelserver/handlers_data.go | 9 +++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 39bf41ebd..9fed99c89 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1774,7 +1774,8 @@ func handleMsgMhfGetEquipSkinHist(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT COALESCE(skin_hist::bytea, $2::bytea) FROM characters WHERE id = $1", s.charID, make([]byte, 0xC80)).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get skin_hist savedata from db", zap.Error(err)) + s.logger.Error("Failed to load skin_hist", zap.Error(err)) + data = make([]byte, 3200) } doAckBufSucceed(s, pkt.AckHandle, data) } @@ -1785,7 +1786,9 @@ func handleMsgMhfUpdateEquipSkinHist(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT COALESCE(skin_hist, $2) FROM characters WHERE id = $1", s.charID, make([]byte, 0xC80)).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get skin_hist from db", zap.Error(err)) + s.logger.Error("Failed to save skin_hist", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return } var bit int @@ -1834,6 +1837,7 @@ func handleMsgMhfGetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT minidata FROM characters WHERE id = $1", pkt.CharID).Scan(&data) if err != nil { + s.logger.Error("Failed to load minidata") data = make([]byte, 1) } doAckBufSucceed(s, pkt.AckHandle, data) @@ -1844,7 +1848,7 @@ func handleMsgMhfSetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, pkt.RawDataPayload, "minidata") _, err := s.server.db.Exec("UPDATE characters SET minidata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update minidata in db", zap.Error(err)) + s.logger.Error("Failed to save minidata", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index 30f3294df..dfd9a56ff 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -305,13 +305,10 @@ func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrame() err := s.server.db.QueryRow("SELECT scenariodata FROM characters WHERE id = $1", s.charID).Scan(&scenarioData) if err != nil { - s.logger.Fatal("Failed to get scenario data contents in db", zap.Error(err)) + s.logger.Error("Failed to load scenariodata", zap.Error(err)) + bf.WriteBytes(make([]byte, 10)) } else { - if len(scenarioData) == 0 { - bf.WriteUint32(0x00) - } else { - bf.WriteBytes(scenarioData) - } + bf.WriteBytes(scenarioData) } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } From e6845d74d025e823ae0ed10250689627441abde0 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 4 Feb 2023 14:29:28 +1100 Subject: [PATCH 12/27] make various handlers not error fatally --- server/channelserver/handlers.go | 13 ++++++++----- server/channelserver/handlers_data.go | 14 +++++++++----- server/channelserver/handlers_rengoku.go | 8 +++++--- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 9fed99c89..3dd1fa76c 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -588,10 +588,11 @@ func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrame() err := s.server.db.QueryRow("SELECT item_box FROM users, characters WHERE characters.id = $1 AND users.id = characters.user_id", int(s.charID)).Scan(&boxContents) if err != nil { - s.logger.Fatal("Failed to get shared item box contents from db", zap.Error(err)) + s.logger.Error("Failed to get shared item box contents from db", zap.Error(err)) + bf.WriteBytes(make([]byte, 4)) } else { if len(boxContents) == 0 { - bf.WriteUint32(0x00) + bf.WriteBytes(make([]byte, 4)) } else { amount := len(boxContents) / 4 bf.WriteUint16(uint16(amount)) @@ -616,7 +617,9 @@ func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) { err := s.server.db.QueryRow("SELECT item_box FROM users, characters WHERE characters.id = $1 AND users.id = characters.user_id", int(s.charID)).Scan(&boxContents) if err != nil { - s.logger.Fatal("Failed to get shared item box contents from db", zap.Error(err)) + s.logger.Error("Failed to get shared item box contents from db", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } else { amount := len(boxContents) / 4 oldItems = make([]Item, amount) @@ -664,9 +667,9 @@ func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) { // Upload new item cache _, err = s.server.db.Exec("UPDATE users SET item_box = $1 FROM characters WHERE users.id = characters.user_id AND characters.id = $2", bf.Data(), int(s.charID)) if err != nil { - s.logger.Fatal("Failed to update shared item box contents in db", zap.Error(err)) + s.logger.Error("Failed to update shared item box contents in db", zap.Error(err)) } - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func handleMsgMhfGetCogInfo(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index dfd9a56ff..62b2282d9 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -29,7 +29,9 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { // diffs themselves are also potentially compressed diff, err := nullcomp.Decompress(pkt.RawDataPayload) if err != nil { - s.logger.Fatal("Failed to decompress diff", zap.Error(err)) + s.logger.Error("Failed to decompress diff", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } // Perform diff. s.logger.Info("Diffing...") @@ -39,7 +41,9 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { // Regular blob update. saveData, err := nullcomp.Decompress(pkt.RawDataPayload) if err != nil { - s.logger.Fatal("Failed to decompress savedata from packet", zap.Error(err)) + s.logger.Error("Failed to decompress savedata from packet", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } s.logger.Info("Updating save with blob") characterSaveData.decompSave = saveData @@ -64,9 +68,9 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { } _, err = s.server.db.Exec("UPDATE characters SET name=$1 WHERE id=$2", characterSaveData.Name, s.charID) if err != nil { - s.logger.Fatal("Failed to update character name in db", zap.Error(err)) + s.logger.Error("Failed to update character name in db", zap.Error(err)) } - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func grpToGR(n uint32) uint16 { @@ -288,7 +292,7 @@ func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, pkt.RawDataPayload, "scenario") _, err := s.server.db.Exec("UPDATE characters SET scenariodata = $1 WHERE id = $2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update scenario data in db", zap.Error(err)) + s.logger.Error("Failed to update scenario data in db", zap.Error(err)) } // Do this ack manually because it uses a non-(0|1) error code s.QueueSendMHF(&mhfpacket.MsgSysAck{ diff --git a/server/channelserver/handlers_rengoku.go b/server/channelserver/handlers_rengoku.go index c1e8d2dbd..732cb77ef 100644 --- a/server/channelserver/handlers_rengoku.go +++ b/server/channelserver/handlers_rengoku.go @@ -19,7 +19,9 @@ func handleMsgMhfSaveRengokuData(s *Session, p mhfpacket.MHFPacket) { dumpSaveData(s, pkt.RawDataPayload, "rengoku") _, err := s.server.db.Exec("UPDATE characters SET rengokudata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID) if err != nil { - s.logger.Fatal("Failed to update rengokudata savedata in db", zap.Error(err)) + s.logger.Error("Failed to save rengokudata", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) bf.Seek(71, 0) @@ -34,7 +36,7 @@ func handleMsgMhfSaveRengokuData(s *Session, p mhfpacket.MHFPacket) { s.server.db.Exec("INSERT INTO rengoku_score (character_id) VALUES ($1)", s.charID) } s.server.db.Exec("UPDATE rengoku_score SET max_stages_mp=$1, max_points_mp=$2, max_stages_sp=$3, max_points_sp=$4 WHERE character_id=$5", maxStageMp, maxScoreMp, maxStageSp, maxScoreSp, s.charID) - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func handleMsgMhfLoadRengokuData(s *Session, p mhfpacket.MHFPacket) { @@ -42,7 +44,7 @@ func handleMsgMhfLoadRengokuData(s *Session, p mhfpacket.MHFPacket) { var data []byte err := s.server.db.QueryRow("SELECT rengokudata FROM characters WHERE id = $1", s.charID).Scan(&data) if err != nil { - s.logger.Fatal("Failed to get rengokudata savedata from db", zap.Error(err)) + s.logger.Error("Failed to load rengokudata", zap.Error(err)) } if len(data) > 0 { doAckBufSucceed(s, pkt.AckHandle, data) From 3afaba519378dda559b519c18747970096cb21fb Mon Sep 17 00:00:00 2001 From: Yarg-mirror <104911041+Yarg-mirror@users.noreply.github.com> Date: Mon, 30 Jan 2023 11:09:01 +0100 Subject: [PATCH 13/27] Update handlers_data.go Under Windows: no change Under Linux: Fix directory creation with no read/write permissions that failed the creation of save data dump --- server/channelserver/handlers_data.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index 62b2282d9..207fc6547 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -240,7 +240,7 @@ func dumpSaveData(s *Session, data []byte, suffix string) { _, err := os.Stat(dir) if err != nil { if os.IsNotExist(err) { - err = os.Mkdir(dir, os.ModeDir) + err = os.Mkdir(dir, os.ModePerm) if err != nil { s.logger.Warn("Error dumping savedata, could not create folder") return From 09f2d138c0d11de2a1888969b132c72e94f05dc0 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 4 Feb 2023 15:44:07 +1100 Subject: [PATCH 14/27] make various handlers not error fatally --- server/channelserver/handlers_guild.go | 56 ++++++++++--------- .../channelserver/handlers_guild_adventure.go | 16 +++--- .../channelserver/handlers_guild_alliance.go | 8 +-- server/channelserver/handlers_kouryou.go | 6 +- server/channelserver/handlers_mail.go | 15 +++-- 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index ca1ddf973..de54263ff 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -1531,10 +1531,11 @@ func handleMsgMhfEnumerateGuildItem(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrame() err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", int(pkt.GuildId)).Scan(&boxContents) if err != nil { - s.logger.Fatal("Failed to get guild item box contents from db", zap.Error(err)) + s.logger.Error("Failed to get guild item box contents from db", zap.Error(err)) + bf.WriteBytes(make([]byte, 4)) } else { if len(boxContents) == 0 { - bf.WriteUint32(0x00) + bf.WriteBytes(make([]byte, 4)) } else { amount := len(boxContents) / 4 bf.WriteUint16(uint16(amount)) @@ -1564,7 +1565,9 @@ func handleMsgMhfUpdateGuildItem(s *Session, p mhfpacket.MHFPacket) { var oldItems []Item err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", int(pkt.GuildId)).Scan(&boxContents) if err != nil { - s.logger.Fatal("Failed to get guild item box contents from db", zap.Error(err)) + s.logger.Error("Failed to get guild item box contents from db", zap.Error(err)) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } else { amount := len(boxContents) / 4 oldItems = make([]Item, amount) @@ -1612,7 +1615,7 @@ func handleMsgMhfUpdateGuildItem(s *Session, p mhfpacket.MHFPacket) { // Upload new item cache _, err = s.server.db.Exec("UPDATE guilds SET item_box = $1 WHERE id = $2", bf.Data(), int(pkt.GuildId)) if err != nil { - s.logger.Fatal("Failed to update guild item box contents in db", zap.Error(err)) + s.logger.Error("Failed to update guild item box contents in db", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) @@ -1737,7 +1740,8 @@ func handleMsgMhfLoadGuildCooking(s *Session, p mhfpacket.MHFPacket) { guild, _ := GetGuildInfoByCharacterId(s, s.charID) data, err := s.server.db.Queryx("SELECT id, meal_id, level, expires FROM guild_meals WHERE guild_id = $1", guild.ID) if err != nil { - s.logger.Fatal("Failed to get guild meals from db", zap.Error(err)) + s.logger.Error("Failed to get guild meals from db", zap.Error(err)) + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) } temp := byteframe.NewByteFrame() count := 0 @@ -1745,7 +1749,7 @@ func handleMsgMhfLoadGuildCooking(s *Session, p mhfpacket.MHFPacket) { mealData := &GuildMeal{} err = data.StructScan(&mealData) if err != nil { - s.logger.Fatal("Failed to scan meal data", zap.Error(err)) + continue } if mealData.Expires > uint32(Time_Current_Adjusted().Add(-60*time.Minute).Unix()) { count++ @@ -1767,12 +1771,12 @@ func handleMsgMhfRegistGuildCooking(s *Session, p mhfpacket.MHFPacket) { if pkt.OverwriteID != 0 { _, err := s.server.db.Exec("DELETE FROM guild_meals WHERE id = $1", pkt.OverwriteID) if err != nil { - s.logger.Fatal("Failed to delete meal in db", zap.Error(err)) + s.logger.Error("Failed to delete meal in db", zap.Error(err)) } } _, err := s.server.db.Exec("INSERT INTO guild_meals (guild_id, meal_id, level, expires) VALUES ($1, $2, $3, $4)", guild.ID, pkt.MealID, pkt.Success, Time_Current_Adjusted().Add(30*time.Minute).Unix()) if err != nil { - s.logger.Fatal("Failed to register meal in db", zap.Error(err)) + s.logger.Error("Failed to register meal in db", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x01, 0x00}) } @@ -1826,7 +1830,9 @@ func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { msgs, err := s.server.db.Queryx("SELECT post_type, stamp_id, title, body, author_id, (EXTRACT(epoch FROM created_at)::int) as created_at, liked_by FROM guild_posts WHERE guild_id = $1 AND post_type = $2 ORDER BY created_at DESC", guild.ID, int(pkt.BoardType)) if err != nil { - s.logger.Fatal("Failed to get guild messages from db", zap.Error(err)) + s.logger.Error("Failed to get guild messages from db", zap.Error(err)) + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } bf := byteframe.NewByteFrame() @@ -1836,11 +1842,10 @@ func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { noMsgs = false postCount++ postData := &MessageBoardPost{} - err = msgs.StructScan(&postData) + msgs.StructScan(&postData) if err != nil { - s.logger.Fatal("Failed to get guild messages from db", zap.Error(err)) + continue } - bf.WriteUint32(postData.Type) bf.WriteUint32(postData.AuthorID) bf.WriteUint64(postData.Timestamp) @@ -1856,7 +1861,7 @@ func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { ps.Uint32(bf, postData.Body, true) } if noMsgs { - doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) } else { data := byteframe.NewByteFrame() data.WriteUint32(uint32(postCount)) @@ -1890,19 +1895,20 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { bodyConv = stringsupport.SJISToUTF8(body) _, err := s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, int(stampId), int(postType), titleConv, bodyConv) if err != nil { - s.logger.Fatal("Failed to add new guild message to db", zap.Error(err)) + s.logger.Error("Failed to add new guild message to db", zap.Error(err)) } - // TODO: if there are too many messages, purge excess + /* TODO: if there are too many messages, purge excess _, err = s.server.db.Exec("") if err != nil { s.logger.Fatal("Failed to remove excess guild messages from db", zap.Error(err)) } + */ case 1: // Delete message postType := bf.ReadUint32() timestamp := bf.ReadUint64() _, err := s.server.db.Exec("DELETE FROM guild_posts WHERE post_type = $1 AND (EXTRACT(epoch FROM created_at)::int) = $2 AND guild_id = $3", int(postType), int(timestamp), guild.ID) if err != nil { - s.logger.Fatal("Failed to delete guild message from db", zap.Error(err)) + s.logger.Error("Failed to delete guild message from db", zap.Error(err)) } case 2: // Update message postType := bf.ReadUint32() @@ -1915,7 +1921,7 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { bodyConv = stringsupport.SJISToUTF8(body) _, err := s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE post_type = $3 AND (EXTRACT(epoch FROM created_at)::int) = $4 AND guild_id = $5", titleConv, bodyConv, int(postType), int(timestamp), guild.ID) if err != nil { - s.logger.Fatal("Failed to update guild message in db", zap.Error(err)) + s.logger.Error("Failed to update guild message in db", zap.Error(err)) } case 3: // Update stamp postType := bf.ReadUint32() @@ -1923,7 +1929,7 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { stampId := bf.ReadUint32() _, err := s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", int(stampId), int(postType), int(timestamp), guild.ID) if err != nil { - s.logger.Fatal("Failed to update guild message stamp in db", zap.Error(err)) + s.logger.Error("Failed to update guild message stamp in db", zap.Error(err)) } case 4: // Like message postType := bf.ReadUint32() @@ -1932,19 +1938,19 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { var likedBy string err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE post_type = $1 AND (EXTRACT(epoch FROM created_at)::int) = $2 AND guild_id = $3", int(postType), int(timestamp), guild.ID).Scan(&likedBy) if err != nil { - s.logger.Fatal("Failed to get guild message like data from db", zap.Error(err)) + s.logger.Error("Failed to get guild message like data from db", zap.Error(err)) } else { if likeState { likedBy = stringsupport.CSVAdd(likedBy, int(s.charID)) _, err := s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", likedBy, int(postType), int(timestamp), guild.ID) if err != nil { - s.logger.Fatal("Failed to like guild message in db", zap.Error(err)) + s.logger.Error("Failed to like guild message in db", zap.Error(err)) } } else { likedBy = stringsupport.CSVRemove(likedBy, int(s.charID)) _, err := s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", likedBy, int(postType), int(timestamp), guild.ID) if err != nil { - s.logger.Fatal("Failed to unlike guild message in db", zap.Error(err)) + s.logger.Error("Failed to unlike guild message in db", zap.Error(err)) } } } @@ -1953,15 +1959,15 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { var newPosts int err := s.server.db.QueryRow("SELECT (EXTRACT(epoch FROM guild_post_checked)::int) FROM characters WHERE id = $1", s.charID).Scan(&timeChecked) if err != nil { - s.logger.Fatal("Failed to get last guild post check timestamp from db", zap.Error(err)) + s.logger.Error("Failed to get last guild post check timestamp from db", zap.Error(err)) } else { _, err = s.server.db.Exec("UPDATE characters SET guild_post_checked = $1 WHERE id = $2", time.Now(), s.charID) if err != nil { - s.logger.Fatal("Failed to update guild post check timestamp in db", zap.Error(err)) + s.logger.Error("Failed to update guild post check timestamp in db", zap.Error(err)) } else { err = s.server.db.QueryRow("SELECT COUNT(*) FROM guild_posts WHERE guild_id = $1 AND (EXTRACT(epoch FROM created_at)::int) > $2 AND author_id != $3", guild.ID, timeChecked, s.charID).Scan(&newPosts) if err != nil { - s.logger.Fatal("Failed to check for new guild posts in db", zap.Error(err)) + s.logger.Error("Failed to check for new guild posts in db", zap.Error(err)) } else { if newPosts > 0 { doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01}) @@ -1971,7 +1977,7 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { } } } - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func handleMsgMhfEntryRookieGuild(s *Session, p mhfpacket.MHFPacket) { diff --git a/server/channelserver/handlers_guild_adventure.go b/server/channelserver/handlers_guild_adventure.go index 45f836127..304b5721f 100644 --- a/server/channelserver/handlers_guild_adventure.go +++ b/server/channelserver/handlers_guild_adventure.go @@ -23,7 +23,9 @@ func handleMsgMhfLoadGuildAdventure(s *Session, p mhfpacket.MHFPacket) { guild, _ := GetGuildInfoByCharacterId(s, s.charID) data, err := s.server.db.Queryx("SELECT id, destination, charge, depart, return, collected_by FROM guild_adventures WHERE guild_id = $1", guild.ID) if err != nil { - s.logger.Fatal("Failed to get guild adventures from db", zap.Error(err)) + s.logger.Error("Failed to get guild adventures from db", zap.Error(err)) + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1)) + return } temp := byteframe.NewByteFrame() count := 0 @@ -32,7 +34,7 @@ func handleMsgMhfLoadGuildAdventure(s *Session, p mhfpacket.MHFPacket) { adventureData := &GuildAdventure{} err = data.StructScan(&adventureData) if err != nil { - s.logger.Fatal("Failed to scan adventure data", zap.Error(err)) + continue } temp.WriteUint32(adventureData.ID) temp.WriteUint32(adventureData.Destination) @@ -52,7 +54,7 @@ func handleMsgMhfRegistGuildAdventure(s *Session, p mhfpacket.MHFPacket) { guild, _ := GetGuildInfoByCharacterId(s, s.charID) _, err := s.server.db.Exec("INSERT INTO guild_adventures (guild_id, destination, depart, return) VALUES ($1, $2, $3, $4)", guild.ID, pkt.Destination, Time_Current_Adjusted().Unix(), Time_Current_Adjusted().Add(6*time.Hour).Unix()) if err != nil { - s.logger.Fatal("Failed to register guild adventure", zap.Error(err)) + s.logger.Error("Failed to register guild adventure", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } @@ -62,12 +64,12 @@ func handleMsgMhfAcquireGuildAdventure(s *Session, p mhfpacket.MHFPacket) { var collectedBy string err := s.server.db.QueryRow("SELECT collected_by FROM guild_adventures WHERE id = $1", pkt.ID).Scan(&collectedBy) if err != nil { - s.logger.Fatal("Error parsing adventure collected by", zap.Error(err)) + s.logger.Error("Error parsing adventure collected by", zap.Error(err)) } else { collectedBy = stringsupport.CSVAdd(collectedBy, int(s.charID)) _, err := s.server.db.Exec("UPDATE guild_adventures SET collected_by = $1 WHERE id = $2", collectedBy, pkt.ID) if err != nil { - s.logger.Fatal("Failed to collect adventure in db", zap.Error(err)) + s.logger.Error("Failed to collect adventure in db", zap.Error(err)) } } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) @@ -77,7 +79,7 @@ func handleMsgMhfChargeGuildAdventure(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfChargeGuildAdventure) _, err := s.server.db.Exec("UPDATE guild_adventures SET charge = charge + $1 WHERE id = $2", pkt.Amount, pkt.ID) if err != nil { - s.logger.Fatal("Failed to charge guild adventure", zap.Error(err)) + s.logger.Error("Failed to charge guild adventure", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } @@ -87,7 +89,7 @@ func handleMsgMhfRegistGuildAdventureDiva(s *Session, p mhfpacket.MHFPacket) { guild, _ := GetGuildInfoByCharacterId(s, s.charID) _, err := s.server.db.Exec("INSERT INTO guild_adventures (guild_id, destination, charge, depart, return) VALUES ($1, $2, $3, $4, $5)", guild.ID, pkt.Destination, pkt.Charge, Time_Current_Adjusted().Unix(), Time_Current_Adjusted().Add(1*time.Hour).Unix()) if err != nil { - s.logger.Fatal("Failed to register guild adventure", zap.Error(err)) + s.logger.Error("Failed to register guild adventure", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } diff --git a/server/channelserver/handlers_guild_alliance.go b/server/channelserver/handlers_guild_alliance.go index 7e2a9a2ac..a77ea1ef3 100644 --- a/server/channelserver/handlers_guild_alliance.go +++ b/server/channelserver/handlers_guild_alliance.go @@ -106,7 +106,7 @@ func handleMsgMhfCreateJoint(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfCreateJoint) _, err := s.server.db.Exec("INSERT INTO guild_alliances (name, parent_id) VALUES ($1, $2)", pkt.Name, pkt.GuildID) if err != nil { - s.logger.Fatal("Failed to create guild alliance in db", zap.Error(err)) + s.logger.Error("Failed to create guild alliance in db", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x01, 0x01, 0x01, 0x01}) } @@ -116,11 +116,11 @@ func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) { guild, err := GetGuildInfoByID(s, pkt.GuildID) if err != nil { - s.logger.Fatal("Failed to get guild info", zap.Error(err)) + s.logger.Error("Failed to get guild info", zap.Error(err)) } alliance, err := GetAllianceData(s, pkt.AllianceID) if err != nil { - s.logger.Fatal("Failed to get alliance info", zap.Error(err)) + s.logger.Error("Failed to get alliance info", zap.Error(err)) } switch pkt.Action { @@ -128,7 +128,7 @@ func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) { if guild.LeaderCharID == s.charID && alliance.ParentGuildID == guild.ID { _, err = s.server.db.Exec("DELETE FROM guild_alliances WHERE id=$1", alliance.ID) if err != nil { - s.logger.Fatal("Failed to disband alliance", zap.Error(err)) + s.logger.Error("Failed to disband alliance", zap.Error(err)) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } else { diff --git a/server/channelserver/handlers_kouryou.go b/server/channelserver/handlers_kouryou.go index 57f26ea40..bff9292a6 100644 --- a/server/channelserver/handlers_kouryou.go +++ b/server/channelserver/handlers_kouryou.go @@ -12,7 +12,7 @@ func handleMsgMhfAddKouryouPoint(s *Session, p mhfpacket.MHFPacket) { var points int err := s.server.db.QueryRow("UPDATE characters SET kouryou_point=COALESCE(kouryou_point + $1, $1) WHERE id=$2 RETURNING kouryou_point", pkt.KouryouPoints, s.charID).Scan(&points) if err != nil { - s.logger.Fatal("Failed to update KouryouPoint in db", zap.Error(err)) + s.logger.Error("Failed to update KouryouPoint in db", zap.Error(err)) } resp := byteframe.NewByteFrame() resp.WriteUint32(uint32(points)) @@ -24,7 +24,7 @@ func handleMsgMhfGetKouryouPoint(s *Session, p mhfpacket.MHFPacket) { var points int err := s.server.db.QueryRow("SELECT COALESCE(kouryou_point, 0) FROM characters WHERE id = $1", s.charID).Scan(&points) if err != nil { - s.logger.Fatal("Failed to get kouryou_point savedata from db", zap.Error(err)) + s.logger.Error("Failed to get kouryou_point savedata from db", zap.Error(err)) } resp := byteframe.NewByteFrame() resp.WriteUint32(uint32(points)) @@ -37,7 +37,7 @@ func handleMsgMhfExchangeKouryouPoint(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfExchangeKouryouPoint) err := s.server.db.QueryRow("UPDATE characters SET kouryou_point=kouryou_point - $1 WHERE id=$2 RETURNING kouryou_point", pkt.KouryouPoints, s.charID).Scan(&points) if err != nil { - s.logger.Fatal("Failed to update platemyset savedata in db", zap.Error(err)) + s.logger.Error("Failed to update platemyset savedata in db", zap.Error(err)) } resp := byteframe.NewByteFrame() resp.WriteUint32(uint32(points)) diff --git a/server/channelserver/handlers_mail.go b/server/channelserver/handlers_mail.go index e31e90eed..1df4711c6 100644 --- a/server/channelserver/handlers_mail.go +++ b/server/channelserver/handlers_mail.go @@ -392,24 +392,29 @@ func handleMsgMhfSendMail(s *Session, p mhfpacket.MHFPacket) { if pkt.RecipientID == 0 { // Guild mail g, err := GetGuildInfoByCharacterId(s, s.charID) if err != nil { - s.logger.Fatal("Failed to get guild info for mail") + s.logger.Error("Failed to get guild info for mail") + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } gm, err := GetGuildMembers(s, g.ID, false) if err != nil { - s.logger.Fatal("Failed to get guild members for mail") + s.logger.Error("Failed to get guild members for mail") + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } for i := 0; i < len(gm); i++ { _, err := s.server.db.Exec(query, s.charID, gm[i].CharID, pkt.Subject, pkt.Body, 0, 0, false) if err != nil { - s.logger.Fatal("Failed to send mail") + s.logger.Error("Failed to send mail") + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return } } } else { _, err := s.server.db.Exec(query, s.charID, pkt.RecipientID, pkt.Subject, pkt.Body, pkt.ItemID, pkt.Quantity, false) if err != nil { - s.logger.Fatal("Failed to send mail") + s.logger.Error("Failed to send mail") } } - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From bea4a8ad3a73df03d4960099a574f650f7402fb6 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 4 Feb 2023 22:14:30 +1100 Subject: [PATCH 15/27] make various handlers not error fatally --- server/channelserver/handlers_guild_alliance.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/channelserver/handlers_guild_alliance.go b/server/channelserver/handlers_guild_alliance.go index a77ea1ef3..fbb285e0a 100644 --- a/server/channelserver/handlers_guild_alliance.go +++ b/server/channelserver/handlers_guild_alliance.go @@ -73,7 +73,8 @@ func buildAllianceObjectFromDbResult(result *sqlx.Rows, err error, s *Session) ( parentGuild, err := GetGuildInfoByID(s, alliance.ParentGuildID) if err != nil { - s.logger.Fatal("Failed to get parent guild info", zap.Error(err)) + s.logger.Error("Failed to get parent guild info", zap.Error(err)) + return nil, err } else { alliance.ParentGuild = *parentGuild alliance.TotalMembers += parentGuild.MemberCount @@ -82,7 +83,8 @@ func buildAllianceObjectFromDbResult(result *sqlx.Rows, err error, s *Session) ( if alliance.SubGuild1ID > 0 { subGuild1, err := GetGuildInfoByID(s, alliance.SubGuild1ID) if err != nil { - s.logger.Fatal("Failed to get sub guild 1 info", zap.Error(err)) + s.logger.Error("Failed to get sub guild 1 info", zap.Error(err)) + return nil, err } else { alliance.SubGuild1 = *subGuild1 alliance.TotalMembers += subGuild1.MemberCount @@ -92,7 +94,8 @@ func buildAllianceObjectFromDbResult(result *sqlx.Rows, err error, s *Session) ( if alliance.SubGuild2ID > 0 { subGuild2, err := GetGuildInfoByID(s, alliance.SubGuild2ID) if err != nil { - s.logger.Fatal("Failed to get sub guild 2 info", zap.Error(err)) + s.logger.Error("Failed to get sub guild 2 info", zap.Error(err)) + return nil, err } else { alliance.SubGuild2 = *subGuild2 alliance.TotalMembers += subGuild2.MemberCount From 717a34b5b99fdc5011e81c2d4c27e66b4acbed83 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 4 Feb 2023 22:41:06 +1100 Subject: [PATCH 16/27] implement automatic damage scaling for raviente --- server/channelserver/handlers_cast_binary.go | 23 +++---------------- server/channelserver/handlers_register.go | 17 +++++++------- server/channelserver/sys_channel_server.go | 24 ++++++++++++++++---- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 17a1d7858..8d9c6356c 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -167,8 +167,7 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { } case BroadcastTypeServer: if pkt.MessageType == 1 { - raviSema := getRaviSemaphore(s) - if raviSema != "" { + if getRaviSemaphore(s.server) != nil { s.server.BroadcastMHF(resp, s) } } else { @@ -361,7 +360,7 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { if strings.HasPrefix(chatMessage.Message, commands["Raviente"].Prefix) { if commands["Raviente"].Enabled { - if getRaviSemaphore(s) != "" { + if getRaviSemaphore(s.server) != nil { s.server.raviente.Lock() if !strings.HasPrefix(chatMessage.Message, "!ravi ") { sendServerChatMessage(s, "No Raviente command specified!") @@ -374,24 +373,8 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { } else { sendServerChatMessage(s, "The Great Slaying has already begun!") } - } else if strings.HasPrefix(chatMessage.Message, "!ravi sm") || strings.HasPrefix(chatMessage.Message, "!ravi setmultiplier") { - var num uint16 - n, numerr := fmt.Sscanf(chatMessage.Message, "!ravi sm %d", &num) - if numerr != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !ravi sm n") - } else if s.server.raviente.state.damageMultiplier == 1 { - if num > 32 { - sendServerChatMessage(s, "Raviente multiplier too high, defaulting to 32x") - s.server.raviente.state.damageMultiplier = 32 - } else { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier set to %dx", num)) - s.server.raviente.state.damageMultiplier = uint32(num) - } - } else { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is already set to %dx!", s.server.raviente.state.damageMultiplier)) - } } else if strings.HasPrefix(chatMessage.Message, "!ravi cm") || strings.HasPrefix(chatMessage.Message, "!ravi checkmultiplier") { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.state.damageMultiplier)) + sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.GetRaviMultiplier(s.server))) } else if strings.HasPrefix(chatMessage.Message, "!ravi sr") || strings.HasPrefix(chatMessage.Message, "!ravi sendres") { if s.server.raviente.state.stateData[28] > 0 { sendServerChatMessage(s, "Sending resurrection support!") diff --git a/server/channelserver/handlers_register.go b/server/channelserver/handlers_register.go index 2c44cc6db..49afc594f 100644 --- a/server/channelserver/handlers_register.go +++ b/server/channelserver/handlers_register.go @@ -21,7 +21,7 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) { resp.WriteUint8(1) resp.WriteUint8(dest) ref := &s.server.raviente.state.stateData[dest] - damageMultiplier := s.server.raviente.state.damageMultiplier + damageMultiplier := s.server.raviente.GetRaviMultiplier(s.server) switch op { case 2: resp.WriteUint32(*ref) @@ -252,21 +252,21 @@ func (s *Session) notifyRavi() { raviNotif.WriteUint16(uint16(temp.Opcode())) temp.Build(raviNotif, s.clientContext) raviNotif.WriteUint16(0x0010) // End it. - sema := getRaviSemaphore(s) - if sema != "" { - for session := range s.server.semaphore[sema].clients { + sema := getRaviSemaphore(s.server) + if sema != nil { + for session := range sema.clients { session.QueueSend(raviNotif.Data()) } } } -func getRaviSemaphore(s *Session) string { - for _, semaphore := range s.server.semaphore { +func getRaviSemaphore(s *Server) *Semaphore { + for _, semaphore := range s.semaphore { if strings.HasPrefix(semaphore.id_semaphore, "hs_l0u3B5") && strings.HasSuffix(semaphore.id_semaphore, "4") { - return semaphore.id_semaphore + return semaphore } } - return "" + return nil } func resetRavi(s *Session) { @@ -278,7 +278,6 @@ func resetRavi(s *Session) { s.server.raviente.register.ravienteType = 0 s.server.raviente.register.maxPlayers = 0 s.server.raviente.register.carveQuest = 0 - s.server.raviente.state.damageMultiplier = 1 s.server.raviente.register.register = []uint32{0, 0, 0, 0, 0} s.server.raviente.state.stateData = []uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} s.server.raviente.support.supportData = []uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index 7c7447dfa..e388149eb 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -92,8 +92,7 @@ type RavienteRegister struct { } type RavienteState struct { - damageMultiplier uint32 - stateData []uint32 + stateData []uint32 } type RavienteSupport struct { @@ -111,9 +110,7 @@ func NewRaviente() *Raviente { maxPlayers: 0, carveQuest: 0, } - ravienteState := &RavienteState{ - damageMultiplier: 1, - } + ravienteState := &RavienteState{} ravienteSupport := &RavienteSupport{} ravienteRegister.register = []uint32{0, 0, 0, 0, 0} ravienteState.stateData = []uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -127,6 +124,23 @@ func NewRaviente() *Raviente { return raviente } +func (r *Raviente) GetRaviMultiplier(s *Server) uint32 { + raviSema := getRaviSemaphore(s) + if raviSema != nil { + var minPlayers uint32 + if r.register.maxPlayers > 8 { + minPlayers = 24 + } else { + minPlayers = 4 + } + if uint32(len(raviSema.clients)) > minPlayers { + return 1 + } + return minPlayers / uint32(len(raviSema.clients)) + } + return 0 +} + // NewServer creates a new Server type. func NewServer(config *Config) *Server { s := &Server{ From a47bde7a4a0c05195b7d9d86a8623f3bc9ee5b50 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 5 Feb 2023 19:41:36 +1100 Subject: [PATCH 17/27] rewrite CastBinary parsing --- server/channelserver/handlers_cast_binary.go | 483 +++++++++---------- 1 file changed, 239 insertions(+), 244 deletions(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 8d9c6356c..22f620a38 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -78,6 +78,233 @@ func sendServerChatMessage(s *Session, message string) { s.QueueSendMHF(castedBin) } +func parseChatCommand(s *Session, command string) { + if strings.HasPrefix(command, commands["Reload"].Prefix) { + // Flush all objects and users and reload + if commands["Reload"].Enabled { + sendServerChatMessage(s, "Reloading players...") + var temp mhfpacket.MHFPacket + deleteNotif := byteframe.NewByteFrame() + for _, object := range s.stage.objects { + if object.ownerCharID == s.charID { + continue + } + temp = &mhfpacket.MsgSysDeleteObject{ObjID: object.id} + deleteNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(deleteNotif, s.clientContext) + } + for _, session := range s.server.sessions { + if s == session { + continue + } + temp = &mhfpacket.MsgSysDeleteUser{CharID: session.charID} + deleteNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(deleteNotif, s.clientContext) + } + deleteNotif.WriteUint16(0x0010) + s.QueueSend(deleteNotif.Data()) + time.Sleep(500 * time.Millisecond) + reloadNotif := byteframe.NewByteFrame() + for _, session := range s.server.sessions { + if s == session { + continue + } + temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} + reloadNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(reloadNotif, s.clientContext) + for i := 0; i < 3; i++ { + temp = &mhfpacket.MsgSysNotifyUserBinary{ + CharID: session.charID, + BinaryType: uint8(i + 1), + } + reloadNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(reloadNotif, s.clientContext) + } + } + for _, obj := range s.stage.objects { + if obj.ownerCharID == s.charID { + continue + } + temp = &mhfpacket.MsgSysDuplicateObject{ + ObjID: obj.id, + X: obj.x, + Y: obj.y, + Z: obj.z, + Unk0: 0, + OwnerCharID: obj.ownerCharID, + } + reloadNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(reloadNotif, s.clientContext) + } + reloadNotif.WriteUint16(0x0010) + s.QueueSend(reloadNotif.Data()) + } else { + sendDisabledCommandMessage(s, commands["Reload"]) + } + } + + if strings.HasPrefix(command, commands["KeyQuest"].Prefix) { + if commands["KeyQuest"].Enabled { + if strings.HasPrefix(command, "!kqf get") { + sendServerChatMessage(s, fmt.Sprintf("KQF: %x", s.kqf)) + } else if strings.HasPrefix(command, "!kqf set") { + var hexs string + n, numerr := fmt.Sscanf(command, "!kqf set %s", &hexs) + if numerr != nil || n != 1 || len(hexs) != 16 { + sendServerChatMessage(s, "Error in command. Format: !kqf set xxxxxxxxxxxxxxxx") + } else { + hexd, _ := hex.DecodeString(hexs) + s.kqf = hexd + s.kqfOverride = true + sendServerChatMessage(s, "KQF set, please switch Land/World") + } + } + } else { + sendDisabledCommandMessage(s, commands["KeyQuest"]) + } + } + + if strings.HasPrefix(command, commands["Rights"].Prefix) { + // Set account rights + if commands["Rights"].Enabled { + var v uint32 + n, err := fmt.Sscanf(command, "!rights %d", &v) + if err != nil || n != 1 { + sendServerChatMessage(s, "Error in command. Format: !rights n") + } else { + _, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID) + if err == nil { + sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v)) + } + } + } else { + sendDisabledCommandMessage(s, commands["Rights"]) + } + } + + if strings.HasPrefix(command, commands["Course"].Prefix) { + if commands["Course"].Enabled { + var name string + n, err := fmt.Sscanf(command, "!course %s", &name) + if err != nil || n != 1 { + sendServerChatMessage(s, "Error in command. Format: !course ") + } else { + name = strings.ToLower(name) + for _, course := range mhfpacket.Courses() { + for _, alias := range course.Aliases { + if strings.ToLower(name) == strings.ToLower(alias) { + if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases[0], Enabled: true}) { + if s.FindCourse(name).ID != 0 { + ei := slices.IndexFunc(s.courses, func(c mhfpacket.Course) bool { + for _, alias := range c.Aliases { + if strings.ToLower(name) == strings.ToLower(alias) { + return true + } + } + return false + }) + if ei != -1 { + s.courses = append(s.courses[:ei], s.courses[ei+1:]...) + sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled`, course.Aliases[0])) + } + } else { + s.courses = append(s.courses, course) + sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled`, course.Aliases[0])) + } + var newInt uint32 + for _, course := range s.courses { + newInt += uint32(math.Pow(2, float64(course.ID))) + } + s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", newInt, s.charID) + updateRights(s) + } else { + sendServerChatMessage(s, fmt.Sprintf(`%s Course is locked`, course.Aliases[0])) + } + } + } + } + } + } else { + sendDisabledCommandMessage(s, commands["Course"]) + } + } + + if strings.HasPrefix(command, commands["Raviente"].Prefix) { + if commands["Raviente"].Enabled { + if getRaviSemaphore(s.server) != nil { + s.server.raviente.Lock() + if !strings.HasPrefix(command, "!ravi ") { + sendServerChatMessage(s, "No Raviente command specified!") + } else { + if strings.HasPrefix(command, "!ravi start") { + if s.server.raviente.register.startTime == 0 { + s.server.raviente.register.startTime = s.server.raviente.register.postTime + sendServerChatMessage(s, "The Great Slaying will begin in a moment") + s.notifyRavi() + } else { + sendServerChatMessage(s, "The Great Slaying has already begun!") + } + } else if strings.HasPrefix(command, "!ravi cm") || strings.HasPrefix(command, "!ravi checkmultiplier") { + sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.GetRaviMultiplier(s.server))) + } else if strings.HasPrefix(command, "!ravi sr") || strings.HasPrefix(command, "!ravi sendres") { + if s.server.raviente.state.stateData[28] > 0 { + sendServerChatMessage(s, "Sending resurrection support!") + s.server.raviente.state.stateData[28] = 0 + } else { + sendServerChatMessage(s, "Resurrection support has not been requested!") + } + } else if strings.HasPrefix(command, "!ravi ss") || strings.HasPrefix(command, "!ravi sendsed") { + sendServerChatMessage(s, "Sending sedation support if requested!") + // Total BerRavi HP + HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] + s.server.raviente.support.supportData[1] = HP + } else if strings.HasPrefix(command, "!ravi rs") || strings.HasPrefix(command, "!ravi reqsed") { + sendServerChatMessage(s, "Requesting sedation support!") + // Total BerRavi HP + HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] + s.server.raviente.support.supportData[1] = HP + 12 + } else { + sendServerChatMessage(s, "Raviente command not recognised!") + } + } + s.server.raviente.Unlock() + } else { + sendServerChatMessage(s, "No one has joined the Great Slaying!") + } + } else { + sendDisabledCommandMessage(s, commands["Raviente"]) + } + } + + if strings.HasPrefix(command, commands["Teleport"].Prefix) { + if commands["Teleport"].Enabled { + var x, y int16 + n, err := fmt.Sscanf(command, "!tele %d %d", &x, &y) + if err != nil || n != 2 { + sendServerChatMessage(s, "Invalid command. Usage:\"!tele 500 500\"") + } else { + sendServerChatMessage(s, fmt.Sprintf("Teleporting to %d %d", x, y)) + + // Make the inside of the casted binary + payload := byteframe.NewByteFrame() + payload.SetLE() + payload.WriteUint8(2) // SetState type(position == 2) + payload.WriteInt16(x) // X + payload.WriteInt16(y) // Y + payloadBytes := payload.Data() + + s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{ + CharID: s.charID, + MessageType: BinaryMessageTypeState, + RawDataPayload: payloadBytes, + }) + } + } else { + sendDisabledCommandMessage(s, commands["Teleport"]) + } + } +} + func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysCastBinary) tmp := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) @@ -144,6 +371,18 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { roll.WriteNullTerminatedBytes([]byte(dice)) roll.WriteNullTerminatedBytes(tmp.ReadNullTerminatedBytes()) realPayload = roll.Data() + } else { + bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) + bf.SetLE() + chatMessage := &binpacket.MsgBinChat{} + chatMessage.Parse(bf) + if strings.HasPrefix(chatMessage.Message, "!") { + parseChatCommand(s, chatMessage.Message) + return + } + if (pkt.BroadcastType == BroadcastTypeStage && s.stage.id == "sl1Ns200p0a0u0") || pkt.BroadcastType == BroadcastTypeWorld { + s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message) + } } } @@ -189,250 +428,6 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { } s.Unlock() } - - // Handle chat - if pkt.MessageType == BinaryMessageTypeChat { - bf := byteframe.NewByteFrameFromBytes(realPayload) - - // IMPORTANT! Casted binary objects are sent _as they are in memory_, - // this means little endian for LE CPUs, might be different for PS3/PS4/PSP/XBOX. - bf.SetLE() - - chatMessage := &binpacket.MsgBinChat{} - chatMessage.Parse(bf) - - fmt.Printf("Got chat message: %+v\n", chatMessage) - - // Discord integration - if (pkt.BroadcastType == BroadcastTypeStage && s.stage.id == "sl1Ns200p0a0u0") || pkt.BroadcastType == BroadcastTypeWorld { - s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message) - } - - if strings.HasPrefix(chatMessage.Message, commands["Reload"].Prefix) { - // Flush all objects and users and reload - if commands["Reload"].Enabled { - sendServerChatMessage(s, "Reloading players...") - var temp mhfpacket.MHFPacket - deleteNotif := byteframe.NewByteFrame() - for _, object := range s.stage.objects { - if object.ownerCharID == s.charID { - continue - } - temp = &mhfpacket.MsgSysDeleteObject{ObjID: object.id} - deleteNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(deleteNotif, s.clientContext) - } - for _, session := range s.server.sessions { - if s == session { - continue - } - temp = &mhfpacket.MsgSysDeleteUser{CharID: session.charID} - deleteNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(deleteNotif, s.clientContext) - } - deleteNotif.WriteUint16(0x0010) - s.QueueSend(deleteNotif.Data()) - time.Sleep(500 * time.Millisecond) - reloadNotif := byteframe.NewByteFrame() - for _, session := range s.server.sessions { - if s == session { - continue - } - temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} - reloadNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(reloadNotif, s.clientContext) - for i := 0; i < 3; i++ { - temp = &mhfpacket.MsgSysNotifyUserBinary{ - CharID: session.charID, - BinaryType: uint8(i + 1), - } - reloadNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(reloadNotif, s.clientContext) - } - } - for _, obj := range s.stage.objects { - if obj.ownerCharID == s.charID { - continue - } - temp = &mhfpacket.MsgSysDuplicateObject{ - ObjID: obj.id, - X: obj.x, - Y: obj.y, - Z: obj.z, - Unk0: 0, - OwnerCharID: obj.ownerCharID, - } - reloadNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(reloadNotif, s.clientContext) - } - reloadNotif.WriteUint16(0x0010) - s.QueueSend(reloadNotif.Data()) - } else { - sendDisabledCommandMessage(s, commands["Reload"]) - } - } - - if strings.HasPrefix(chatMessage.Message, commands["KeyQuest"].Prefix) { - if commands["KeyQuest"].Enabled { - if strings.HasPrefix(chatMessage.Message, "!kqf get") { - sendServerChatMessage(s, fmt.Sprintf("KQF: %x", s.kqf)) - } else if strings.HasPrefix(chatMessage.Message, "!kqf set") { - var hexs string - n, numerr := fmt.Sscanf(chatMessage.Message, "!kqf set %s", &hexs) - if numerr != nil || n != 1 || len(hexs) != 16 { - sendServerChatMessage(s, "Error in command. Format: !kqf set xxxxxxxxxxxxxxxx") - } else { - hexd, _ := hex.DecodeString(hexs) - s.kqf = hexd - s.kqfOverride = true - sendServerChatMessage(s, "KQF set, please switch Land/World") - } - } - } else { - sendDisabledCommandMessage(s, commands["KeyQuest"]) - } - } - - if strings.HasPrefix(chatMessage.Message, commands["Rights"].Prefix) { - // Set account rights - if commands["Rights"].Enabled { - var v uint32 - n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v) - if err != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !rights n") - } else { - _, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID) - if err == nil { - sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v)) - } - } - } else { - sendDisabledCommandMessage(s, commands["Rights"]) - } - } - - if strings.HasPrefix(chatMessage.Message, commands["Course"].Prefix) { - if commands["Course"].Enabled { - var name string - n, err := fmt.Sscanf(chatMessage.Message, "!course %s", &name) - if err != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !course ") - } else { - name = strings.ToLower(name) - for _, course := range mhfpacket.Courses() { - for _, alias := range course.Aliases { - if strings.ToLower(name) == strings.ToLower(alias) { - if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases[0], Enabled: true}) { - if s.FindCourse(name).ID != 0 { - ei := slices.IndexFunc(s.courses, func(c mhfpacket.Course) bool { - for _, alias := range c.Aliases { - if strings.ToLower(name) == strings.ToLower(alias) { - return true - } - } - return false - }) - if ei != -1 { - s.courses = append(s.courses[:ei], s.courses[ei+1:]...) - sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled`, course.Aliases[0])) - } - } else { - s.courses = append(s.courses, course) - sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled`, course.Aliases[0])) - } - var newInt uint32 - for _, course := range s.courses { - newInt += uint32(math.Pow(2, float64(course.ID))) - } - s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", newInt, s.charID) - updateRights(s) - } else { - sendServerChatMessage(s, fmt.Sprintf(`%s Course is locked`, course.Aliases[0])) - } - } - } - } - } - } else { - sendDisabledCommandMessage(s, commands["Course"]) - } - } - - if strings.HasPrefix(chatMessage.Message, commands["Raviente"].Prefix) { - if commands["Raviente"].Enabled { - if getRaviSemaphore(s.server) != nil { - s.server.raviente.Lock() - if !strings.HasPrefix(chatMessage.Message, "!ravi ") { - sendServerChatMessage(s, "No Raviente command specified!") - } else { - if strings.HasPrefix(chatMessage.Message, "!ravi start") { - if s.server.raviente.register.startTime == 0 { - s.server.raviente.register.startTime = s.server.raviente.register.postTime - sendServerChatMessage(s, "The Great Slaying will begin in a moment") - s.notifyRavi() - } else { - sendServerChatMessage(s, "The Great Slaying has already begun!") - } - } else if strings.HasPrefix(chatMessage.Message, "!ravi cm") || strings.HasPrefix(chatMessage.Message, "!ravi checkmultiplier") { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.GetRaviMultiplier(s.server))) - } else if strings.HasPrefix(chatMessage.Message, "!ravi sr") || strings.HasPrefix(chatMessage.Message, "!ravi sendres") { - if s.server.raviente.state.stateData[28] > 0 { - sendServerChatMessage(s, "Sending resurrection support!") - s.server.raviente.state.stateData[28] = 0 - } else { - sendServerChatMessage(s, "Resurrection support has not been requested!") - } - } else if strings.HasPrefix(chatMessage.Message, "!ravi ss") || strings.HasPrefix(chatMessage.Message, "!ravi sendsed") { - sendServerChatMessage(s, "Sending sedation support if requested!") - // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP - } else if strings.HasPrefix(chatMessage.Message, "!ravi rs") || strings.HasPrefix(chatMessage.Message, "!ravi reqsed") { - sendServerChatMessage(s, "Requesting sedation support!") - // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP + 12 - } else { - sendServerChatMessage(s, "Raviente command not recognised!") - } - } - s.server.raviente.Unlock() - } else { - sendServerChatMessage(s, "No one has joined the Great Slaying!") - } - } else { - sendDisabledCommandMessage(s, commands["Raviente"]) - } - } - - if strings.HasPrefix(chatMessage.Message, commands["Teleport"].Prefix) { - if commands["Teleport"].Enabled { - var x, y int16 - n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y) - if err != nil || n != 2 { - sendServerChatMessage(s, "Invalid command. Usage:\"!tele 500 500\"") - } else { - sendServerChatMessage(s, fmt.Sprintf("Teleporting to %d %d", x, y)) - - // Make the inside of the casted binary - payload := byteframe.NewByteFrame() - payload.SetLE() - payload.WriteUint8(2) // SetState type(position == 2) - payload.WriteInt16(x) // X - payload.WriteInt16(y) // Y - payloadBytes := payload.Data() - - s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{ - CharID: s.charID, - MessageType: BinaryMessageTypeState, - RawDataPayload: payloadBytes, - }) - } - } else { - sendDisabledCommandMessage(s, commands["Teleport"]) - } - } - } } func handleMsgSysCastedBinary(s *Session, p mhfpacket.MHFPacket) {} From 132870f0204157e8cae1a85084898adc2864ce6c Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 8 Feb 2023 00:01:02 +1100 Subject: [PATCH 18/27] add support for JP chat command responses --- server/channelserver/handlers_cast_binary.go | 58 ++++++++++---------- server/channelserver/sys_language.go | 52 ++++++++++++++++++ 2 files changed, 81 insertions(+), 29 deletions(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 22f620a38..a7a9856e2 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -53,7 +53,7 @@ func init() { } func sendDisabledCommandMessage(s *Session, cmd config.Command) { - sendServerChatMessage(s, fmt.Sprintf("%s command is disabled", cmd.Name)) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandDisabled"], cmd.Name)) } func sendServerChatMessage(s *Session, message string) { @@ -82,7 +82,7 @@ func parseChatCommand(s *Session, command string) { if strings.HasPrefix(command, commands["Reload"].Prefix) { // Flush all objects and users and reload if commands["Reload"].Enabled { - sendServerChatMessage(s, "Reloading players...") + sendServerChatMessage(s, s.server.dict["commandReload"]) var temp mhfpacket.MHFPacket deleteNotif := byteframe.NewByteFrame() for _, object := range s.stage.objects { @@ -145,18 +145,18 @@ func parseChatCommand(s *Session, command string) { if strings.HasPrefix(command, commands["KeyQuest"].Prefix) { if commands["KeyQuest"].Enabled { - if strings.HasPrefix(command, "!kqf get") { - sendServerChatMessage(s, fmt.Sprintf("KQF: %x", s.kqf)) - } else if strings.HasPrefix(command, "!kqf set") { + if strings.HasPrefix(command, fmt.Sprintf("%s get", commands["KeyQuest"].Prefix)) { + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfGet"], s.kqf)) + } else if strings.HasPrefix(command, fmt.Sprintf("%s set", commands["KeyQuest"].Prefix)) { var hexs string - n, numerr := fmt.Sscanf(command, "!kqf set %s", &hexs) + n, numerr := fmt.Sscanf(command, fmt.Sprintf("%s set %%s", commands["KeyQuest"].Prefix), &hexs) if numerr != nil || n != 1 || len(hexs) != 16 { - sendServerChatMessage(s, "Error in command. Format: !kqf set xxxxxxxxxxxxxxxx") + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfSetError"], commands["KeyQuest"].Prefix)) } else { hexd, _ := hex.DecodeString(hexs) s.kqf = hexd s.kqfOverride = true - sendServerChatMessage(s, "KQF set, please switch Land/World") + sendServerChatMessage(s, s.server.dict["commandKqfSetSuccess"]) } } } else { @@ -168,13 +168,13 @@ func parseChatCommand(s *Session, command string) { // Set account rights if commands["Rights"].Enabled { var v uint32 - n, err := fmt.Sscanf(command, "!rights %d", &v) + n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%d", commands["Rights"].Prefix), &v) if err != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !rights n") + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsError"], commands["Rights"].Prefix)) } else { _, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID) if err == nil { - sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v)) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsSuccess"], v)) } } } else { @@ -185,9 +185,9 @@ func parseChatCommand(s *Session, command string) { if strings.HasPrefix(command, commands["Course"].Prefix) { if commands["Course"].Enabled { var name string - n, err := fmt.Sscanf(command, "!course %s", &name) + n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%s", commands["Course"].Prefix), &name) if err != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !course ") + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix)) } else { name = strings.ToLower(name) for _, course := range mhfpacket.Courses() { @@ -205,11 +205,11 @@ func parseChatCommand(s *Session, command string) { }) if ei != -1 { s.courses = append(s.courses[:ei], s.courses[ei+1:]...) - sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled`, course.Aliases[0])) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseDisabled"], course.Aliases[0])) } } else { s.courses = append(s.courses, course) - sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled`, course.Aliases[0])) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseEnabled"], course.Aliases[0])) } var newInt uint32 for _, course := range s.courses { @@ -218,7 +218,7 @@ func parseChatCommand(s *Session, command string) { s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", newInt, s.charID) updateRights(s) } else { - sendServerChatMessage(s, fmt.Sprintf(`%s Course is locked`, course.Aliases[0])) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseLocked"], course.Aliases[0])) } } } @@ -234,42 +234,42 @@ func parseChatCommand(s *Session, command string) { if getRaviSemaphore(s.server) != nil { s.server.raviente.Lock() if !strings.HasPrefix(command, "!ravi ") { - sendServerChatMessage(s, "No Raviente command specified!") + sendServerChatMessage(s, s.server.dict["commandRaviNoCommand"]) } else { if strings.HasPrefix(command, "!ravi start") { if s.server.raviente.register.startTime == 0 { s.server.raviente.register.startTime = s.server.raviente.register.postTime - sendServerChatMessage(s, "The Great Slaying will begin in a moment") + sendServerChatMessage(s, s.server.dict["commandRaviStartSuccess"]) s.notifyRavi() } else { - sendServerChatMessage(s, "The Great Slaying has already begun!") + sendServerChatMessage(s, s.server.dict["commandRaviStartError"]) } } else if strings.HasPrefix(command, "!ravi cm") || strings.HasPrefix(command, "!ravi checkmultiplier") { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.GetRaviMultiplier(s.server))) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRaviMultiplier"], s.server.raviente.GetRaviMultiplier(s.server))) } else if strings.HasPrefix(command, "!ravi sr") || strings.HasPrefix(command, "!ravi sendres") { if s.server.raviente.state.stateData[28] > 0 { - sendServerChatMessage(s, "Sending resurrection support!") + sendServerChatMessage(s, s.server.dict["commandRaviResSuccess"]) s.server.raviente.state.stateData[28] = 0 } else { - sendServerChatMessage(s, "Resurrection support has not been requested!") + sendServerChatMessage(s, s.server.dict["commandRaviResError"]) } } else if strings.HasPrefix(command, "!ravi ss") || strings.HasPrefix(command, "!ravi sendsed") { - sendServerChatMessage(s, "Sending sedation support if requested!") + sendServerChatMessage(s, s.server.dict["commandRaviSedSuccess"]) // Total BerRavi HP HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] s.server.raviente.support.supportData[1] = HP } else if strings.HasPrefix(command, "!ravi rs") || strings.HasPrefix(command, "!ravi reqsed") { - sendServerChatMessage(s, "Requesting sedation support!") + sendServerChatMessage(s, s.server.dict["commandRaviRequest"]) // Total BerRavi HP HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] s.server.raviente.support.supportData[1] = HP + 12 } else { - sendServerChatMessage(s, "Raviente command not recognised!") + sendServerChatMessage(s, s.server.dict["commandRaviError"]) } } s.server.raviente.Unlock() } else { - sendServerChatMessage(s, "No one has joined the Great Slaying!") + sendServerChatMessage(s, s.server.dict["commandRaviNoPlayers"]) } } else { sendDisabledCommandMessage(s, commands["Raviente"]) @@ -279,11 +279,11 @@ func parseChatCommand(s *Session, command string) { if strings.HasPrefix(command, commands["Teleport"].Prefix) { if commands["Teleport"].Enabled { var x, y int16 - n, err := fmt.Sscanf(command, "!tele %d %d", &x, &y) + n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%d %%d", commands["Teleport"].Prefix), &x, &y) if err != nil || n != 2 { - sendServerChatMessage(s, "Invalid command. Usage:\"!tele 500 500\"") + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportError"], commands["Teleport"].Prefix)) } else { - sendServerChatMessage(s, fmt.Sprintf("Teleporting to %d %d", x, y)) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportSuccess"], x, y)) // Make the inside of the casted binary payload := byteframe.NewByteFrame() diff --git a/server/channelserver/sys_language.go b/server/channelserver/sys_language.go index 1dc917559..b7bf57b4f 100644 --- a/server/channelserver/sys_language.go +++ b/server/channelserver/sys_language.go @@ -6,6 +6,32 @@ func getLangStrings(s *Server) map[string]string { case "jp": strings["language"] = "日本語" strings["cafeReset"] = "%d/%dにリセット" + + strings["commandDisabled"] = "%sのコマンドは無効です" + strings["commandReload"] = "リロードします" + strings["commandKqfGet"] = "現在のキークエストフラグ:%x" + strings["commandKqfSetError"] = "キークエコマンドエラー 例:%s set xxxxxxxxxxxxxxxx" + strings["commandKqfSetSuccess"] = "キークエストのフラグが更新されました。ワールド/ランドを移動してください" + strings["commandRightsError"] = "コース更新コマンドエラー 例:%s x" + strings["commandRightsSuccess"] = "コース情報を更新しました:%d" + strings["commandCourseError"] = "コース確認コマンドエラー 例:%s " + strings["commandCourseDisabled"] = "%sコースは無効です" + strings["commandCourseEnabled"] = "%sコースは有効です" + strings["commandCourseLocked"] = "%sコースはロックされています" + strings["commandTeleportError"] = "テレポートコマンドエラー 構文:%s x y" + strings["commandTeleportSuccess"] = "%d %dにテレポート" + + strings["commandRaviNoCommand"] = "ラヴィコマンドが指定されていません" + strings["commandRaviStartSuccess"] = "大討伐を開始します" + strings["commandRaviStartError"] = "大討伐は既に開催されています" + strings["commandRaviMultiplier"] = "ラヴィダメージ倍率:x%d" + strings["commandRaviResSuccess"] = "復活支援を実行します" + strings["commandRaviResError"] = "復活支援は実行されませんでした" + strings["commandRaviSedSuccess"] = "鎮静支援を実行します" + strings["commandRaviRequest"] = "鎮静支援を要請します" + strings["commandRaviError"] = "ラヴィコマンドが認識されません" + strings["commandRaviNoPlayers"] = "誰も大討伐に参加していません" + strings["ravienteBerserk"] = "<大討伐:猛狂期>が開催されました!" strings["ravienteExtreme"] = "<大討伐:猛狂期【極】>が開催されました!" strings["ravienteExtremeLimited"] = "<大討伐:猛狂期【極】(制限付)>が開催されました!" @@ -28,6 +54,32 @@ func getLangStrings(s *Server) map[string]string { default: strings["language"] = "English" strings["cafeReset"] = "Resets on %d/%d" + + strings["commandDisabled"] = "%s command is disabled" + strings["commandReload"] = "Reloading players..." + strings["commandKqfGet"] = "KQF: %x" + strings["commandKqfSetError"] = "Error in command. Format: %s set xxxxxxxxxxxxxxxx" + strings["commandKqfSetSuccess"] = "KQF set, please switch Land/World" + strings["commandRightsError"] = "Error in command. Format: %s x" + strings["commandRightsSuccess"] = "Set rights integer: %d" + strings["commandCourseError"] = "Error in command. Format: %s " + strings["commandCourseDisabled"] = "%s Course disabled" + strings["commandCourseEnabled"] = "%s Course enabled" + strings["commandCourseLocked"] = "%s Course is locked" + strings["commandTeleportError"] = "Error in command. Format: %s x y" + strings["commandTeleportSuccess"] = "Teleporting to %d %d" + + strings["commandRaviNoCommand"] = "No Raviente command specified!" + strings["commandRaviStartSuccess"] = "The Great Slaying will begin in a moment" + strings["commandRaviStartError"] = "The Great Slaying has already begun!" + strings["commandRaviMultiplier"] = "Raviente multiplier is currently %dx" + strings["commandRaviResSuccess"] = "Sending resurrection support!" + strings["commandRaviResError"] = "Resurrection support has not been requested!" + strings["commandRaviSedSuccess"] = "Sending sedation support if requested!" + strings["commandRaviRequest"] = "Requesting sedation support!" + strings["commandRaviError"] = "Raviente command not recognised!" + strings["commandRaviNoPlayers"] = "No one has joined the Great Slaying!" + strings["ravienteBerserk"] = " is being held!" strings["ravienteExtreme"] = " is being held!" strings["ravienteExtremeLimited"] = " is being held!" From 955ed73dbb3b3ec907e226243fe01e357903d947 Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 8 Feb 2023 00:03:23 +1100 Subject: [PATCH 19/27] test using alternative tracking raviente semaphore --- server/channelserver/handlers_register.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_register.go b/server/channelserver/handlers_register.go index 49afc594f..301c192b0 100644 --- a/server/channelserver/handlers_register.go +++ b/server/channelserver/handlers_register.go @@ -262,7 +262,7 @@ func (s *Session) notifyRavi() { func getRaviSemaphore(s *Server) *Semaphore { for _, semaphore := range s.semaphore { - if strings.HasPrefix(semaphore.id_semaphore, "hs_l0u3B5") && strings.HasSuffix(semaphore.id_semaphore, "4") { + if strings.HasPrefix(semaphore.id_semaphore, "hs_l0u3B5") && strings.HasSuffix(semaphore.id_semaphore, "3") { return semaphore } } From 939c4e24969ba699ec333167fc4bc9d7afbe00c8 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 11 Feb 2023 20:36:55 +1100 Subject: [PATCH 20/27] fix nil savedata on logout --- server/channelserver/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 3dd1fa76c..dbd056a3a 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -253,7 +253,7 @@ func logoutPlayer(s *Session) { removeSessionFromStage(s) saveData, err := GetCharacterSaveData(s, s.charID) - if err != nil { + if err != nil || saveData == nil { s.logger.Error("Failed to get savedata") return } From 91d95400219f28122009dd10c87dd91645d71320 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 00:55:37 +1100 Subject: [PATCH 21/27] add event rp donation tracking --- patch-schema/guild-event-rp.sql | 5 +++++ server/channelserver/handlers_guild.go | 12 ++++++++---- server/channelserver/handlers_guild_member.go | 4 ++++ 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 patch-schema/guild-event-rp.sql diff --git a/patch-schema/guild-event-rp.sql b/patch-schema/guild-event-rp.sql new file mode 100644 index 000000000..4801fd8f7 --- /dev/null +++ b/patch-schema/guild-event-rp.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE IF EXISTS public.guild_characters ADD donated_rp INT DEFAULT 0; + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index de54263ff..f4e5b1991 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -736,7 +736,10 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { // TODO: This doesn't implement blocking, if someone unlocked the same outfit at the same time s.server.db.Exec(`UPDATE guilds SET pugi_outfits=pugi_outfits+$1 WHERE id=$2`, int(math.Pow(float64(pkt.Data1.ReadUint32()), 2)), guild.ID) case mhfpacket.OPERATE_GUILD_DONATE_EVENT: - bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, true)) + quantity := uint16(pkt.Data1.ReadUint32()) + bf.WriteBytes(handleDonateRP(s, quantity, guild, true)) + // TODO: Move this value onto rp_yesterday and reset to 0... daily? + s.server.db.Exec(`UPDATE guild_characters SET rp_today=rp_today+$1 WHERE character_id=$2`, quantity, s.charID) case mhfpacket.OPERATE_GUILD_EVENT_EXCHANGE: rp := uint16(pkt.Data1.ReadUint32()) var balance uint32 @@ -782,7 +785,7 @@ func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byt bf := byteframe.NewByteFrame() bf.WriteUint32(0) saveData, err := GetCharacterSaveData(s, s.charID) - if err != nil { + if err != nil || saveData == nil { return bf.Data() } saveData.RP -= amount @@ -1443,8 +1446,9 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(0) } - for range guildMembers { - bf.WriteUint32(0x00) // Unk + for _, member := range guildMembers { + bf.WriteUint16(member.RPToday) + bf.WriteUint16(member.RPYesterday) } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) diff --git a/server/channelserver/handlers_guild_member.go b/server/channelserver/handlers_guild_member.go index 2c3f0cd1a..3f19d4b2e 100644 --- a/server/channelserver/handlers_guild_member.go +++ b/server/channelserver/handlers_guild_member.go @@ -13,6 +13,8 @@ type GuildMember struct { CharID uint32 `db:"character_id"` JoinedAt *time.Time `db:"joined_at"` Souls uint32 `db:"souls"` + RPToday uint16 `db:"rp_today"` + RPYesterday uint16 `db:"rp_yesterday"` Name string `db:"name"` IsApplicant bool `db:"is_applicant"` OrderIndex uint8 `db:"order_index"` @@ -63,6 +65,8 @@ SELECT g.id as guild_id, joined_at, coalesce(souls, 0) as souls, + rp_today, + rp_yesterday, c.name, character.character_id, coalesce(gc.order_index, 0) as order_index, From 2287e5a6b1332ac8acc3671b89009694867c6e6a Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 01:27:49 +1100 Subject: [PATCH 22/27] implement additional currency distribution handling --- server/channelserver/handlers_distitem.go | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 91c980cff..0da9347fa 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -94,6 +94,35 @@ func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { return } + if len(dist.Data) >= 2 { + distData := byteframe.NewByteFrameFromBytes(dist.Data) + distItems := int(distData.ReadUint16()) + for i := 0; i < distItems; i++ { + if len(dist.Data) >= 2+(i*13) { + itemType := distData.ReadUint8() + _ = distData.ReadBytes(6) + quantity := int(distData.ReadUint16()) + _ = distData.ReadBytes(4) + switch itemType { + case 17: + _ = addPointNetcafe(s, quantity) + case 19: + s.server.db.Exec("UPDATE users u SET gacha_premium=gacha_premium+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) + case 20: + s.server.db.Exec("UPDATE users u SET gacha_trial=gacha_trial+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) + case 21: + s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) + case 23: + saveData, err := GetCharacterSaveData(s, s.charID) + if err == nil { + saveData.RP += uint16(quantity) + saveData.Save(s) + } + } + } + } + } + bf := byteframe.NewByteFrame() bf.WriteUint32(pkt.DistributionID) bf.WriteBytes(dist.Data) From e9d57b477f1622b9981a6d09eb89171b7cd9c526 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 01:31:11 +1100 Subject: [PATCH 23/27] fix incorrect patch schema --- patch-schema/guild-event-rp.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patch-schema/guild-event-rp.sql b/patch-schema/guild-event-rp.sql index 4801fd8f7..1dca6aae1 100644 --- a/patch-schema/guild-event-rp.sql +++ b/patch-schema/guild-event-rp.sql @@ -1,5 +1,7 @@ BEGIN; -ALTER TABLE IF EXISTS public.guild_characters ADD donated_rp INT DEFAULT 0; +ALTER TABLE IF EXISTS public.guild_characters ADD rp_today INT DEFAULT 0; + +ALTER TABLE IF EXISTS public.guild_characters ADD rp_yesterday INT DEFAULT 0; END; \ No newline at end of file From 174f58c0148bd13d51608a160f714fd885fed636 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 01:35:48 +1100 Subject: [PATCH 24/27] fix nil savedata error proper --- server/channelserver/handlers.go | 2 +- server/channelserver/handlers_character.go | 2 ++ server/channelserver/handlers_guild.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index dbd056a3a..3dd1fa76c 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -253,7 +253,7 @@ func logoutPlayer(s *Session) { removeSessionFromStage(s) saveData, err := GetCharacterSaveData(s, s.charID) - if err != nil || saveData == nil { + if err != nil { s.logger.Error("Failed to get savedata") return } diff --git a/server/channelserver/handlers_character.go b/server/channelserver/handlers_character.go index 8499f9b17..7de800e04 100644 --- a/server/channelserver/handlers_character.go +++ b/server/channelserver/handlers_character.go @@ -2,6 +2,7 @@ package channelserver import ( "encoding/binary" + "errors" "erupe-ce/common/bfutil" "erupe-ce/common/stringsupport" @@ -58,6 +59,7 @@ func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) } defer result.Close() if !result.Next() { + err = errors.New("no savedata found") s.logger.Error("No savedata found", zap.Uint32("charID", charID)) return nil, err } diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index f4e5b1991..feb56857f 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -785,7 +785,7 @@ func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byt bf := byteframe.NewByteFrame() bf.WriteUint32(0) saveData, err := GetCharacterSaveData(s, s.charID) - if err != nil || saveData == nil { + if err != nil { return bf.Data() } saveData.RP -= amount From c718e9a5a7b142e7038a68df617c623e31d51244 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 14:04:16 +1100 Subject: [PATCH 25/27] fix various packet responses --- server/channelserver/handlers_data.go | 8 +------- server/channelserver/handlers_mercenary.go | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index 207fc6547..36dd2e596 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -294,13 +294,7 @@ func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) { if err != nil { s.logger.Error("Failed to update scenario data in db", zap.Error(err)) } - // Do this ack manually because it uses a non-(0|1) error code - s.QueueSendMHF(&mhfpacket.MsgSysAck{ - AckHandle: pkt.AckHandle, - IsBufferResponse: false, - ErrorCode: 0x40, - AckData: []byte{0x00, 0x00, 0x00, 0x40}, - }) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) { diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index b20b55ff4..c52802c73 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -38,8 +38,21 @@ func handleMsgMhfSavePartner(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfLoadLegendDispatch(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfLoadLegendDispatch) - data := []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x02, 0xde, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x04, 0x30, 0x40} - doAckBufSucceed(s, pkt.AckHandle, data) + bf := byteframe.NewByteFrame() + legendDispatch := []struct { + Unk uint32 + Timestamp uint32 + }{ + {0, uint32(Time_Current_Midnight().Add(-12 * time.Hour).Unix())}, + {0, uint32(Time_Current_Midnight().Add(12 * time.Hour).Unix())}, + {0, uint32(Time_Current_Midnight().Add(36 * time.Hour).Unix())}, + } + bf.WriteUint8(uint8(len(legendDispatch))) + for _, dispatch := range legendDispatch { + bf.WriteUint32(dispatch.Unk) + bf.WriteUint32(dispatch.Timestamp) + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfLoadHunterNavi(s *Session, p mhfpacket.MHFPacket) { From 091a8cd3da145197546db37f8b38b1ba101eb32e Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 12 Feb 2023 17:00:37 +1100 Subject: [PATCH 26/27] move caravan event handlers --- network/mhfpacket/msg_mhf_post_tiny_bin.go | 17 +++++++++----- server/channelserver/handlers.go | 23 ------------------ server/channelserver/handlers_caravan.go | 27 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/network/mhfpacket/msg_mhf_post_tiny_bin.go b/network/mhfpacket/msg_mhf_post_tiny_bin.go index a43ed7b85..4c06a51e0 100644 --- a/network/mhfpacket/msg_mhf_post_tiny_bin.go +++ b/network/mhfpacket/msg_mhf_post_tiny_bin.go @@ -1,15 +1,18 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPostTinyBin represents the MSG_MHF_POST_TINY_BIN -type MsgMhfPostTinyBin struct{} +type MsgMhfPostTinyBin struct { + AckHandle uint32 + Unk []byte +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfPostTinyBin) Opcode() network.PacketID { @@ -18,7 +21,9 @@ func (m *MsgMhfPostTinyBin) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk = bf.ReadBytes(14) + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 3dd1fa76c..10baadd1e 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1706,14 +1706,6 @@ func handleMsgMhfPostNotice(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetRandFromTable(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfGetTinyBin(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfGetTinyBin) - // requested after conquest quests - doAckBufSucceed(s, pkt.AckHandle, []byte{}) -} - -func handleMsgMhfPostTinyBin(s *Session, p mhfpacket.MHFPacket) {} - func handleMsgMhfGetSenyuDailyCount(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { @@ -1723,21 +1715,6 @@ func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfGetRyoudama) - // likely guild related - // REQ: 00 04 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 01 FE 4E - // REQ: 00 06 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 - // REQ: 00 05 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 0E 2A 15 9E CC 00 00 00 01 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 1E 55 B0 2F 00 00 00 01 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 2A 15 9E CC 00 00 00 02 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 03 D5 30 56 00 00 00 02 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 3F 57 76 9F 00 00 00 03 93 56 92 6E 96 B3 97 70 00 00 00 00 00 00 38 D9 0E C4 00 00 00 03 87 64 83 78 83 42 00 00 00 00 00 00 00 00 23 F3 B9 77 00 00 00 04 82 B3 82 CC 82 DC 82 E9 81 99 00 00 00 00 3F 1B 17 9C 00 00 00 04 82 B1 82 A4 82 BD 00 00 00 00 00 00 00 00 00 B9 F9 C0 00 00 00 05 82 CD 82 E9 82 A9 00 00 00 00 00 00 00 00 23 9F 9A EA 00 00 00 05 83 70 83 62 83 4C 83 83 83 49 00 00 00 00 38 D9 0E C4 00 00 00 06 87 64 83 78 83 42 00 00 00 00 00 00 00 00 1E 55 B0 2F 00 00 00 06 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 03 D5 30 56 00 00 00 07 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 02 D3 B8 77 00 00 00 07 6F 77 6C 32 35 32 35 00 00 00 00 00 00 00 - data, _ := hex.DecodeString("0A218EAD0000000000000000000000010000000000000000") - doAckBufSucceed(s, pkt.AckHandle, data) -} - -func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {} - func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) { // if the game gets bad responses for this it breaks the ability to save pkt := p.(*mhfpacket.MsgMhfGetTenrouirai) diff --git a/server/channelserver/handlers_caravan.go b/server/channelserver/handlers_caravan.go index f000d1623..86cf73249 100644 --- a/server/channelserver/handlers_caravan.go +++ b/server/channelserver/handlers_caravan.go @@ -1,9 +1,36 @@ package channelserver import ( + "encoding/hex" "erupe-ce/network/mhfpacket" ) +func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetRyoudama) + // likely guild related + // REQ: 00 04 13 53 8F 18 00 + // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 01 FE 4E + // REQ: 00 06 13 53 8F 18 00 + // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 + // REQ: 00 05 13 53 8F 18 00 + // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 0E 2A 15 9E CC 00 00 00 01 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 1E 55 B0 2F 00 00 00 01 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 2A 15 9E CC 00 00 00 02 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 03 D5 30 56 00 00 00 02 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 3F 57 76 9F 00 00 00 03 93 56 92 6E 96 B3 97 70 00 00 00 00 00 00 38 D9 0E C4 00 00 00 03 87 64 83 78 83 42 00 00 00 00 00 00 00 00 23 F3 B9 77 00 00 00 04 82 B3 82 CC 82 DC 82 E9 81 99 00 00 00 00 3F 1B 17 9C 00 00 00 04 82 B1 82 A4 82 BD 00 00 00 00 00 00 00 00 00 B9 F9 C0 00 00 00 05 82 CD 82 E9 82 A9 00 00 00 00 00 00 00 00 23 9F 9A EA 00 00 00 05 83 70 83 62 83 4C 83 83 83 49 00 00 00 00 38 D9 0E C4 00 00 00 06 87 64 83 78 83 42 00 00 00 00 00 00 00 00 1E 55 B0 2F 00 00 00 06 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 03 D5 30 56 00 00 00 07 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 02 D3 B8 77 00 00 00 07 6F 77 6C 32 35 32 35 00 00 00 00 00 00 00 + data, _ := hex.DecodeString("0A218EAD0000000000000000000000010000000000000000") + doAckBufSucceed(s, pkt.AckHandle, data) +} + +func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {} + +func handleMsgMhfGetTinyBin(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetTinyBin) + // requested after conquest quests + doAckBufSucceed(s, pkt.AckHandle, []byte{}) +} + +func handleMsgMhfPostTinyBin(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPostTinyBin) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} + func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) {} From e98259a11a8c0e8d661c1aa316085fac4fdc735a Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 13 Feb 2023 00:21:07 +1100 Subject: [PATCH 27/27] move various packet handlers --- ...g_mhf_get_weekly_seibatu_ranking_reward.go | 23 ++++++++---- network/mhfpacket/msg_mhf_present_box.go | 33 +++++++++++++---- server/channelserver/handlers.go | 26 -------------- server/channelserver/handlers_reward.go | 4 --- server/channelserver/handlers_tower.go | 36 +++++++++++++++++++ 5 files changed, 80 insertions(+), 42 deletions(-) diff --git a/network/mhfpacket/msg_mhf_get_weekly_seibatu_ranking_reward.go b/network/mhfpacket/msg_mhf_get_weekly_seibatu_ranking_reward.go index 3b8b07c01..2823ff525 100644 --- a/network/mhfpacket/msg_mhf_get_weekly_seibatu_ranking_reward.go +++ b/network/mhfpacket/msg_mhf_get_weekly_seibatu_ranking_reward.go @@ -1,15 +1,21 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetWeeklySeibatuRankingReward represents the MSG_MHF_GET_WEEKLY_SEIBATU_RANKING_REWARD -type MsgMhfGetWeeklySeibatuRankingReward struct{} +type MsgMhfGetWeeklySeibatuRankingReward struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 uint32 + Unk3 uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfGetWeeklySeibatuRankingReward) Opcode() network.PacketID { @@ -18,7 +24,12 @@ func (m *MsgMhfGetWeeklySeibatuRankingReward) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetWeeklySeibatuRankingReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadUint32() + m.Unk3 = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_present_box.go b/network/mhfpacket/msg_mhf_present_box.go index 77bdd0db2..c3da92e31 100644 --- a/network/mhfpacket/msg_mhf_present_box.go +++ b/network/mhfpacket/msg_mhf_present_box.go @@ -1,15 +1,26 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPresentBox represents the MSG_MHF_PRESENT_BOX -type MsgMhfPresentBox struct{} +type MsgMhfPresentBox struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 uint32 + Unk3 uint32 + Unk4 uint32 + Unk5 uint32 + Unk6 uint32 + Unk7 uint32 + Unk8 uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfPresentBox) Opcode() network.PacketID { @@ -18,7 +29,17 @@ func (m *MsgMhfPresentBox) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPresentBox) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadUint32() + m.Unk3 = bf.ReadUint32() + m.Unk4 = bf.ReadUint32() + m.Unk5 = bf.ReadUint32() + m.Unk6 = bf.ReadUint32() + m.Unk7 = bf.ReadUint32() + m.Unk8 = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 10baadd1e..9d5fd3a61 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -528,8 +528,6 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { func handleMsgCaExchangeItem(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) {} - func handleMsgMhfServerCommand(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfAnnounce(s *Session, p mhfpacket.MHFPacket) { @@ -1715,30 +1713,6 @@ func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) { - // if the game gets bad responses for this it breaks the ability to save - pkt := p.(*mhfpacket.MsgMhfGetTenrouirai) - var data []byte - var err error - if pkt.Unk0 == 1 { - data, err = hex.DecodeString("0A218EAD000000000000000000000001010000000000060010") - } else if pkt.Unk2 == 4 { - data, err = hex.DecodeString("0A218EAD0000000000000000000000210101005000000202010102020104001000000202010102020106003200000202010002020104000C003202020101020201030032000002020101020202059C4000000202010002020105C35000320202010102020201003C00000202010102020203003200000201010001020203002800320201010101020204000C00000201010101020206002800000201010001020101003C00320201020101020105C35000000301020101020106003200000301020001020104001000320301020101020105C350000003010201010202030028000003010200010201030032003203010201010202059C4000000301020101010206002800000301020001010201003C00320301020101010206003200000301020101010204000C000003010200010101010050003203010201010101059C40000003010201010101030032000003010200010101040010003203010001010101060032000003010001010102030028000003010001010101010050003203010000010102059C4000000301000001010206002800000301000001010010") - } else { - data = []byte{0x00, 0x00, 0x00, 0x00} - s.logger.Info("GET_TENROUIRAI request for unknown type") - } - if err != nil { - panic(err) - } - doAckBufSucceed(s, pkt.AckHandle, data) -} - -func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfPostTenrouirai) - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) -} - func handleMsgMhfGetDailyMissionMaster(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetDailyMissionPersonal(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_reward.go b/server/channelserver/handlers_reward.go index b4a1abc6d..73234c2ae 100644 --- a/server/channelserver/handlers_reward.go +++ b/server/channelserver/handlers_reward.go @@ -43,7 +43,3 @@ func handleMsgMhfAcquireMonthlyReward(s *Session, p mhfpacket.MHFPacket) { } func handleMsgMhfAcceptReadReward(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index 0bafffaa2..0a2675812 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -58,6 +58,42 @@ func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } +func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) { + // if the game gets bad responses for this it breaks the ability to save + pkt := p.(*mhfpacket.MsgMhfGetTenrouirai) + var data []byte + var err error + if pkt.Unk0 == 1 { + data, err = hex.DecodeString("0A218EAD000000000000000000000001010000000000060010") + } else if pkt.Unk2 == 4 { + data, err = hex.DecodeString("0A218EAD0000000000000000000000210101005000000202010102020104001000000202010102020106003200000202010002020104000C003202020101020201030032000002020101020202059C4000000202010002020105C35000320202010102020201003C00000202010102020203003200000201010001020203002800320201010101020204000C00000201010101020206002800000201010001020101003C00320201020101020105C35000000301020101020106003200000301020001020104001000320301020101020105C350000003010201010202030028000003010200010201030032003203010201010202059C4000000301020101010206002800000301020001010201003C00320301020101010206003200000301020101010204000C000003010200010101010050003203010201010101059C40000003010201010101030032000003010200010101040010003203010001010101060032000003010001010102030028000003010001010101010050003203010000010102059C4000000301000001010206002800000301000001010010") + } else { + data = []byte{0x00, 0x00, 0x00, 0x00} + s.logger.Info("GET_TENROUIRAI request for unknown type") + } + if err != nil { + panic(err) + } + doAckBufSucceed(s, pkt.AckHandle, data) +} + +func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPostTenrouirai) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) +} + +func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {} + +func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} + +func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPresentBox) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} + func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetGemInfo) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))