initial warehouse-v2 concept commit

This commit is contained in:
wish
2023-10-01 03:17:51 +11:00
parent 4bf8dc32eb
commit a9f280a2ef
6 changed files with 258 additions and 151 deletions

133
common/mhfitem/mhfitem.go Normal file
View File

@@ -0,0 +1,133 @@
package mhfitem
import "erupe-ce/common/byteframe"
type MHFItem struct {
ItemID uint16
}
type MHFSigilEffect struct {
ID uint16
Level uint16
}
type MHFSigil struct {
Effects []MHFSigilEffect
Unk0 uint8
Unk1 uint8
Unk2 uint8
Unk3 uint8
}
type MHFEquipment struct {
WarehouseID uint32
ItemType uint8
Unk0 uint8
ItemID uint16
Level uint16
Decorations []MHFItem
Sigils []MHFSigil
Unk1 uint16
}
type MHFItemStack struct {
WarehouseID uint32
Item MHFItem
Quantity uint16
Unk0 uint32
}
func ReadWarehouseItem(bf *byteframe.ByteFrame) MHFItemStack {
var item MHFItemStack
item.WarehouseID = bf.ReadUint32()
item.Item.ItemID = bf.ReadUint16()
item.Quantity = bf.ReadUint16()
item.Unk0 = bf.ReadUint32()
return item
}
func (is MHFItemStack) ToBytes() []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint32(is.WarehouseID)
bf.WriteUint16(is.Item.ItemID)
bf.WriteUint16(is.Quantity)
bf.WriteUint32(is.Unk0)
return bf.Data()
}
func SerializeWarehouseItems(i []MHFItemStack) []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint16(uint16(len(i)))
bf.WriteUint16(0) // Unused
for _, j := range i {
bf.WriteBytes(j.ToBytes())
}
return bf.Data()
}
func ReadWarehouseEquipment(bf *byteframe.ByteFrame) MHFEquipment {
var equipment MHFEquipment
equipment.Decorations = make([]MHFItem, 3)
equipment.Sigils = make([]MHFSigil, 3)
for i := 0; i < 3; i++ {
equipment.Sigils[i].Effects = make([]MHFSigilEffect, 3)
}
equipment.WarehouseID = bf.ReadUint32()
equipment.ItemType = bf.ReadUint8()
equipment.Unk0 = bf.ReadUint8()
equipment.ItemID = bf.ReadUint16()
equipment.Level = bf.ReadUint16()
for i := 0; i < 3; i++ {
equipment.Decorations[i].ItemID = bf.ReadUint16()
}
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
equipment.Sigils[i].Effects[j].ID = bf.ReadUint16()
}
for j := 0; j < 3; j++ {
equipment.Sigils[i].Effects[j].Level = bf.ReadUint16()
}
equipment.Sigils[i].Unk0 = bf.ReadUint8()
equipment.Sigils[i].Unk1 = bf.ReadUint8()
equipment.Sigils[i].Unk2 = bf.ReadUint8()
equipment.Sigils[i].Unk3 = bf.ReadUint8()
}
equipment.Unk1 = bf.ReadUint16()
return equipment
}
func (e MHFEquipment) ToBytes() []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint32(e.WarehouseID)
bf.WriteUint8(e.ItemType)
bf.WriteUint8(e.Unk0)
bf.WriteUint16(e.ItemID)
bf.WriteUint16(e.Level)
for i := 0; i < 3; i++ {
bf.WriteUint16(e.Decorations[i].ItemID)
}
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
bf.WriteUint16(e.Sigils[i].Effects[j].ID)
}
for j := 0; j < 3; j++ {
bf.WriteUint16(e.Sigils[i].Effects[j].Level)
}
bf.WriteUint8(e.Sigils[i].Unk0)
bf.WriteUint8(e.Sigils[i].Unk1)
bf.WriteUint8(e.Sigils[i].Unk2)
bf.WriteUint8(e.Sigils[i].Unk3)
}
bf.WriteUint16(e.Unk1)
return bf.Data()
}
func SerializeWarehouseEquipment(i []MHFEquipment) []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint16(uint16(len(i)))
bf.WriteUint16(0) // Unused
for _, j := range i {
bf.WriteBytes(j.ToBytes())
}
return bf.Data()
}

View File

