mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-15 08:25:09 +01:00
Merge pull request #14 from straticspaff/feature/garden-cat
Garden Cat (Account Shared Inventory)
This commit is contained in:
@@ -9,7 +9,8 @@ CREATE DOMAIN uint16 AS integer
|
||||
CREATE TABLE users (
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
username text UNIQUE NOT NULL,
|
||||
password text NOT NULL
|
||||
password text NOT NULL,
|
||||
item_box bytea
|
||||
);
|
||||
|
||||
CREATE TABLE characters (
|
||||
|
||||
@@ -3,13 +3,16 @@ package mhfpacket
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
)
|
||||
|
||||
// MsgMhfEnumerateUnionItem represents the MSG_MHF_ENUMERATE_UNION_ITEM
|
||||
type MsgMhfEnumerateUnionItem struct{}
|
||||
type MsgMhfEnumerateUnionItem struct {
|
||||
AckHandle uint32
|
||||
Unk0 uint16
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfEnumerateUnionItem) Opcode() network.PacketID {
|
||||
@@ -18,7 +21,10 @@ func (m *MsgMhfEnumerateUnionItem) Opcode() network.PacketID {
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfEnumerateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint16()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
|
||||
@@ -3,13 +3,25 @@ package mhfpacket
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
Unk0 uint32
|
||||
ItemId uint16
|
||||
Amount uint16
|
||||
Unk1 uint32
|
||||
}
|
||||
|
||||
// MsgMhfUpdateUnionItem represents the MSG_MHF_UPDATE_UNION_ITEM
|
||||
type MsgMhfUpdateUnionItem struct{}
|
||||
type MsgMhfUpdateUnionItem struct {
|
||||
AckHandle uint32
|
||||
Amount uint16
|
||||
Unk1 uint16 // 0x00 0x00
|
||||
Items []Item // Array of updated item IDs
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID {
|
||||
@@ -18,7 +30,19 @@ func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID {
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfUpdateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Amount = bf.ReadUint16()
|
||||
m.Unk1 = bf.ReadUint16()
|
||||
m.Items = make([]Item, int(m.Amount))
|
||||
|
||||
for i := 0; i < int(m.Amount); 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()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
|
||||
@@ -2,11 +2,12 @@ package channelserver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/bits"
|
||||
"math/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
@@ -356,9 +357,100 @@ func handleMsgMhfAcquireTitle(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgMhfEnumerateTitle(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) {}
|
||||
type Item struct {
|
||||
ItemId uint16
|
||||
Amount uint16
|
||||
}
|
||||
|
||||
func handleMsgMhfUpdateUnionItem(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.Fatal("Failed to get shared item box contents from db", zap.Error(err))
|
||||
} else {
|
||||
if len(boxContents) == 0 {
|
||||
bf.WriteUint32(0x00)
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
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.Fatal("Failed to get shared item box contents from db", zap.Error(err))
|
||||
} 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 < int(pkt.Amount); 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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]
|
||||
}
|
||||
}
|
||||
|
||||
// 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.Fatal("Failed to update shared item box contents in db", zap.Error(err))
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
|
||||
}
|
||||
|
||||
func handleMsgMhfCreateJoint(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user