From 86cb254d1a5fe5205909783bef7f6157a94b07a5 Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 15 Aug 2022 15:12:50 +1000 Subject: [PATCH 1/4] 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)) +} From b7d41c1c7f0e829095095861148aa48134c476e0 Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 15 Aug 2022 20:09:19 +1000 Subject: [PATCH 2/4] warehouse item updates --- .../mhfpacket/msg_mhf_enumerate_warehouse.go | 10 ++- network/mhfpacket/msg_mhf_update_warehouse.go | 24 ++++--- server/channelserver/handlers_house.go | 72 +++++++++++++++++-- 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/network/mhfpacket/msg_mhf_enumerate_warehouse.go b/network/mhfpacket/msg_mhf_enumerate_warehouse.go index 7a5e76a7b..3f1358045 100644 --- a/network/mhfpacket/msg_mhf_enumerate_warehouse.go +++ b/network/mhfpacket/msg_mhf_enumerate_warehouse.go @@ -11,7 +11,7 @@ import ( // MsgMhfEnumerateWarehouse represents the MSG_MHF_ENUMERATE_WAREHOUSE type MsgMhfEnumerateWarehouse struct { AckHandle uint32 - BoxType uint8 + BoxType string BoxIndex uint8 } @@ -23,7 +23,13 @@ func (m *MsgMhfEnumerateWarehouse) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.BoxType = bf.ReadUint8() + boxType := bf.ReadUint8() + switch boxType { + case 0: + m.BoxType = "item" + case 1: + m.BoxType = "equip" + } m.BoxIndex = bf.ReadUint8() _ = bf.ReadUint16() return nil diff --git a/network/mhfpacket/msg_mhf_update_warehouse.go b/network/mhfpacket/msg_mhf_update_warehouse.go index 884ed4119..b6777b8d6 100644 --- a/network/mhfpacket/msg_mhf_update_warehouse.go +++ b/network/mhfpacket/msg_mhf_update_warehouse.go @@ -2,25 +2,24 @@ package mhfpacket import ( "errors" - "erupe-ce/common/byteframe" "erupe-ce/network" "erupe-ce/network/clientctx" ) -type UpdatedStack struct { +type WarehouseStack struct { ID uint32 Index uint16 ItemID uint16 Quantity uint16 - Unk uint16 } // MsgMhfUpdateWarehouse represents the MSG_MHF_UPDATE_WAREHOUSE type MsgMhfUpdateWarehouse struct { AckHandle uint32 - BoxID uint16 - Items []UpdatedStack + BoxType string + BoxIndex uint8 + Updates []WarehouseStack } // Opcode returns the ID associated with this packet type. @@ -31,16 +30,23 @@ func (m *MsgMhfUpdateWarehouse) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.BoxID = bf.ReadUint16() + boxType := bf.ReadUint8() + switch boxType { + case 0: + m.BoxType = "item" + case 1: + m.BoxType = "equip" + } + m.BoxIndex = bf.ReadUint8() changes := int(bf.ReadUint16()) - var stackUpdate UpdatedStack + var stackUpdate WarehouseStack 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() // Unk + m.Updates = append(m.Updates, stackUpdate) } _ = bf.ReadUint16() return nil diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index b7bdd78bf..1059b7a72 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -426,15 +426,79 @@ func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } +func getWarehouseBox(s *Session, boxType string, boxIndex uint8) []mhfpacket.WarehouseStack { + var data []byte + s.server.db.QueryRow(fmt.Sprintf("SELECT %s%d FROM warehouse WHERE character_id=$1", boxType, boxIndex), s.charID).Scan(&data) + if len(data) > 0 { + box := byteframe.NewByteFrameFromBytes(data) + numStacks := box.ReadUint16() + stacks := make([]mhfpacket.WarehouseStack, numStacks) + for i := 0; i < int(numStacks); i++ { + stacks[i].ID = box.ReadUint32() + stacks[i].Index = box.ReadUint16() + stacks[i].ItemID = box.ReadUint16() + stacks[i].Quantity = box.ReadUint16() + box.ReadUint16() + } + return stacks + } else { + return make([]mhfpacket.WarehouseStack, 0) + } +} + +func boxToBytes(stacks []mhfpacket.WarehouseStack) []byte { + bf := byteframe.NewByteFrame() + bf.WriteUint16(uint16(len(stacks))) + for _, stack := range stacks { + bf.WriteUint32(stack.ID) + bf.WriteUint16(stack.Index) + bf.WriteUint16(stack.ItemID) + bf.WriteUint16(stack.Quantity) + bf.WriteUint16(0) + } + bf.WriteUint16(0) + return bf.Data() +} + 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()) + box := getWarehouseBox(s, pkt.BoxType, pkt.BoxIndex) + if len(box) > 0 { + doAckBufSucceed(s, pkt.AckHandle, boxToBytes(box)) + } else { + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) + } } func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateWarehouse) + box := getWarehouseBox(s, pkt.BoxType, pkt.BoxIndex) + // Update existing stacks + var newStacks []mhfpacket.WarehouseStack + for _, update := range pkt.Updates { + exists := false + for i, stack := range box { + if stack.ItemID == update.ItemID { + box[i].Quantity = update.Quantity + exists = true + break + } + } + if exists == false { + newStacks = append(newStacks, update) + } + } + // Append new stacks + for _, stack := range newStacks { + box = append(box, stack) + } + // Slice empty stacks + var cleanedBox []mhfpacket.WarehouseStack + for _, stack := range box { + if stack.Quantity > 0 { + cleanedBox = append(cleanedBox, stack) + } + } + s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET %s%d=$1 WHERE character_id=$2", pkt.BoxType, pkt.BoxIndex), boxToBytes(cleanedBox), s.charID) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From 81e40b988d38d80b53db3bfe9f38fc5e5e9c4de6 Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 15 Aug 2022 21:53:00 +1000 Subject: [PATCH 3/4] warehouse equipment updates --- network/mhfpacket/msg_mhf_update_warehouse.go | 32 +++++--- server/channelserver/handlers_house.go | 74 +++++++++++++------ 2 files changed, 75 insertions(+), 31 deletions(-) diff --git a/network/mhfpacket/msg_mhf_update_warehouse.go b/network/mhfpacket/msg_mhf_update_warehouse.go index b6777b8d6..962906988 100644 --- a/network/mhfpacket/msg_mhf_update_warehouse.go +++ b/network/mhfpacket/msg_mhf_update_warehouse.go @@ -8,10 +8,12 @@ import ( ) type WarehouseStack struct { - ID uint32 - Index uint16 - ItemID uint16 - Quantity uint16 + ID uint32 + Index uint16 + EquipType uint16 + ItemID uint16 + Quantity uint16 + Data []byte } // MsgMhfUpdateWarehouse represents the MSG_MHF_UPDATE_WAREHOUSE @@ -41,12 +43,22 @@ func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl changes := int(bf.ReadUint16()) var stackUpdate WarehouseStack for i := 0; i < changes; i++ { - stackUpdate.ID = bf.ReadUint32() - stackUpdate.Index = bf.ReadUint16() - stackUpdate.ItemID = bf.ReadUint16() - stackUpdate.Quantity = bf.ReadUint16() - _ = bf.ReadUint16() // Unk - m.Updates = append(m.Updates, stackUpdate) + switch boxType { + case 0: + stackUpdate.ID = bf.ReadUint32() + stackUpdate.Index = bf.ReadUint16() + stackUpdate.ItemID = bf.ReadUint16() + stackUpdate.Quantity = bf.ReadUint16() + _ = bf.ReadUint16() // Unk + m.Updates = append(m.Updates, stackUpdate) + case 1: + stackUpdate.ID = bf.ReadUint32() + stackUpdate.Index = bf.ReadUint16() + stackUpdate.EquipType = bf.ReadUint16() + stackUpdate.ItemID = bf.ReadUint16() + stackUpdate.Data = bf.ReadBytes(56) + m.Updates = append(m.Updates, stackUpdate) + } } _ = bf.ReadUint16() return nil diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 1059b7a72..4e6af6947 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -434,11 +434,19 @@ func getWarehouseBox(s *Session, boxType string, boxIndex uint8) []mhfpacket.War numStacks := box.ReadUint16() stacks := make([]mhfpacket.WarehouseStack, numStacks) for i := 0; i < int(numStacks); i++ { - stacks[i].ID = box.ReadUint32() - stacks[i].Index = box.ReadUint16() - stacks[i].ItemID = box.ReadUint16() - stacks[i].Quantity = box.ReadUint16() - box.ReadUint16() + if boxType == "item" { + stacks[i].ID = box.ReadUint32() + stacks[i].Index = box.ReadUint16() + stacks[i].ItemID = box.ReadUint16() + stacks[i].Quantity = box.ReadUint16() + box.ReadUint16() + } else { + stacks[i].ID = box.ReadUint32() + stacks[i].Index = box.ReadUint16() + stacks[i].EquipType = box.ReadUint16() + stacks[i].ItemID = box.ReadUint16() + stacks[i].Data = box.ReadBytes(56) + } } return stacks } else { @@ -446,15 +454,23 @@ func getWarehouseBox(s *Session, boxType string, boxIndex uint8) []mhfpacket.War } } -func boxToBytes(stacks []mhfpacket.WarehouseStack) []byte { +func boxToBytes(stacks []mhfpacket.WarehouseStack, boxType string) []byte { bf := byteframe.NewByteFrame() bf.WriteUint16(uint16(len(stacks))) - for _, stack := range stacks { - bf.WriteUint32(stack.ID) - bf.WriteUint16(stack.Index) - bf.WriteUint16(stack.ItemID) - bf.WriteUint16(stack.Quantity) - bf.WriteUint16(0) + for i, stack := range stacks { + if boxType == "item" { + bf.WriteUint32(stack.ID) + bf.WriteUint16(uint16(i + 1)) + bf.WriteUint16(stack.ItemID) + bf.WriteUint16(stack.Quantity) + bf.WriteUint16(0) + } else { + bf.WriteUint32(stack.ID) + bf.WriteUint16(uint16(i + 1)) + bf.WriteUint16(stack.EquipType) + bf.WriteUint16(stack.ItemID) + bf.WriteBytes(stack.Data) + } } bf.WriteUint16(0) return bf.Data() @@ -464,7 +480,7 @@ func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateWarehouse) box := getWarehouseBox(s, pkt.BoxType, pkt.BoxIndex) if len(box) > 0 { - doAckBufSucceed(s, pkt.AckHandle, boxToBytes(box)) + doAckBufSucceed(s, pkt.AckHandle, boxToBytes(box, pkt.BoxType)) } else { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) } @@ -477,11 +493,21 @@ func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { var newStacks []mhfpacket.WarehouseStack for _, update := range pkt.Updates { exists := false - for i, stack := range box { - if stack.ItemID == update.ItemID { - box[i].Quantity = update.Quantity - exists = true - break + if pkt.BoxType == "item" { + for i, stack := range box { + if stack.Index == update.Index { + exists = true + box[i].Quantity = update.Quantity + break + } + } + } else { + for i, stack := range box { + if stack.Index == update.Index { + exists = true + box[i].ItemID = update.ItemID + break + } } } if exists == false { @@ -495,10 +521,16 @@ func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { // Slice empty stacks var cleanedBox []mhfpacket.WarehouseStack for _, stack := range box { - if stack.Quantity > 0 { - cleanedBox = append(cleanedBox, stack) + if pkt.BoxType == "item" { + if stack.Quantity > 0 { + cleanedBox = append(cleanedBox, stack) + } + } else { + if stack.ItemID != 0 { + cleanedBox = append(cleanedBox, stack) + } } } - s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET %s%d=$1 WHERE character_id=$2", pkt.BoxType, pkt.BoxIndex), boxToBytes(cleanedBox), s.charID) + s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET %s%d=$1 WHERE character_id=$2", pkt.BoxType, pkt.BoxIndex), boxToBytes(cleanedBox, pkt.BoxType), s.charID) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From bc75902da126b3b3e7172ee2f4daa1bd82fc1990 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 16 Aug 2022 01:39:53 +1000 Subject: [PATCH 4/4] prevent nil warehouse error --- server/channelserver/handlers_house.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 4e6af6947..b4b97e3fa 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -369,6 +369,11 @@ func handleMsgMhfResetTitle(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfOperateWarehouse) + 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 := byteframe.NewByteFrame() bf.WriteUint8(pkt.Operation) switch pkt.Operation { @@ -380,7 +385,7 @@ func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { &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 + bf.WriteUint16(10000) // Usages temp := byteframe.NewByteFrame() for i, name := range itemNames { if len(name) > 0 { @@ -405,16 +410,11 @@ func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { 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 + bf.WriteUint32(0) // Usage renewal time, >1 = disabled + bf.WriteUint16(10000) // Usages case 4: bf.WriteUint32(0) - bf.WriteUint16(1000) // Usages + bf.WriteUint16(10000) // Usages bf.WriteUint8(0) } // Opcodes