mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-04 09:15:08 +01:00
implement guild treasure hunting
This commit is contained in:
@@ -145,6 +145,14 @@ func CSVContains(csv string, v int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CSVLength(csv string) int {
|
||||||
|
if csv == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
s := strings.Split(csv, ",")
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
||||||
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
||||||
r := bytes.NewBuffer([]byte(text))
|
r := bytes.NewBuffer([]byte(text))
|
||||||
|
|||||||
@@ -37,4 +37,19 @@ CREATE TABLE IF NOT EXISTS public.guild_meals
|
|||||||
expires int NOT NULL
|
expires int NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.guild_hunts
|
||||||
|
(
|
||||||
|
id serial NOT NULL PRIMARY KEY,
|
||||||
|
guild_id int NOT NULL,
|
||||||
|
host_id int NOT NULL,
|
||||||
|
destination int NOT NULL,
|
||||||
|
level int NOT NULL,
|
||||||
|
return int NOT NULL,
|
||||||
|
acquired bool NOT NULL DEFAULT false,
|
||||||
|
claimed bool NOT NULL DEFAULT false,
|
||||||
|
hunters text NOT NULL DEFAULT '',
|
||||||
|
treasure text NOT NULL DEFAULT '',
|
||||||
|
hunt_data bytea NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
END;
|
END;
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfAcquireGuildTresure represents the MSG_MHF_ACQUIRE_GUILD_TRESURE
|
// MsgMhfAcquireGuildTresure represents the MSG_MHF_ACQUIRE_GUILD_TRESURE
|
||||||
type MsgMhfAcquireGuildTresure struct {
|
type MsgMhfAcquireGuildTresure struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint32
|
HuntID uint32
|
||||||
Unk1 uint8
|
Unk uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -22,10 +22,10 @@ func (m *MsgMhfAcquireGuildTresure) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint32()
|
m.HuntID = bf.ReadUint32()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.Unk = bf.ReadUint8()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfOperateGuildTresureReport represents the MSG_MHF_OPERATE_GUILD_TRESURE_REPORT
|
// MsgMhfOperateGuildTresureReport represents the MSG_MHF_OPERATE_GUILD_TRESURE_REPORT
|
||||||
type MsgMhfOperateGuildTresureReport struct{
|
type MsgMhfOperateGuildTresureReport struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
HuntID uint32
|
HuntID uint32
|
||||||
Unk uint16
|
State uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -22,10 +22,10 @@ func (m *MsgMhfOperateGuildTresureReport) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfOperateGuildTresureReport) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfOperateGuildTresureReport) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.HuntID = bf.ReadUint32()
|
m.HuntID = bf.ReadUint32()
|
||||||
m.Unk = bf.ReadUint16()
|
m.State = bf.ReadUint16()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfRegistGuildTresure represents the MSG_MHF_REGIST_GUILD_TRESURE
|
// MsgMhfRegistGuildTresure represents the MSG_MHF_REGIST_GUILD_TRESURE
|
||||||
type MsgMhfRegistGuildTresure struct {
|
type MsgMhfRegistGuildTresure struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -21,10 +21,10 @@ func (m *MsgMhfRegistGuildTresure) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfRegistGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfRegistGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Data = bf.ReadBytes(uint(bf.ReadUint16()))
|
m.Data = bf.ReadBytes(uint(bf.ReadUint16()))
|
||||||
_ = bf.ReadUint32()
|
_ = bf.ReadUint32()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ func logoutPlayer(s *Session) {
|
|||||||
|
|
||||||
removeSessionFromSemaphore(s)
|
removeSessionFromSemaphore(s)
|
||||||
removeSessionFromStage(s)
|
removeSessionFromStage(s)
|
||||||
|
treasureHuntUnregister(s)
|
||||||
|
|
||||||
saveData, err := GetCharacterSaveData(s, s.charID)
|
saveData, err := GetCharacterSaveData(s, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,25 +1,166 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import "erupe-ce/network/mhfpacket"
|
import (
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
|
"erupe-ce/network/mhfpacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TreasureHunt struct {
|
||||||
|
HuntID uint32 `db:"id"`
|
||||||
|
HostID uint32 `db:"host_id"`
|
||||||
|
Destination uint32 `db:"destination"`
|
||||||
|
Level uint32 `db:"level"`
|
||||||
|
Return uint32 `db:"return"`
|
||||||
|
Acquired bool `db:"acquired"`
|
||||||
|
Claimed bool `db:"claimed"`
|
||||||
|
Hunters string `db:"hunters"`
|
||||||
|
Treasure string `db:"treasure"`
|
||||||
|
HuntData []byte `db:"hunt_data"`
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateGuildTresure)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateGuildTresure)
|
||||||
|
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
hunts := 0
|
||||||
|
rows, _ := s.server.db.Queryx("SELECT id, host_id, destination, level, return, acquired, claimed, hunters, treasure, hunt_data FROM guild_hunts WHERE guild_id=$1", guild.ID)
|
||||||
|
for rows.Next() {
|
||||||
|
hunt := &TreasureHunt{}
|
||||||
|
err = rows.StructScan(&hunt)
|
||||||
|
// Remove self from other hunter count
|
||||||
|
hunt.Hunters = stringsupport.CSVRemove(hunt.Hunters, int(s.charID))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if pkt.MaxHunts == 1 {
|
||||||
|
if hunt.HostID != s.charID || hunt.Acquired {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hunts++
|
||||||
|
bf.WriteUint32(hunt.HuntID)
|
||||||
|
bf.WriteUint32(hunt.Destination)
|
||||||
|
bf.WriteUint32(hunt.Level)
|
||||||
|
bf.WriteUint32(uint32(stringsupport.CSVLength(hunt.Hunters)))
|
||||||
|
bf.WriteUint32(hunt.Return)
|
||||||
|
bf.WriteBool(false)
|
||||||
|
bf.WriteBool(false)
|
||||||
|
bf.WriteBytes(hunt.HuntData)
|
||||||
|
break
|
||||||
|
} else if pkt.MaxHunts == 30 && hunt.Acquired && hunt.Level == 2 {
|
||||||
|
hunts++
|
||||||
|
bf.WriteUint32(hunt.HuntID)
|
||||||
|
bf.WriteUint32(hunt.Destination)
|
||||||
|
bf.WriteUint32(hunt.Level)
|
||||||
|
bf.WriteUint32(uint32(stringsupport.CSVLength(hunt.Hunters)))
|
||||||
|
bf.WriteUint32(hunt.Return)
|
||||||
|
bf.WriteBool(hunt.Claimed)
|
||||||
|
bf.WriteBool(stringsupport.CSVContains(hunt.Treasure, int(s.charID)))
|
||||||
|
bf.WriteBytes(hunt.HuntData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp := byteframe.NewByteFrame()
|
||||||
|
resp.WriteUint16(uint16(hunts))
|
||||||
|
resp.WriteUint16(uint16(hunts))
|
||||||
|
resp.WriteBytes(bf.Data())
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfRegistGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfRegistGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfRegistGuildTresure)
|
pkt := p.(*mhfpacket.MsgMhfRegistGuildTresure)
|
||||||
|
bf := byteframe.NewByteFrameFromBytes(pkt.Data)
|
||||||
|
huntData := byteframe.NewByteFrame()
|
||||||
|
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
guildCats := getGuildAirouList(s)
|
||||||
|
destination := bf.ReadUint32()
|
||||||
|
level := bf.ReadUint32()
|
||||||
|
huntData.WriteUint32(s.charID)
|
||||||
|
huntData.WriteBytes(stringsupport.PaddedString(s.Name, 18, true))
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
catID := bf.ReadUint32()
|
||||||
|
huntData.WriteUint32(catID)
|
||||||
|
if catID > 0 {
|
||||||
|
for _, cat := range guildCats {
|
||||||
|
if cat.CatID == catID {
|
||||||
|
huntData.WriteBytes(cat.CatName)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
huntData.WriteBytes(bf.ReadBytes(9))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = s.server.db.Exec("INSERT INTO guild_hunts (guild_id, host_id, destination, level, return, hunt_data) VALUES ($1, $2, $3, $4, $5, $6)",
|
||||||
|
guild.ID, s.charID, destination, level, Time_Current_Adjusted().Unix(), huntData.Data())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfAcquireGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfAcquireGuildTresure(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfAcquireGuildTresure)
|
pkt := p.(*mhfpacket.MsgMhfAcquireGuildTresure)
|
||||||
|
_, err := s.server.db.Exec("UPDATE guild_hunts SET acquired=true WHERE id=$1", pkt.HuntID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func treasureHuntUnregister(s *Session) {
|
||||||
|
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var huntID int
|
||||||
|
var hunters string
|
||||||
|
rows, _ := s.server.db.Queryx("SELECT id, hunters FROM guild_hunts WHERE guild_id=$1", guild.ID)
|
||||||
|
for rows.Next() {
|
||||||
|
rows.Scan(&huntID, &hunters)
|
||||||
|
hunters = stringsupport.CSVRemove(hunters, int(s.charID))
|
||||||
|
_, err = s.server.db.Exec("UPDATE guild_hunts SET hunters=$1 WHERE id=$2", hunters, huntID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfOperateGuildTresureReport(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfOperateGuildTresureReport(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfOperateGuildTresureReport)
|
pkt := p.(*mhfpacket.MsgMhfOperateGuildTresureReport)
|
||||||
|
var csv string
|
||||||
|
if pkt.State == 0 { // Report registration
|
||||||
|
// Unregister from all other hunts
|
||||||
|
treasureHuntUnregister(s)
|
||||||
|
if pkt.HuntID != 0 {
|
||||||
|
// Register to selected hunt
|
||||||
|
err := s.server.db.QueryRow("SELECT hunters FROM guild_hunts WHERE id=$1", pkt.HuntID).Scan(&csv)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
csv = stringsupport.CSVAdd(csv, int(s.charID))
|
||||||
|
_, err = s.server.db.Exec("UPDATE guild_hunts SET hunters=$1 WHERE id=$2", csv, pkt.HuntID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if pkt.State == 1 { // Collected by hunter
|
||||||
|
s.server.db.Exec("UPDATE guild_hunts SET hunters='', claimed=true WHERE id=$1", pkt.HuntID)
|
||||||
|
} else if pkt.State == 2 { // Claim treasure
|
||||||
|
err := s.server.db.QueryRow("SELECT treasure FROM guild_hunts WHERE id=$1", pkt.HuntID).Scan(&csv)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
csv = stringsupport.CSVAdd(csv, int(s.charID))
|
||||||
|
_, err = s.server.db.Exec("UPDATE guild_hunts SET treasure=$1 WHERE id=$2", csv, pkt.HuntID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user