@@ -11,7 +11,7 @@ import (
// MsgMhfEnumerateWarehouse represents the MSG_MHF_ENUMERATE_WAREHOUSE // MsgMhfEnumerateWarehouse represents the MSG_MHF_ENUMERATE_WAREHOUSE
type MsgMhfEnumerateWarehouse struct { type MsgMhfEnumerateWarehouse struct {
AckHandle uint32 AckHandle uint32
BoxType string BoxType uint8
BoxIndex uint8 BoxIndex uint8
} }
@@ -23,15 +23,9 @@ func (m *MsgMhfEnumerateWarehouse) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
boxType := bf.ReadUint8() m.BoxType = bf.ReadUint8()
switch boxType {
case 0:
m.BoxType = "item"
case 1:
m.BoxType = "equip"
}
m.BoxIndex = bf.ReadUint8() m.BoxIndex = bf.ReadUint8()
_ = bf.ReadUint16() bf.ReadBytes(2) // Zeroed
return nil return nil
} }

View File

@@ -13,7 +13,7 @@ import (
type MsgMhfOperateWarehouse struct { type MsgMhfOperateWarehouse struct {
AckHandle uint32 AckHandle uint32
Operation uint8 Operation uint8
BoxType string BoxType uint8
BoxIndex uint8 BoxIndex uint8
Name string Name string
} }
@@ -27,16 +27,10 @@ func (m *MsgMhfOperateWarehouse) Opcode() network.PacketID {
func (m *MsgMhfOperateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfOperateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Operation = bf.ReadUint8() m.Operation = bf.ReadUint8()
boxType := bf.ReadUint8() m.BoxType = bf.ReadUint8()
switch boxType {
case 0:
m.BoxType = "item"
case 1:
m.BoxType = "equip"
}
m.BoxIndex = bf.ReadUint8() m.BoxIndex = bf.ReadUint8()
_ = bf.ReadUint8() // lenName _ = bf.ReadUint8() // lenName
_ = bf.ReadUint16() // Unk bf.ReadUint16() // Zeroed
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -3,25 +3,18 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/mhfitem"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
type WarehouseStack struct {
ID uint32
Index uint16
EquipType uint16
ItemID uint16
Quantity uint16
Data []byte
}
// MsgMhfUpdateWarehouse represents the MSG_MHF_UPDATE_WAREHOUSE // MsgMhfUpdateWarehouse represents the MSG_MHF_UPDATE_WAREHOUSE
type MsgMhfUpdateWarehouse struct { type MsgMhfUpdateWarehouse struct {
AckHandle uint32 AckHandle uint32
BoxType string BoxType uint8
BoxIndex uint8 BoxIndex uint8
Updates []WarehouseStack UpdatedItems []mhfitem.MHFItemStack
UpdatedEquipment []mhfitem.MHFEquipment
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,35 +25,18 @@ func (m *MsgMhfUpdateWarehouse) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
boxType := bf.ReadUint8() m.BoxType = bf.ReadUint8()
switch boxType {
case 0:
m.BoxType = "item"
case 1:
m.BoxType = "equip"
}
m.BoxIndex = bf.ReadUint8() m.BoxIndex = bf.ReadUint8()
changes := int(bf.ReadUint16()) changes := int(bf.ReadUint16())
var stackUpdate WarehouseStack bf.ReadBytes(2) // Zeroed
for i := 0; i < changes; i++ { for i := 0; i < changes; i++ {
switch boxType { switch m.BoxType {
case 0: case 0:
stackUpdate.ID = bf.ReadUint32() m.UpdatedItems = append(m.UpdatedItems, mhfitem.ReadWarehouseItem(bf))
stackUpdate.Index = bf.ReadUint16()
stackUpdate.ItemID = bf.ReadUint16()
stackUpdate.Quantity = bf.ReadUint16()
_ = bf.ReadUint16() // Unk
m.Updates = append(m.Updates, stackUpdate)
case 1: case 1:
stackUpdate.ID = bf.ReadUint32() m.UpdatedEquipment = append(m.UpdatedEquipment, mhfitem.ReadWarehouseEquipment(bf))
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 return nil
} }

View File

@@ -4,6 +4,7 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"erupe-ce/common/mhfcourse" "erupe-ce/common/mhfcourse"
"erupe-ce/common/mhfitem"
ps "erupe-ce/common/pascalstring" ps "erupe-ce/common/pascalstring"
"erupe-ce/common/stringsupport" "erupe-ce/common/stringsupport"
_config "erupe-ce/config" _config "erupe-ce/config"
@@ -762,19 +763,19 @@ func handleMsgMhfCheckWeeklyStamp(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfExchangeWeeklyStamp(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfExchangeWeeklyStamp(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfExchangeWeeklyStamp) pkt := p.(*mhfpacket.MsgMhfExchangeWeeklyStamp)
var total, redeemed uint16 var total, redeemed uint16
var tktStack mhfpacket.WarehouseStack var tktStack mhfitem.MHFItemStack
if pkt.Unk1 == 0xA { // Yearly Sub Ex if pkt.Unk1 == 0xA { // Yearly Sub Ex
s.server.db.QueryRow("UPDATE stamps SET hl_total=hl_total-48, hl_redeemed=hl_redeemed-48 WHERE character_id=$1 RETURNING hl_total, hl_redeemed", s.charID).Scan(&total, &redeemed) s.server.db.QueryRow("UPDATE stamps SET hl_total=hl_total-48, hl_redeemed=hl_redeemed-48 WHERE character_id=$1 RETURNING hl_total, hl_redeemed", s.charID).Scan(&total, &redeemed)
tktStack = mhfpacket.WarehouseStack{ItemID: 0x08A2, Quantity: 1} tktStack = mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: 2210}, Quantity: 1}
} else { } else {
s.server.db.QueryRow(fmt.Sprintf("UPDATE stamps SET %s_redeemed=%s_redeemed+8 WHERE character_id=$1 RETURNING %s_total, %s_redeemed", pkt.StampType, pkt.StampType, pkt.StampType, pkt.StampType), s.charID).Scan(&total, &redeemed) s.server.db.QueryRow(fmt.Sprintf("UPDATE stamps SET %s_redeemed=%s_redeemed+8 WHERE character_id=$1 RETURNING %s_total, %s_redeemed", pkt.StampType, pkt.StampType, pkt.StampType, pkt.StampType), s.charID).Scan(&total, &redeemed)
if pkt.StampType == "hl" { if pkt.StampType == "hl" {
tktStack = mhfpacket.WarehouseStack{ItemID: 0x065E, Quantity: 5} tktStack = mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: 1630}, Quantity: 5}
} else { } else {
tktStack = mhfpacket.WarehouseStack{ItemID: 0x065F, Quantity: 5} tktStack = mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: 1631}, Quantity: 5}
} }
} }
addWarehouseGift(s, "item", tktStack) addWarehouseItem(s, tktStack)
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint16(total) bf.WriteUint16(total)
bf.WriteUint16(redeemed) bf.WriteUint16(redeemed)
@@ -1626,13 +1627,13 @@ func handleMsgMhfStampcardStamp(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint16(pkt.Reward2) bf.WriteUint16(pkt.Reward2)
bf.WriteUint16(pkt.Item2) bf.WriteUint16(pkt.Item2)
bf.WriteUint16(pkt.Quantity2) bf.WriteUint16(pkt.Quantity2)
addWarehouseGift(s, "item", mhfpacket.WarehouseStack{ItemID: pkt.Item2, Quantity: pkt.Quantity2}) addWarehouseItem(s, mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item2}, Quantity: pkt.Quantity2})
} else if stamps%15 == 0 { } else if stamps%15 == 0 {
bf.WriteUint16(1) bf.WriteUint16(1)
bf.WriteUint16(pkt.Reward1) bf.WriteUint16(pkt.Reward1)
bf.WriteUint16(pkt.Item1) bf.WriteUint16(pkt.Item1)
bf.WriteUint16(pkt.Quantity1) bf.WriteUint16(pkt.Quantity1)
addWarehouseGift(s, "item", mhfpacket.WarehouseStack{ItemID: pkt.Item1, Quantity: pkt.Quantity1}) addWarehouseItem(s, mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item1}, Quantity: pkt.Quantity1})
} else { } else {
bf.WriteBytes(make([]byte, 8)) bf.WriteBytes(make([]byte, 8))
} }

