From 86cb254d1a5fe5205909783bef7f6157a94b07a5 Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 15 Aug 2022 15:12:50 +1000 Subject: [PATCH] initial warehouse concept --- .../mhfpacket/msg_mhf_enumerate_warehouse.go | 20 ++-- .../mhfpacket/msg_mhf_operate_warehouse.go | 32 ++++-- network/mhfpacket/msg_mhf_update_warehouse.go | 37 +++++-- patch-schema/warehouse.sql | 49 ++++++++++ server/channelserver/handlers_house.go | 98 ++++++++++++++++++- 5 files changed, 215 insertions(+), 21 deletions(-) create mode 100644 patch-schema/warehouse.sql diff --git a/network/mhfpacket/msg_mhf_enumerate_warehouse.go b/network/mhfpacket/msg_mhf_enumerate_warehouse.go index f567e8bcb..7a5e76a7b 100644 --- a/network/mhfpacket/msg_mhf_enumerate_warehouse.go +++ b/network/mhfpacket/msg_mhf_enumerate_warehouse.go @@ -1,15 +1,19 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfEnumerateWarehouse represents the MSG_MHF_ENUMERATE_WAREHOUSE -type MsgMhfEnumerateWarehouse struct{} +type MsgMhfEnumerateWarehouse struct { + AckHandle uint32 + BoxType uint8 + BoxIndex uint8 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfEnumerateWarehouse) Opcode() network.PacketID { @@ -18,7 +22,11 @@ func (m *MsgMhfEnumerateWarehouse) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.BoxType = bf.ReadUint8() + m.BoxIndex = bf.ReadUint8() + _ = bf.ReadUint16() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_operate_warehouse.go b/network/mhfpacket/msg_mhf_operate_warehouse.go index 9df4e3770..ba0ee7b78 100644 --- a/network/mhfpacket/msg_mhf_operate_warehouse.go +++ b/network/mhfpacket/msg_mhf_operate_warehouse.go @@ -1,15 +1,22 @@ package mhfpacket -import ( - "errors" +import ( + "errors" + "erupe-ce/common/stringsupport" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfOperateWarehouse represents the MSG_MHF_OPERATE_WAREHOUSE -type MsgMhfOperateWarehouse struct{} +type MsgMhfOperateWarehouse struct { + AckHandle uint32 + Operation uint8 + BoxType string + BoxIndex uint8 + Name string +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfOperateWarehouse) Opcode() network.PacketID { @@ -18,7 +25,20 @@ func (m *MsgMhfOperateWarehouse) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfOperateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Operation = bf.ReadUint8() + boxType := bf.ReadUint8() + switch boxType { + case 0: + m.BoxType = "item" + case 1: + m.BoxType = "equip" + } + m.BoxIndex = bf.ReadUint8() + _ = bf.ReadUint8() // lenName + _ = bf.ReadUint16() // Unk + m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_update_warehouse.go b/network/mhfpacket/msg_mhf_update_warehouse.go index ba0321910..884ed4119 100644 --- a/network/mhfpacket/msg_mhf_update_warehouse.go +++ b/network/mhfpacket/msg_mhf_update_warehouse.go @@ -1,15 +1,27 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) +type UpdatedStack struct { + ID uint32 + Index uint16 + ItemID uint16 + Quantity uint16 + Unk uint16 +} + // MsgMhfUpdateWarehouse represents the MSG_MHF_UPDATE_WAREHOUSE -type MsgMhfUpdateWarehouse struct{} +type MsgMhfUpdateWarehouse struct { + AckHandle uint32 + BoxID uint16 + Items []UpdatedStack +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfUpdateWarehouse) Opcode() network.PacketID { @@ -18,7 +30,20 @@ func (m *MsgMhfUpdateWarehouse) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.BoxID = bf.ReadUint16() + changes := int(bf.ReadUint16()) + var stackUpdate UpdatedStack + for i := 0; i < changes; i++ { + stackUpdate.ID = bf.ReadUint32() + stackUpdate.Index = bf.ReadUint16() + stackUpdate.ItemID = bf.ReadUint16() + stackUpdate.Quantity = bf.ReadUint16() + stackUpdate.Unk = bf.ReadUint16() + m.Items = append(m.Items, stackUpdate) + } + _ = bf.ReadUint16() + return nil } // Build builds a binary packet from the current data. diff --git a/patch-schema/warehouse.sql b/patch-schema/warehouse.sql new file mode 100644 index 000000000..2f2a5adde --- /dev/null +++ b/patch-schema/warehouse.sql @@ -0,0 +1,49 @@ +BEGIN; + +CREATE TABLE IF NOT EXISTS public.warehouse ( + character_id integer PRIMARY KEY, + item0 bytea, + item1 bytea, + item2 bytea, + item3 bytea, + item4 bytea, + item5 bytea, + item6 bytea, + item7 bytea, + item8 bytea, + item9 bytea, + item10 bytea, + item0name text, + item1name text, + item2name text, + item3name text, + item4name text, + item5name text, + item6name text, + item7name text, + item8name text, + item9name text, + equip0 bytea, + equip1 bytea, + equip2 bytea, + equip3 bytea, + equip4 bytea, + equip5 bytea, + equip6 bytea, + equip7 bytea, + equip8 bytea, + equip9 bytea, + equip10 bytea, + equip0name text, + equip1name text, + equip2name text, + equip3name text, + equip4name text, + equip5name text, + equip6name text, + equip7name text, + equip8name text, + equip9name text +); + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 401347b76..b7bdd78bf 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -5,11 +5,37 @@ import ( ps "erupe-ce/common/pascalstring" "erupe-ce/common/stringsupport" "erupe-ce/network/mhfpacket" + "fmt" "go.uber.org/zap" "io" "time" ) +const warehouseNamesQuery = ` +SELECT +COALESCE(item0name, ''), +COALESCE(item1name, ''), +COALESCE(item2name, ''), +COALESCE(item3name, ''), +COALESCE(item4name, ''), +COALESCE(item5name, ''), +COALESCE(item6name, ''), +COALESCE(item7name, ''), +COALESCE(item8name, ''), +COALESCE(item9name, ''), +COALESCE(equip0name, ''), +COALESCE(equip1name, ''), +COALESCE(equip2name, ''), +COALESCE(equip3name, ''), +COALESCE(equip4name, ''), +COALESCE(equip5name, ''), +COALESCE(equip6name, ''), +COALESCE(equip7name, ''), +COALESCE(equip8name, ''), +COALESCE(equip9name, '') +FROM warehouse +` + func handleMsgMhfUpdateInterior(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateInterior) _, err := s.server.db.Exec("UPDATE characters SET house=$1 WHERE id=$2", pkt.InteriorData, s.charID) @@ -341,8 +367,74 @@ func handleMsgMhfAcquireTitle(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfResetTitle(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfOperateWarehouse) + bf := byteframe.NewByteFrame() + bf.WriteUint8(pkt.Operation) + switch pkt.Operation { + case 0: + var count uint8 + itemNames := make([]string, 10) + equipNames := make([]string, 10) + s.server.db.QueryRow(fmt.Sprintf("%s WHERE character_id=$1", warehouseNamesQuery), s.charID).Scan(&itemNames[0], + &itemNames[1], &itemNames[2], &itemNames[3], &itemNames[4], &itemNames[5], &itemNames[6], &itemNames[7], &itemNames[8], &itemNames[9], &equipNames[0], + &equipNames[1], &equipNames[2], &equipNames[3], &equipNames[4], &equipNames[5], &equipNames[6], &equipNames[7], &equipNames[8], &equipNames[9]) + bf.WriteUint32(0) + bf.WriteUint16(1000) // Usages + temp := byteframe.NewByteFrame() + for i, name := range itemNames { + if len(name) > 0 { + count++ + temp.WriteUint8(0) + temp.WriteUint8(uint8(i)) + ps.Uint8(temp, name, true) + } + } + for i, name := range equipNames { + if len(name) > 0 { + count++ + temp.WriteUint8(1) + temp.WriteUint8(uint8(i)) + ps.Uint8(temp, name, true) + } + } + bf.WriteUint8(count) + bf.WriteBytes(temp.Data()) + case 1: + bf.WriteUint8(0) + case 2: + s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET %s%dname=$1 WHERE character_id=$2", pkt.BoxType, pkt.BoxIndex), pkt.Name, s.charID) + case 3: + var t int + err := s.server.db.QueryRow("SELECT character_id FROM warehouse WHERE character_id=$1", s.charID).Scan(&t) + if err != nil { + s.server.db.Exec("INSERT INTO warehouse (character_id) VALUES ($1)", s.charID) + } + bf.WriteUint32(0) + bf.WriteUint16(1000) // Usages + case 4: + bf.WriteUint32(0) + bf.WriteUint16(1000) // Usages + bf.WriteUint8(0) + } + // Opcodes + // 0 = Get box names + // 1 = Commit usage + // 2 = Rename + // 3 = Get usage limit + // 4 = Get gift box names (doesn't do anything?) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} -func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfEnumerateWarehouse) + bf := byteframe.NewByteFrame() + bf.WriteUint16(0) // numStacks + bf.WriteUint16(0) // Unk + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} -func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfUpdateWarehouse) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +}