mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 07:25:03 +01:00
implement persistent house data
This commit is contained in:
@@ -94,6 +94,9 @@ func (save *CharacterSaveData) Save(s *Session) {
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update savedata", zap.Error(err), zap.Uint32("charID", save.CharID))
|
||||
}
|
||||
|
||||
s.server.db.Exec(`UPDATE user_binary SET house_tier=$1, house_data=$2, bookshelf=$3, gallery=$4, tore=$5, garden=$6 WHERE id=$7
|
||||
`, save.HouseTier, save.HouseData, save.BookshelfData, save.GalleryData, save.ToreData, save.GardenData, s.charID)
|
||||
}
|
||||
|
||||
func (save *CharacterSaveData) Compress() error {
|
||||
|
||||
@@ -38,24 +38,26 @@ 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)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.server.db.Exec(`UPDATE user_binary SET house_furniture=$1 WHERE id=$2`, pkt.InteriorData, s.charID)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
type HouseData struct {
|
||||
CharID uint32 `db:"id"`
|
||||
HRP uint16 `db:"hrp"`
|
||||
GR uint16 `db:"gr"`
|
||||
Name string `db:"name"`
|
||||
CharID uint32 `db:"id"`
|
||||
HRP uint16 `db:"hrp"`
|
||||
GR uint16 `db:"gr"`
|
||||
Name string `db:"name"`
|
||||
HouseState uint8 `db:"house_state"`
|
||||
HousePassword string `db:"house_password"`
|
||||
}
|
||||
|
||||
func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfEnumerateHouse)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint16(0)
|
||||
var houses []HouseData
|
||||
houseQuery := `SELECT c.id, hrp, gr, name, COALESCE(ub.house_state, 2) as house_state, COALESCE(ub.house_password, '') as house_password
|
||||
FROM characters c LEFT JOIN user_binary ub ON ub.id = c.id WHERE c.id=$1`
|
||||
switch pkt.Method {
|
||||
case 1:
|
||||
var friendsList string
|
||||
@@ -63,17 +65,15 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
cids := stringsupport.CSVElems(friendsList)
|
||||
for _, cid := range cids {
|
||||
house := HouseData{}
|
||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", cid)
|
||||
row := s.server.db.QueryRowx(houseQuery, cid)
|
||||
err := row.StructScan(&house)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
if err == nil {
|
||||
houses = append(houses, house)
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||
if err != nil {
|
||||
if err != nil || guild == nil {
|
||||
break
|
||||
}
|
||||
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
||||
@@ -82,58 +82,48 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
for _, member := range guildMembers {
|
||||
house := HouseData{}
|
||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", member.CharID)
|
||||
err := row.StructScan(&house)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
row := s.server.db.QueryRowx(houseQuery, member.CharID)
|
||||
err = row.StructScan(&house)
|
||||
if err == nil {
|
||||
houses = append(houses, house)
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
houseQuery = `SELECT c.id, hrp, gr, name, COALESCE(ub.house_state, 2) as house_state, COALESCE(ub.house_password, '') as house_password
|
||||
FROM characters c LEFT JOIN user_binary ub ON ub.id = c.id WHERE name ILIKE $1`
|
||||
house := HouseData{}
|
||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE name ILIKE $1", fmt.Sprintf(`%%%s%%`, pkt.Name))
|
||||
err := row.StructScan(&house)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
houses = append(houses, house)
|
||||
rows, _ := s.server.db.Queryx(houseQuery, fmt.Sprintf(`%%%s%%`, pkt.Name))
|
||||
for rows.Next() {
|
||||
err := rows.StructScan(&house)
|
||||
if err == nil {
|
||||
houses = append(houses, house)
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
house := HouseData{}
|
||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", pkt.CharID)
|
||||
row := s.server.db.QueryRowx(houseQuery, pkt.CharID)
|
||||
err := row.StructScan(&house)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
if err == nil {
|
||||
houses = append(houses, house)
|
||||
}
|
||||
case 5: // Recent visitors
|
||||
break
|
||||
}
|
||||
var exists int
|
||||
for _, house := range houses {
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == house.CharID {
|
||||
exists++
|
||||
bf.WriteUint32(house.CharID)
|
||||
bf.WriteUint8(session.myseries.state)
|
||||
if len(session.myseries.password) > 0 {
|
||||
bf.WriteUint8(3)
|
||||
} else {
|
||||
bf.WriteUint8(0)
|
||||
}
|
||||
bf.WriteUint16(house.HRP)
|
||||
bf.WriteUint16(house.GR)
|
||||
ps.Uint8(bf, house.Name, true)
|
||||
break
|
||||
}
|
||||
bf.WriteUint32(house.CharID)
|
||||
bf.WriteUint8(house.HouseState)
|
||||
if len(house.HousePassword) > 0 {
|
||||
bf.WriteUint8(3)
|
||||
} else {
|
||||
bf.WriteUint8(0)
|
||||
}
|
||||
bf.WriteUint16(house.HRP)
|
||||
bf.WriteUint16(house.GR)
|
||||
ps.Uint8(bf, house.Name, true)
|
||||
}
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint16(uint16(exists))
|
||||
resp.WriteBytes(bf.Data())
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
bf.Seek(0, 0)
|
||||
bf.WriteUint16(uint16(len(houses)))
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfUpdateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
@@ -143,8 +133,7 @@ func handleMsgMhfUpdateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
// 03 = open friends
|
||||
// 04 = open guild
|
||||
// 05 = open friends+guild
|
||||
s.myseries.state = pkt.State
|
||||
s.myseries.password = pkt.Password
|
||||
s.server.db.Exec(`UPDATE user_binary SET house_state=$1, house_password=$2 WHERE id=$3`, pkt.State, pkt.Password, s.charID)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
@@ -152,63 +141,41 @@ func handleMsgMhfLoadHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfLoadHouse)
|
||||
bf := byteframe.NewByteFrame()
|
||||
if pkt.Destination != 9 && len(pkt.Password) > 0 && pkt.CheckPass {
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID && pkt.Password != session.myseries.password {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
var password string
|
||||
s.server.db.Select(&password, `SELECT house_password FROM user_binary WHERE id=$1`, pkt.CharID)
|
||||
if pkt.Password != password {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var furniture []byte
|
||||
err := s.server.db.QueryRow("SELECT house FROM characters WHERE id=$1", pkt.CharID).Scan(&furniture)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if furniture == nil {
|
||||
furniture = make([]byte, 20)
|
||||
var houseTier, houseData, houseFurniture, bookshelf, gallery, tore, garden []byte
|
||||
s.server.db.QueryRow(`SELECT house_tier, house_data, house_furniture, bookshelf, gallery, tore, garden FROM user_binary WHERE id=$1
|
||||
`, pkt.CharID).Scan(&houseTier, &houseData, &houseFurniture, &bookshelf, &gallery, &tore, &garden)
|
||||
if houseFurniture == nil {
|
||||
houseFurniture = make([]byte, 20)
|
||||
}
|
||||
|
||||
switch pkt.Destination {
|
||||
case 3: // Others house
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID {
|
||||
bf.WriteBytes(session.myseries.houseTier)
|
||||
bf.WriteBytes(session.myseries.houseData)
|
||||
bf.WriteBytes(make([]byte, 19)) // Padding?
|
||||
bf.WriteBytes(furniture)
|
||||
}
|
||||
}
|
||||
bf.WriteBytes(houseTier)
|
||||
bf.WriteBytes(houseData)
|
||||
bf.WriteBytes(make([]byte, 19)) // Padding?
|
||||
bf.WriteBytes(houseFurniture)
|
||||
case 4: // Bookshelf
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID {
|
||||
bf.WriteBytes(session.myseries.bookshelfData)
|
||||
}
|
||||
}
|
||||
bf.WriteBytes(bookshelf)
|
||||
case 5: // Gallery
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID {
|
||||
bf.WriteBytes(session.myseries.galleryData)
|
||||
}
|
||||
}
|
||||
bf.WriteBytes(gallery)
|
||||
case 8: // Tore
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID {
|
||||
bf.WriteBytes(session.myseries.toreData)
|
||||
}
|
||||
}
|
||||
bf.WriteBytes(tore)
|
||||
case 9: // Own house
|
||||
bf.WriteBytes(furniture)
|
||||
bf.WriteBytes(houseFurniture)
|
||||
case 10: // Garden
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == pkt.CharID {
|
||||
bf.WriteBytes(session.myseries.gardenData)
|
||||
c, d := getGookData(s, pkt.CharID)
|
||||
bf.WriteUint16(c)
|
||||
bf.WriteUint16(0)
|
||||
bf.WriteBytes(d)
|
||||
}
|
||||
}
|
||||
bf.WriteBytes(garden)
|
||||
c, d := getGookData(s, pkt.CharID)
|
||||
bf.WriteUint16(c)
|
||||
bf.WriteUint16(0)
|
||||
bf.WriteBytes(d)
|
||||
}
|
||||
if len(bf.Data()) == 0 {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
|
||||
@@ -17,12 +17,12 @@ func handleMsgSysSetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.server.userBinaryPartsLock.Unlock()
|
||||
|
||||
var exists []byte
|
||||
err := s.server.db.QueryRow("SELECT type2 FROM user_binaries WHERE id=$1", s.charID).Scan(&exists)
|
||||
err := s.server.db.QueryRow("SELECT type2 FROM user_binary WHERE id=$1", s.charID).Scan(&exists)
|
||||
if err != nil {
|
||||
s.server.db.Exec("INSERT INTO user_binaries (id) VALUES ($1)", s.charID)
|
||||
s.server.db.Exec("INSERT INTO user_binary (id) VALUES ($1)", s.charID)
|
||||
}
|
||||
|
||||
s.server.db.Exec(fmt.Sprintf("UPDATE user_binaries SET type%d=$1 WHERE id=$2", pkt.BinaryType), pkt.RawDataPayload, s.charID)
|
||||
s.server.db.Exec(fmt.Sprintf("UPDATE user_binary SET type%d=$1 WHERE id=$2", pkt.BinaryType), pkt.RawDataPayload, s.charID)
|
||||
|
||||
msg := &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: s.charID,
|
||||
@@ -42,7 +42,7 @@ func handleMsgSysGetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
// If we can't get the real data, try to get it from the database.
|
||||
if !ok {
|
||||
err := s.server.db.QueryRow(fmt.Sprintf("SELECT type%d FROM user_binaries WHERE id=$1", pkt.BinaryType), pkt.CharID).Scan(&data)
|
||||
err := s.server.db.QueryRow(fmt.Sprintf("SELECT type%d FROM user_binary WHERE id=$1", pkt.BinaryType), pkt.CharID).Scan(&data)
|
||||
if err != nil {
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user