From bd42b5d0c24adfd454e0c80b95752768ca61b25b Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 29 Jan 2023 01:27:46 +1100 Subject: [PATCH 1/4] 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 2/4] 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 3/4] 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 4/4] 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)) }