fix gook enumeration

This commit is contained in:
wish
2022-07-25 02:27:36 +10:00
parent b7c293812c
commit bfdcca44e1
2 changed files with 63 additions and 209 deletions

View File

@@ -1,42 +1,22 @@
package mhfpacket
import (
"errors"
import (
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// GuacotUpdateEntry represents an entry inside the MsgMhfUpdateGuacot packet.
type GuacotUpdateEntry struct {
Unk0 uint32
Unk1 uint16
Unk2 uint16
Unk3 uint16
Unk4 uint16
Unk5 uint16
Unk6 uint16
Unk7 uint16
Unk8 uint16
Unk9 uint16
Unk10 uint16
Unk11 uint16
Unk12 uint16
Unk13 uint16
Unk14 uint16
Unk15 uint16
Unk16 uint16
Unk17 uint16
Unk18 uint16
Unk19 uint16
Unk20 uint16
Unk21 uint16
Unk22 uint16
Unk23 uint32
Unk24 uint32
DataSize uint8
RawDataPayload []byte
type Gook struct {
Exists bool
Index uint32
Type uint16
Data []byte
Birthday1 uint32
Birthday2 uint32
NameLen uint8
Name []byte
}
// MsgMhfUpdateGuacot represents the MSG_MHF_UPDATE_GUACOT
@@ -44,7 +24,7 @@ type MsgMhfUpdateGuacot struct {
AckHandle uint32
EntryCount uint16
Unk0 uint16 // Hardcoded 0 in binary
Entries []*GuacotUpdateEntry
Gooks []Gook
}
// Opcode returns the ID associated with this packet type.
@@ -58,38 +38,20 @@ func (m *MsgMhfUpdateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
m.EntryCount = bf.ReadUint16()
m.Unk0 = bf.ReadUint16()
for i := 0; i < int(m.EntryCount); i++ {
// Yikes.
e := &GuacotUpdateEntry{}
e.Unk0 = bf.ReadUint32()
e.Unk1 = bf.ReadUint16()
e.Unk2 = bf.ReadUint16()
e.Unk3 = bf.ReadUint16()
e.Unk4 = bf.ReadUint16()
e.Unk5 = bf.ReadUint16()
e.Unk6 = bf.ReadUint16()
e.Unk7 = bf.ReadUint16()
e.Unk8 = bf.ReadUint16()
e.Unk9 = bf.ReadUint16()
e.Unk10 = bf.ReadUint16()
e.Unk11 = bf.ReadUint16()
e.Unk12 = bf.ReadUint16()
e.Unk13 = bf.ReadUint16()
e.Unk14 = bf.ReadUint16()
e.Unk15 = bf.ReadUint16()
e.Unk16 = bf.ReadUint16()
e.Unk17 = bf.ReadUint16()
e.Unk18 = bf.ReadUint16()
e.Unk19 = bf.ReadUint16()
e.Unk20 = bf.ReadUint16()
e.Unk21 = bf.ReadUint16()
e.Unk22 = bf.ReadUint16()
e.Unk23 = bf.ReadUint32()
e.Unk24 = bf.ReadUint32()
e.DataSize = bf.ReadUint8()
e.RawDataPayload = bf.ReadBytes(uint(e.DataSize))
m.Entries = append(m.Entries, e)
e := Gook{}
e.Index = bf.ReadUint32()
e.Type = bf.ReadUint16()
e.Data = bf.ReadBytes(42)
e.Birthday1 = bf.ReadUint32()
e.Birthday2 = bf.ReadUint32()
e.NameLen = bf.ReadUint8()
e.Name = bf.ReadBytes(uint(e.NameLen))
if e.Type > 0 {
e.Exists = true
} else {
e.Exists = false
}
m.Gooks = append(m.Gooks, e)
}
return nil
}
@@ -98,36 +60,3 @@ func (m *MsgMhfUpdateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
func (m *MsgMhfUpdateGuacot) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
}
func (m *MsgMhfUpdateGuacot) GuacotUpdateEntryToBytes(Entry *GuacotUpdateEntry) []byte {
resp:= byteframe.NewByteFrame()
resp.WriteUint32(Entry.Unk0)
resp.WriteUint16(Entry.Unk1)
resp.WriteUint16(Entry.Unk1)
resp.WriteUint16(Entry.Unk2)
resp.WriteUint16(Entry.Unk3)
resp.WriteUint16(Entry.Unk4)
resp.WriteUint16(Entry.Unk5)
resp.WriteUint16(Entry.Unk6)
resp.WriteUint16(Entry.Unk7)
resp.WriteUint16(Entry.Unk8)
resp.WriteUint16(Entry.Unk9)
resp.WriteUint16(Entry.Unk10)
resp.WriteUint16(Entry.Unk11)
resp.WriteUint16(Entry.Unk12)
resp.WriteUint16(Entry.Unk13)
resp.WriteUint16(Entry.Unk14)
resp.WriteUint16(Entry.Unk15)
resp.WriteUint16(Entry.Unk16)
resp.WriteUint16(Entry.Unk17)
resp.WriteUint16(Entry.Unk18)
resp.WriteUint16(Entry.Unk19)
resp.WriteUint16(Entry.Unk20)
resp.WriteUint16(Entry.Unk21)
resp.WriteUint16(Entry.Unk22)
resp.WriteUint32(Entry.Unk23)
resp.WriteUint32(Entry.Unk24)
resp.WriteUint8(Entry.DataSize)
resp.WriteBytes(Entry.RawDataPayload)
return resp.Data()
}

View File

@@ -4,8 +4,8 @@ import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"io/ioutil"
"math/bits"
"math/rand"
@@ -579,123 +579,48 @@ func handleMsgMhfExchangeWeeklyStamp(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgMhfEnumerateGuacot(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfEnumerateGuacot)
var data bool
err := s.server.db.QueryRow("SELECT gook0status FROM gook WHERE id = $1", s.charID).Scan(&data)
if err == nil {
tempresp := byteframe.NewByteFrame()
count := uint16(0)
var gook0 []byte
var gook1 []byte
var gook2 []byte
var gook3 []byte
var gook4 []byte
var gook5 []byte
var gook0status bool
var gook1status bool
var gook2status bool
var gook3status bool
var gook4status bool
var gook5status bool
_ = s.server.db.QueryRow("SELECT gook0 FROM gook WHERE id = $1", s.charID).Scan(&gook0)
_ = s.server.db.QueryRow("SELECT gook1 FROM gook WHERE id = $1", s.charID).Scan(&gook1)
_ = s.server.db.QueryRow("SELECT gook2 FROM gook WHERE id = $1", s.charID).Scan(&gook2)
_ = s.server.db.QueryRow("SELECT gook3 FROM gook WHERE id = $1", s.charID).Scan(&gook3)
_ = s.server.db.QueryRow("SELECT gook4 FROM gook WHERE id = $1", s.charID).Scan(&gook4)
_ = s.server.db.QueryRow("SELECT gook5 FROM gook WHERE id = $1", s.charID).Scan(&gook5)
_ = s.server.db.QueryRow("SELECT gook0status FROM gook WHERE id = $1", s.charID).Scan(&gook0status)
_ = s.server.db.QueryRow("SELECT gook1status FROM gook WHERE id = $1", s.charID).Scan(&gook1status)
_ = s.server.db.QueryRow("SELECT gook2status FROM gook WHERE id = $1", s.charID).Scan(&gook2status)
_ = s.server.db.QueryRow("SELECT gook3status FROM gook WHERE id = $1", s.charID).Scan(&gook3status)
_ = s.server.db.QueryRow("SELECT gook4status FROM gook WHERE id = $1", s.charID).Scan(&gook4status)
_ = s.server.db.QueryRow("SELECT gook5status FROM gook WHERE id = $1", s.charID).Scan(&gook5status)
if gook0status == true {
var data []byte
var count uint16
bf := byteframe.NewByteFrame()
for i := 0; i < 5; i++ {
err := s.server.db.QueryRow(fmt.Sprintf("SELECT gook%d FROM gook WHERE id=$1", i), s.charID).Scan(&data)
if err == nil && data != nil {
count++
tempresp.WriteBytes(gook0)
bf.WriteBytes(data)
}
if gook1status == true {
count++
tempresp.WriteBytes(gook1)
}
if gook2status == true {
count++
tempresp.WriteBytes(gook2)
}
if gook3status == true {
count++
tempresp.WriteBytes(gook3)
}
if gook4status == true {
count++
tempresp.WriteBytes(gook4)
}
if gook5status == true {
count++
tempresp.WriteBytes(gook5)
}
if count == uint16(0) {
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
} else {
resp := byteframe.NewByteFrame()
resp.WriteUint16(count)
resp.WriteBytes(tempresp.Data())
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
}
} else {
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
}
resp := byteframe.NewByteFrame()
resp.WriteUint16(count)
resp.WriteBytes(bf.Data())
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
}
func handleMsgMhfUpdateGuacot(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfUpdateGuacot)
count := int(pkt.EntryCount)
fmt.Printf("handleMsgMhfUpdateGuacot:%d\n", count)
if count == 0 {
_, err := s.server.db.Exec("INSERT INTO gook(id,gook0status,gook1status,gook2status,gook3status,gook4status,gook5status) VALUES($1,bool(false),bool(false),bool(false),bool(false),bool(false),bool(false))", s.charID)
if err != nil {
fmt.Printf("INSERT INTO gook failure\n")
}
} else {
for i := 0; i < int(pkt.EntryCount); i++ {
gookindex := int(pkt.Entries[i].Unk0)
buf := pkt.GuacotUpdateEntryToBytes(pkt.Entries[i])
//fmt.Printf("gookindex:%d\n", gookindex)
switch gookindex {
case 0:
s.server.db.Exec("UPDATE gook SET gook0 = $1 WHERE id = $2", buf, s.charID)
if pkt.Entries[i].Unk1 != uint16(0) {
s.server.db.Exec("UPDATE gook SET gook0status = $1 WHERE id = $2", bool(true), s.charID)
} else {
s.server.db.Exec("UPDATE gook SET gook0status = $1 WHERE id = $2", bool(false), s.charID)
}
case 1:
s.server.db.Exec("UPDATE gook SET gook1 = $1 WHERE id = $2", buf, s.charID)
if pkt.Entries[i].Unk1 != uint16(0) {
s.server.db.Exec("UPDATE gook SET gook1status = $1 WHERE id = $2", bool(true), s.charID)
} else {
s.server.db.Exec("UPDATE gook SET gook1status = $1 WHERE id = $2", bool(false), s.charID)
}
case 2:
s.server.db.Exec("UPDATE gook SET gook2 = $1 WHERE id = $2", buf, s.charID)
if pkt.Entries[i].Unk1 != uint16(0) {
s.server.db.Exec("UPDATE gook SET gook2status = $1 WHERE id = $2", bool(true), s.charID)
} else {
s.server.db.Exec("UPDATE gook SET gook2status = $1 WHERE id = $2", bool(false), s.charID)
}
case 3:
s.server.db.Exec("UPDATE gook SET gook3 = $1 WHERE id = $2", buf, s.charID)
if pkt.Entries[i].Unk1 != uint16(0) {
s.server.db.Exec("UPDATE gook SET gook3status = $1 WHERE id = $2", bool(true), s.charID)
} else {
s.server.db.Exec("UPDATE gook SET gook3status = $1 WHERE id = $2", bool(false), s.charID)
}
case 4:
s.server.db.Exec("UPDATE gook SET gook4 = $1 WHERE id = $2", buf, s.charID)
if pkt.Entries[i].Unk1 != uint16(0) {
s.server.db.Exec("UPDATE gook SET gook4status = $1 WHERE id = $2", bool(true), s.charID)
} else {
s.server.db.Exec("UPDATE gook SET gook4status = $1 WHERE id = $2", bool(false), s.charID)
}
for _, gook := range pkt.Gooks {
if !gook.Exists {
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=NULL WHERE id=$1", gook.Index), s.charID)
} else {
// TODO: Birthdays are still 7 years in the past
//var data []byte
//err := s.server.db.QueryRow(fmt.Sprintf("SELECT gook%d FROM gook WHERE id=$1", gook.Index), s.charID).Scan(&data)
//if err != nil && data == nil { // If index doesn't exist
// // Give gook a birthday not 7 years ago
// gook.Birthday1 = uint32(time.Now().Unix())
// gook.Birthday2 = uint32(time.Now().Unix())
//}
bf := byteframe.NewByteFrame()
bf.WriteUint32(gook.Index)
if gook.Index == 0 {
bf.WriteUint16(gook.Type)
}
bf.WriteUint16(gook.Type)
bf.WriteBytes(gook.Data)
bf.WriteUint32(gook.Birthday1)
bf.WriteUint32(gook.Birthday2)
bf.WriteUint8(gook.NameLen)
bf.WriteBytes(gook.Name)
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=$1 WHERE id=$2", gook.Index), bf.Data(), s.charID)
}
}
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})