From 40d4aba3c47a988c4104dea46a962716aefe38f3 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 25 Feb 2024 14:12:37 +1100 Subject: [PATCH] convert other Warehouse types to new system --- .../mhfpacket/msg_mhf_update_guild_item.go | 26 ++-- .../mhfpacket/msg_mhf_update_union_item.go | 17 +-- network/mhfpacket/msg_mhf_update_warehouse.go | 3 +- schemas/patch-schema/reset-warehouses.sql | 6 + server/channelserver/handlers.go | 111 ++++++---------- server/channelserver/handlers_guild.go | 119 ++++++------------ 6 files changed, 94 insertions(+), 188 deletions(-) create mode 100644 schemas/patch-schema/reset-warehouses.sql diff --git a/network/mhfpacket/msg_mhf_update_guild_item.go b/network/mhfpacket/msg_mhf_update_guild_item.go index ddd7ef6e5..164adfb20 100644 --- a/network/mhfpacket/msg_mhf_update_guild_item.go +++ b/network/mhfpacket/msg_mhf_update_guild_item.go @@ -2,24 +2,18 @@ package mhfpacket import ( "errors" + "erupe-ce/common/mhfitem" "erupe-ce/common/byteframe" "erupe-ce/network" "erupe-ce/network/clientctx" ) -type Item struct { - Unk0 uint32 - ItemID uint16 - Amount uint16 - Unk1 uint32 -} - // MsgMhfUpdateGuildItem represents the MSG_MHF_UPDATE_GUILD_ITEM type MsgMhfUpdateGuildItem struct { - AckHandle uint32 - GuildID uint32 - Items []Item + AckHandle uint32 + GuildID uint32 + UpdatedItems []mhfitem.MHFItemStack } // Opcode returns the ID associated with this packet type. @@ -31,18 +25,12 @@ func (m *MsgMhfUpdateGuildItem) Opcode() network.PacketID { func (m *MsgMhfUpdateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.GuildID = bf.ReadUint32() - itemCount := int(bf.ReadUint16()) + changes := int(bf.ReadUint16()) bf.ReadUint8() // Zeroed bf.ReadUint8() // Zeroed - m.Items = make([]Item, itemCount) - - for i := 0; i < itemCount; i++ { - m.Items[i].Unk0 = bf.ReadUint32() - m.Items[i].ItemID = bf.ReadUint16() - m.Items[i].Amount = bf.ReadUint16() - m.Items[i].Unk1 = bf.ReadUint32() + for i := 0; i < changes; i++ { + m.UpdatedItems = append(m.UpdatedItems, mhfitem.ReadWarehouseItem(bf)) } - return nil } diff --git a/network/mhfpacket/msg_mhf_update_union_item.go b/network/mhfpacket/msg_mhf_update_union_item.go index 68e8de365..f40dedd5f 100644 --- a/network/mhfpacket/msg_mhf_update_union_item.go +++ b/network/mhfpacket/msg_mhf_update_union_item.go @@ -2,6 +2,7 @@ package mhfpacket import ( "errors" + "erupe-ce/common/mhfitem" "erupe-ce/common/byteframe" "erupe-ce/network" @@ -10,8 +11,8 @@ import ( // MsgMhfUpdateUnionItem represents the MSG_MHF_UPDATE_UNION_ITEM type MsgMhfUpdateUnionItem struct { - AckHandle uint32 - Items []Item + AckHandle uint32 + UpdatedItems []mhfitem.MHFItemStack } // Opcode returns the ID associated with this packet type. @@ -22,18 +23,12 @@ func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - itemCount := int(bf.ReadUint16()) + changes := int(bf.ReadUint16()) bf.ReadUint8() // Zeroed bf.ReadUint8() // Zeroed - m.Items = make([]Item, itemCount) - - for i := 0; i < itemCount; i++ { - m.Items[i].Unk0 = bf.ReadUint32() - m.Items[i].ItemID = bf.ReadUint16() - m.Items[i].Amount = bf.ReadUint16() - m.Items[i].Unk1 = bf.ReadUint32() + for i := 0; i < changes; i++ { + m.UpdatedItems = append(m.UpdatedItems, mhfitem.ReadWarehouseItem(bf)) } - return nil } diff --git a/network/mhfpacket/msg_mhf_update_warehouse.go b/network/mhfpacket/msg_mhf_update_warehouse.go index 5cac9425b..9d264cf89 100644 --- a/network/mhfpacket/msg_mhf_update_warehouse.go +++ b/network/mhfpacket/msg_mhf_update_warehouse.go @@ -28,7 +28,8 @@ func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl m.BoxType = bf.ReadUint8() m.BoxIndex = bf.ReadUint8() changes := int(bf.ReadUint16()) - bf.ReadBytes(2) // Zeroed + bf.ReadUint8() // Zeroed + bf.ReadUint8() // Zeroed for i := 0; i < changes; i++ { switch m.BoxType { case 0: diff --git a/schemas/patch-schema/reset-warehouses.sql b/schemas/patch-schema/reset-warehouses.sql new file mode 100644 index 000000000..efb42f8a9 --- /dev/null +++ b/schemas/patch-schema/reset-warehouses.sql @@ -0,0 +1,6 @@ +BEGIN; + +UPDATE guilds SET item_box=NULL; +UPDATE users SET item_box=NULL; + +END; \ No newline at end of file diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index ba3161f8b..a3657f7be 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -7,6 +7,7 @@ import ( "erupe-ce/common/mhfmon" ps "erupe-ce/common/pascalstring" "erupe-ce/common/stringsupport" + "erupe-ce/common/token" _config "erupe-ce/config" "fmt" "io" @@ -818,93 +819,53 @@ func handleMsgMhfEnumerateOrder(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfGetExtraInfo(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfEnumerateUnionItem) - var boxContents []byte - 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.Error("Failed to get shared item box contents from db", zap.Error(err)) - bf.WriteBytes(make([]byte, 4)) - } else { - if len(boxContents) == 0 { - bf.WriteBytes(make([]byte, 4)) - } else { - amount := len(boxContents) / 4 - bf.WriteUint16(uint16(amount)) - bf.WriteUint32(0x00) - bf.WriteUint16(0x00) - for i := 0; i < amount; i++ { - bf.WriteUint32(binary.BigEndian.Uint32(boxContents[i*4 : i*4+4])) - if i+1 != amount { - bf.WriteUint64(0x00) - } - } +func userGetItems(s *Session) []mhfitem.MHFItemStack { + var data []byte + var items []mhfitem.MHFItemStack + s.server.db.QueryRow(`SELECT item_box FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&data) + if len(data) > 0 { + box := byteframe.NewByteFrameFromBytes(data) + numStacks := box.ReadUint16() + box.ReadUint16() // Unused + for i := 0; i < int(numStacks); i++ { + items = append(items, mhfitem.ReadWarehouseItem(box)) } } + return items +} + +func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfEnumerateUnionItem) + items := userGetItems(s) + bf := byteframe.NewByteFrame() + bf.WriteBytes(mhfitem.SerializeWarehouseItems(items)) doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateUnionItem) - // Get item cache from DB - var boxContents []byte - var oldItems []Item - - 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.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) - for i := 0; i < amount; i++ { - oldItems[i].ItemId = binary.BigEndian.Uint16(boxContents[i*4 : i*4+2]) - oldItems[i].Amount = binary.BigEndian.Uint16(boxContents[i*4+2 : i*4+4]) - } - } - - // Update item stacks - newItems := make([]Item, len(oldItems)) - copy(newItems, oldItems) - for i := 0; i < len(pkt.Items); i++ { - for j := 0; j <= len(oldItems); j++ { - if j == len(oldItems) { - var newItem Item - newItem.ItemId = pkt.Items[i].ItemID - newItem.Amount = pkt.Items[i].Amount - newItems = append(newItems, newItem) - break - } - if pkt.Items[i].ItemID == oldItems[j].ItemId { - newItems[j].Amount = pkt.Items[i].Amount - break + // o = old, u = update, f = final + var fItems []mhfitem.MHFItemStack + oItems := userGetItems(s) + for _, uItem := range pkt.UpdatedItems { + exists := false + for i := range oItems { + if oItems[i].WarehouseID == uItem.WarehouseID { + exists = true + oItems[i].Quantity = uItem.Quantity } } - } - - // Delete empty item stacks - for i := len(newItems) - 1; i >= 0; i-- { - if int(newItems[i].Amount) == 0 { - copy(newItems[i:], newItems[i+1:]) - newItems[len(newItems)-1] = make([]Item, 1)[0] - newItems = newItems[:len(newItems)-1] + if !exists { + uItem.WarehouseID = token.RNG.Uint32() + fItems = append(fItems, uItem) } } - - // Create new item cache - bf := byteframe.NewByteFrame() - for i := 0; i < len(newItems); i++ { - bf.WriteUint16(newItems[i].ItemId) - bf.WriteUint16(newItems[i].Amount) - } - - // 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.Error("Failed to update shared item box contents in db", zap.Error(err)) + for _, oItem := range oItems { + if oItem.Quantity > 0 { + fItems = append(fItems, oItem) + } } + s.server.db.Exec(`UPDATE users u SET item_box=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, mhfitem.SerializeWarehouseItems(fItems), s.charID) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index 9df9dd2c6..07b9106cb 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -3,9 +3,10 @@ package channelserver import ( "database/sql" "database/sql/driver" - "encoding/binary" "encoding/json" "errors" + "erupe-ce/common/mhfitem" + "erupe-ce/common/token" _config "erupe-ce/config" "fmt" "math" @@ -1554,100 +1555,54 @@ func handleMsgMhfGetGuildTargetMemberNum(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } -func handleMsgMhfEnumerateGuildItem(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfEnumerateGuildItem) - var boxContents []byte - bf := byteframe.NewByteFrame() - err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", pkt.GuildID).Scan(&boxContents) - if err != nil { - 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.WriteBytes(make([]byte, 4)) - } else { - amount := len(boxContents) / 4 - bf.WriteUint16(uint16(amount)) - bf.WriteUint32(0x00) - bf.WriteUint16(0x00) - for i := 0; i < amount; i++ { - bf.WriteUint32(binary.BigEndian.Uint32(boxContents[i*4 : i*4+4])) - if i+1 != amount { - bf.WriteUint64(0x00) - } - } +func guildGetItems(s *Session, guildID uint32) []mhfitem.MHFItemStack { + var data []byte + var items []mhfitem.MHFItemStack + s.server.db.QueryRow(`SELECT item_box FROM guilds WHERE id=$1`, guildID).Scan(&data) + if len(data) > 0 { + box := byteframe.NewByteFrameFromBytes(data) + numStacks := box.ReadUint16() + box.ReadUint16() // Unused + for i := 0; i < int(numStacks); i++ { + items = append(items, mhfitem.ReadWarehouseItem(box)) } } - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + return items } -type Item struct { - ItemId uint16 - Amount uint16 +func handleMsgMhfEnumerateGuildItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfEnumerateGuildItem) + items := guildGetItems(s, pkt.GuildID) + bf := byteframe.NewByteFrame() + bf.WriteBytes(mhfitem.SerializeWarehouseItems(items)) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfUpdateGuildItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateGuildItem) - - // Get item cache from DB - var boxContents []byte - var oldItems []Item - err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", pkt.GuildID).Scan(&boxContents) - if err != nil { - 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) - for i := 0; i < amount; i++ { - oldItems[i].ItemId = binary.BigEndian.Uint16(boxContents[i*4 : i*4+2]) - oldItems[i].Amount = binary.BigEndian.Uint16(boxContents[i*4+2 : i*4+4]) - } - } - - // Update item stacks - newItems := make([]Item, len(oldItems)) - copy(newItems, oldItems) - for i := 0; i < len(pkt.Items); i++ { - for j := 0; j <= len(oldItems); j++ { - if j == len(oldItems) { - var newItem Item - newItem.ItemId = pkt.Items[i].ItemID - newItem.Amount = pkt.Items[i].Amount - newItems = append(newItems, newItem) - break - } - if pkt.Items[i].ItemID == oldItems[j].ItemId { - newItems[j].Amount = pkt.Items[i].Amount - break + // o = old, u = update, f = final + var fItems []mhfitem.MHFItemStack + oItems := guildGetItems(s, pkt.GuildID) + for _, uItem := range pkt.UpdatedItems { + exists := false + for i := range oItems { + if oItems[i].WarehouseID == uItem.WarehouseID { + exists = true + oItems[i].Quantity = uItem.Quantity } } - } - - // Delete empty item stacks - for i := len(newItems) - 1; i >= 0; i-- { - if int(newItems[i].Amount) == 0 { - copy(newItems[i:], newItems[i+1:]) - newItems[len(newItems)-1] = make([]Item, 1)[0] - newItems = newItems[:len(newItems)-1] + if !exists { + uItem.WarehouseID = token.RNG.Uint32() + fItems = append(fItems, uItem) } } - - // Create new item cache - bf := byteframe.NewByteFrame() - for i := 0; i < len(newItems); i++ { - bf.WriteUint16(newItems[i].ItemId) - bf.WriteUint16(newItems[i].Amount) + for _, oItem := range oItems { + if oItem.Quantity > 0 { + fItems = append(fItems, oItem) + } } - - // Upload new item cache - _, err = s.server.db.Exec("UPDATE guilds SET item_box = $1 WHERE id = $2", bf.Data(), pkt.GuildID) - if err != nil { - s.logger.Error("Failed to update guild item box contents in db", zap.Error(err)) - } - - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + s.server.db.Exec(`UPDATE guilds SET item_box=$1 WHERE id=$2`, mhfitem.SerializeWarehouseItems(fItems), pkt.GuildID) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } func handleMsgMhfUpdateGuildIcon(s *Session, p mhfpacket.MHFPacket) {