View File

@@ -1,7 +1,9 @@
package channelserver package channelserver
import ( import (
"crypto/rand"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/mhfitem"
ps "erupe-ce/common/pascalstring" ps "erupe-ce/common/pascalstring"
"erupe-ce/common/stringsupport" "erupe-ce/common/stringsupport"
_config "erupe-ce/config" _config "erupe-ce/config"
@@ -406,7 +408,12 @@ func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) {
case 1: case 1:
bf.WriteUint8(0) bf.WriteUint8(0)
case 2: 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) switch pkt.BoxType {
case 0:
s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET item%dname=$1 WHERE character_id=$2", pkt.BoxIndex), pkt.Name, s.charID)
case 1:
s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET equip%dname=$1 WHERE character_id=$2", pkt.BoxIndex), pkt.Name, s.charID)
}
case 3: case 3:
bf.WriteUint32(0) // Usage renewal time, >1 = disabled bf.WriteUint32(0) // Usage renewal time, >1 = disabled
bf.WriteUint16(10000) // Usages bf.WriteUint16(10000) // Usages
@@ -424,81 +431,74 @@ func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) {
doAckBufSucceed(s, pkt.AckHandle, bf.Data()) doAckBufSucceed(s, pkt.AckHandle, bf.Data())
} }
func addWarehouseGift(s *Session, boxType string, giftStack mhfpacket.WarehouseStack) { func addWarehouseItem(s *Session, item mhfitem.MHFItemStack) {
giftBox := getWarehouseBox(s, boxType, 10) giftBox := warehouseGetItems(s, 10)
if boxType == "item" { exists := false
exists := false for i, stack := range giftBox {
for i, stack := range giftBox { if stack.Item.ItemID == item.Item.ItemID {
if stack.ItemID == giftStack.ItemID { exists = true
exists = true giftBox[i].Quantity += item.Quantity
giftBox[i].Quantity += giftStack.Quantity break
break
}
} }
if exists == false {
giftBox = append(giftBox, giftStack)
}
} else {
giftBox = append(giftBox, giftStack)
} }
s.server.db.Exec(fmt.Sprintf("UPDATE warehouse SET %s10=$1 WHERE character_id=$2", boxType), boxToBytes(giftBox, boxType), s.charID) if !exists {
giftBox = append(giftBox, item)
}
s.server.db.Exec("UPDATE warehouse SET item10=$1 WHERE character_id=$2", mhfitem.SerializeWarehouseItems(giftBox), s.charID)
} }
func getWarehouseBox(s *Session, boxType string, boxIndex uint8) []mhfpacket.WarehouseStack { func addWarehouseEquipment(s *Session, equipment mhfitem.MHFEquipment) {
giftBox := warehouseGetEquipment(s, 10)
giftBox = append(giftBox, equipment)
s.server.db.Exec("UPDATE warehouse SET equip10=$1 WHERE character_id=$2", mhfitem.SerializeWarehouseEquipment(giftBox), s.charID)
}
func warehouseGetItems(s *Session, index uint8) []mhfitem.MHFItemStack {
var data []byte var data []byte
s.server.db.QueryRow(fmt.Sprintf("SELECT %s%d FROM warehouse WHERE character_id=$1", boxType, boxIndex), s.charID).Scan(&data) var items []mhfitem.MHFItemStack
s.server.db.QueryRow(fmt.Sprintf(`SELECT item%d FROM warehouse WHERE character_id=$1`, index), s.charID).Scan(&data)
if len(data) > 0 { if len(data) > 0 {
box := byteframe.NewByteFrameFromBytes(data) box := byteframe.NewByteFrameFromBytes(data)
numStacks := box.ReadUint16() numStacks := box.ReadUint16()
stacks := make([]mhfpacket.WarehouseStack, numStacks) box.ReadUint16() // Unused
for i := 0; i < int(numStacks); i++ { for i := 0; i < int(numStacks); i++ {
if boxType == "item" { items = append(items, mhfitem.ReadWarehouseItem(box))
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 {
return make([]mhfpacket.WarehouseStack, 0)
} }
return items
} }
func boxToBytes(stacks []mhfpacket.WarehouseStack, boxType string) []byte { func warehouseGetEquipment(s *Session, index uint8) []mhfitem.MHFEquipment {
bf := byteframe.NewByteFrame() var data []byte
bf.WriteUint16(uint16(len(stacks))) var equipment []mhfitem.MHFEquipment
for i, stack := range stacks { s.server.db.QueryRow(fmt.Sprintf(`SELECT equip%d FROM warehouse WHERE character_id=$1`, index), s.charID).Scan(&data)
if boxType == "item" { if len(data) > 0 {
bf.WriteUint32(stack.ID) box := byteframe.NewByteFrameFromBytes(data)
bf.WriteUint16(uint16(i + 1)) numStacks := box.ReadUint16()
bf.WriteUint16(stack.ItemID) box.ReadUint16() // Unused
bf.WriteUint16(stack.Quantity) for i := 0; i < int(numStacks); i++ {
bf.WriteUint16(0) temp := mhfitem.ReadWarehouseEquipment(box)
} else { if !temp.Deleted {
bf.WriteUint32(stack.ID) equipment = append(equipment, temp)
bf.WriteUint16(uint16(i + 1)) }
bf.WriteUint16(stack.EquipType)
bf.WriteUint16(stack.ItemID)
bf.WriteBytes(stack.Data)
} }
} }
bf.WriteUint16(0) return equipment
return bf.Data()
} }
func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfEnumerateWarehouse) pkt := p.(*mhfpacket.MsgMhfEnumerateWarehouse)
box := getWarehouseBox(s, pkt.BoxType, pkt.BoxIndex) bf := byteframe.NewByteFrame()
if len(box) > 0 { switch pkt.BoxType {
doAckBufSucceed(s, pkt.AckHandle, boxToBytes(box, pkt.BoxType)) case 0:
items := warehouseGetItems(s, pkt.BoxIndex)
bf.WriteBytes(mhfitem.SerializeWarehouseItems(items))
case 1:
equipment := warehouseGetEquipment(s, pkt.BoxIndex)
bf.WriteBytes(mhfitem.SerializeWarehouseEquipment(equipment))
}
if bf.Index() > 0 {
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
} else { } else {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
@@ -506,49 +506,58 @@ func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfUpdateWarehouse) pkt := p.(*mhfpacket.MsgMhfUpdateWarehouse)
box := getWarehouseBox(s, pkt.BoxType, pkt.BoxIndex) // o = old, u = update, f = final
// Update existing stacks var fItems []mhfitem.MHFItemStack
var newStacks []mhfpacket.WarehouseStack var fEquip []mhfitem.MHFEquipment
for _, update := range pkt.Updates { switch pkt.BoxType {
exists := false case 0:
if pkt.BoxType == "item" { oItems := warehouseGetItems(s, pkt.BoxIndex)
for i, stack := range box { for _, uItem := range pkt.UpdatedItems {
if stack.Index == update.Index { exists := false
for _, oItem := range oItems {
if uItem.Item.ItemID == oItem.Item.ItemID {
if uItem.Quantity > 0 {
fItems = append(fItems, uItem)
}
exists = true exists = true
box[i].Quantity = update.Quantity
break break
} }
} }
} else { if !exists {
for i, stack := range box { newID := make([]byte, 4)
if stack.Index == update.Index { _, _ = rand.Read(newID)
bf := byteframe.NewByteFrameFromBytes(newID)
uItem.WarehouseID = bf.ReadUint32()
fItems = append(fItems, uItem)
}
}
s.server.db.Exec(fmt.Sprintf(`UPDATE warehouse SET item%d=$1 WHERE character_id=$2`, pkt.BoxIndex), mhfitem.SerializeWarehouseItems(fItems), s.charID)
case 1:
oEquips := warehouseGetEquipment(s, pkt.BoxIndex)
for _, uEquip := range pkt.UpdatedEquipment {
exists := false
for _, oEquip := range oEquips {
if oEquip.WarehouseID == uEquip.WarehouseID {
exists = true exists = true
box[i].ItemID = update.ItemID // Will set removed items to 0
oEquip.ItemID = uEquip.ItemID
break break
} }
} }
} if !exists {
if exists == false { newID := make([]byte, 4)
newStacks = append(newStacks, update) _, _ = rand.Read(newID)
} bf := byteframe.NewByteFrameFromBytes(newID)
} uEquip.WarehouseID = bf.ReadUint32()
// Append new stacks fEquip = append(fEquip, uEquip)
for _, stack := range newStacks {
box = append(box, stack)
}
// Slice empty stacks
var cleanedBox []mhfpacket.WarehouseStack
for _, stack := range box {
if pkt.BoxType == "item" {
if stack.Quantity > 0 {
cleanedBox = append(cleanedBox, stack)
}
} else {
if stack.ItemID != 0 {
cleanedBox = append(cleanedBox, stack)
} }
} }
for _, oEquip := range oEquips {
if oEquip.ItemID > 0 {
fEquip = append(fEquip, oEquip)
}
}
s.server.db.Exec(fmt.Sprintf(`UPDATE warehouse SET equip%d=$1 WHERE character_id=$2`, pkt.BoxIndex), mhfitem.SerializeWarehouseEquipment(fEquip), 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)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }