partial Tenrouirai automation and Gem fix

This commit is contained in:
wish
2023-06-25 00:11:47 +10:00
parent b60bf4979b
commit 4a21272c42
3 changed files with 191 additions and 89 deletions

View File

@@ -12,15 +12,23 @@ import (
type MsgMhfPostTenrouirai struct { type MsgMhfPostTenrouirai struct {
AckHandle uint32 AckHandle uint32
Unk0 uint8 Unk0 uint8
Unk1 uint8 Op uint8
GuildID uint32 GuildID uint32
Unk3 uint8 Unk1 uint8
Floors uint16 Floors uint16
Antiques uint16 Antiques uint16
Chests uint16 Chests uint16
Cats uint16 Cats uint16
TRP uint16 TRP uint16
Slays uint16 Slays uint16
DonatedRP uint16
PreviousRP uint16
Unk2_0 uint16
Unk2_1 uint16
Unk2_2 uint16
Unk2_3 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,15 +40,27 @@ func (m *MsgMhfPostTenrouirai) Opcode() network.PacketID {
func (m *MsgMhfPostTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfPostTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint8() m.Op = bf.ReadUint8()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.Unk3 = bf.ReadUint8() m.Unk1 = bf.ReadUint8()
switch m.Op {
case 1:
m.Floors = bf.ReadUint16() m.Floors = bf.ReadUint16()
m.Antiques = bf.ReadUint16() m.Antiques = bf.ReadUint16()
m.Chests = bf.ReadUint16() m.Chests = bf.ReadUint16()
m.Cats = bf.ReadUint16() m.Cats = bf.ReadUint16()
m.TRP = bf.ReadUint16() m.TRP = bf.ReadUint16()
m.Slays = bf.ReadUint16() m.Slays = bf.ReadUint16()
case 2:
m.DonatedRP = bf.ReadUint16()
m.PreviousRP = bf.ReadUint16()
m.Unk2_0 = bf.ReadUint16()
m.Unk2_1 = bf.ReadUint16()
m.Unk2_2 = bf.ReadUint16()
m.Unk2_3 = bf.ReadUint16()
}
return nil return nil
} }

View File

@@ -8,7 +8,22 @@ CREATE TABLE IF NOT EXISTS tower (
block1 INT, block1 INT,
block2 INT, block2 INT,
skills TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0', skills TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0',
gems TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' gems TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0'
); );
ALTER TABLE IF EXISTS guild_characters
ADD COLUMN IF NOT EXISTS tower_mission_1 INT;
ALTER TABLE IF EXISTS guild_characters
ADD COLUMN IF NOT EXISTS tower_mission_2 INT;
ALTER TABLE IF EXISTS guild_characters
ADD COLUMN IF NOT EXISTS tower_mission_3 INT;
ALTER TABLE IF EXISTS guilds
ADD COLUMN IF NOT EXISTS tower_mission_page INT DEFAULT 1;
ALTER TABLE IF EXISTS guilds
ADD COLUMN IF NOT EXISTS tower_rp INT DEFAULT 0;
END; END;

View File

@@ -1,6 +1,7 @@
package channelserver package channelserver
import ( import (
"fmt"
"go.uber.org/zap" "go.uber.org/zap"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
@@ -130,59 +131,8 @@ func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) {
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
type TenrouiraiCharScore struct { // Default missions
Score int32 var tenrouiraiData = []TenrouiraiData{
Name string
}
type TenrouiraiProgress struct {
Completed uint8
Mission1 uint16
Mission2 uint16
Mission3 uint16
}
type TenrouiraiTicket struct {
Unk0 uint8
Unk1 uint32
Unk2 uint32
}
type TenrouiraiData struct {
Block uint8
Mission uint8
// 1 = Floors climbed
// 2 = Collect antiques
// 3 = Open chests
// 4 = Cats saved
// 5 = TRP acquisition
// 6 = Monster slays
Goal uint16
Unk3 uint16
Unk4 uint8
Unk5 uint8
Unk6 uint8
Unk7 uint8
Unk8 uint8
Unk9 uint8
}
type Tenrouirai struct {
CharScore []TenrouiraiCharScore
Progress []TenrouiraiProgress
Ticket []TenrouiraiTicket
Data []TenrouiraiData
}
func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetTenrouirai)
var data []*byteframe.ByteFrame
tenrouirai := Tenrouirai{
Progress: []TenrouiraiProgress{
{1, 0, 0, 0},
},
Data: []TenrouiraiData{
{1, 1, 80, 0, 2, 2, 1, 1, 2, 2}, {1, 1, 80, 0, 2, 2, 1, 1, 2, 2},
{1, 4, 16, 0, 2, 2, 1, 1, 2, 2}, {1, 4, 16, 0, 2, 2, 1, 1, 2, 2},
{1, 6, 50, 0, 2, 2, 1, 0, 2, 2}, {1, 6, 50, 0, 2, 2, 1, 0, 2, 2},
@@ -216,7 +166,73 @@ func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
{1, 1, 80, 50, 3, 1, 0, 0, 1, 1}, {1, 1, 80, 50, 3, 1, 0, 0, 1, 1},
{2, 5, 40000, 0, 3, 1, 0, 0, 1, 1}, {2, 5, 40000, 0, 3, 1, 0, 0, 1, 1},
{2, 6, 40, 0, 3, 1, 0, 0, 1, 1}, {2, 6, 40, 0, 3, 1, 0, 0, 1, 1},
}, }
type TenrouiraiProgress struct {
Page uint8
Mission1 uint16
Mission2 uint16
Mission3 uint16
}
type TenrouiraiReward struct {
Index uint8
Item []uint16 // 5
Quantity []uint8 // 5
}
type TenrouiraiKeyScore struct {
Unk0 uint8
Unk1 int32
}
type TenrouiraiData struct {
Block uint8
Mission uint8
// 1 = Floors climbed
// 2 = Collect antiques
// 3 = Open chests
// 4 = Cats saved
// 5 = TRP acquisition
// 6 = Monster slays
Goal uint16
Cost uint16
Skill1 uint8 // 80
Skill2 uint8 // 40
Skill3 uint8 // 40
Skill4 uint8 // 20
Skill5 uint8 // 40
Skill6 uint8 // 50
}
type TenrouiraiCharScore struct {
Score int32
Name string
}
type TenrouiraiTicket struct {
Unk0 uint8
RP uint32
Unk2 uint32
}
type Tenrouirai struct {
Progress []TenrouiraiProgress
Reward []TenrouiraiReward
KeyScore []TenrouiraiKeyScore
Data []TenrouiraiData
CharScore []TenrouiraiCharScore
Ticket []TenrouiraiTicket
}
func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetTenrouirai)
var data []*byteframe.ByteFrame
tenrouirai := Tenrouirai{
Progress: []TenrouiraiProgress{{1, 0, 0, 0}},
Data: tenrouiraiData,
Ticket: []TenrouiraiTicket{{0, 0, 0}},
} }
switch pkt.Unk1 { switch pkt.Unk1 {
@@ -226,24 +242,75 @@ func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint8(tdata.Block) bf.WriteUint8(tdata.Block)
bf.WriteUint8(tdata.Mission) bf.WriteUint8(tdata.Mission)
bf.WriteUint16(tdata.Goal) bf.WriteUint16(tdata.Goal)
bf.WriteUint16(tdata.Unk3) bf.WriteUint16(tdata.Cost)
bf.WriteUint8(tdata.Unk4) bf.WriteUint8(tdata.Skill1)
bf.WriteUint8(tdata.Unk5) bf.WriteUint8(tdata.Skill2)
bf.WriteUint8(tdata.Unk6) bf.WriteUint8(tdata.Skill3)
bf.WriteUint8(tdata.Unk7) bf.WriteUint8(tdata.Skill4)
bf.WriteUint8(tdata.Unk8) bf.WriteUint8(tdata.Skill5)
bf.WriteUint8(tdata.Unk9) bf.WriteUint8(tdata.Skill6)
data = append(data, bf)
}
case 2:
for _, reward := range tenrouirai.Reward {
bf := byteframe.NewByteFrame()
bf.WriteUint8(reward.Index)
bf.WriteUint16(reward.Item[0])
bf.WriteUint16(reward.Item[1])
bf.WriteUint16(reward.Item[2])
bf.WriteUint16(reward.Item[3])
bf.WriteUint16(reward.Item[4])
bf.WriteUint8(reward.Quantity[0])
bf.WriteUint8(reward.Quantity[1])
bf.WriteUint8(reward.Quantity[2])
bf.WriteUint8(reward.Quantity[3])
bf.WriteUint8(reward.Quantity[4])
data = append(data, bf) data = append(data, bf)
} }
case 4: case 4:
s.server.db.QueryRow(`SELECT tower_mission_page FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&tenrouirai.Progress[0].Page)
s.server.db.QueryRow(`SELECT SUM(tower_mission_1) AS _, SUM(tower_mission_2) AS _, SUM(tower_mission_3) AS _ FROM guild_characters WHERE guild_id=$1
`, pkt.GuildID).Scan(&tenrouirai.Progress[0].Mission1, &tenrouirai.Progress[0].Mission2, &tenrouirai.Progress[0].Mission3)
if tenrouirai.Progress[0].Mission1 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal {
tenrouirai.Progress[0].Mission1 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal
}
if tenrouirai.Progress[0].Mission2 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal {
tenrouirai.Progress[0].Mission2 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal
}
if tenrouirai.Progress[0].Mission1 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal {
tenrouirai.Progress[0].Mission1 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal
}
for _, progress := range tenrouirai.Progress { for _, progress := range tenrouirai.Progress {
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint8(progress.Completed) bf.WriteUint8(progress.Page)
bf.WriteUint16(progress.Mission1) bf.WriteUint16(progress.Mission1)
bf.WriteUint16(progress.Mission2) bf.WriteUint16(progress.Mission2)
bf.WriteUint16(progress.Mission3) bf.WriteUint16(progress.Mission3)
data = append(data, bf) data = append(data, bf)
} }
case 5:
rows, _ := s.server.db.Query(fmt.Sprintf(`SELECT name, tower_mission_%d FROM guild_characters gc INNER JOIN characters c on gc.character_id = c.id WHERE guild_id=$1 AND tower_mission_%d IS NOT NULL`, pkt.Unk3, pkt.Unk3), pkt.GuildID)
for rows.Next() {
temp := TenrouiraiCharScore{}
rows.Scan(&temp.Name, &temp.Score)
tenrouirai.CharScore = append(tenrouirai.CharScore, temp)
}
for _, charScore := range tenrouirai.CharScore {
bf := byteframe.NewByteFrame()
bf.WriteInt32(charScore.Score)
bf.WriteBytes(stringsupport.PaddedString(charScore.Name, 14, true))
data = append(data, bf)
}
case 6:
for _, ticket := range tenrouirai.Ticket {
bf := byteframe.NewByteFrame()
bf.WriteUint8(ticket.Unk0)
bf.WriteUint32(ticket.RP)
bf.WriteUint32(ticket.Unk2)
data = append(data, bf)
}
} }
doAckEarthSucceed(s, pkt.AckHandle, data) doAckEarthSucceed(s, pkt.AckHandle, data)
@@ -256,9 +323,9 @@ func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) {
s.logger.Debug( s.logger.Debug(
p.Opcode().String(), p.Opcode().String(),
zap.Uint8("Unk0", pkt.Unk0), zap.Uint8("Unk0", pkt.Unk0),
zap.Uint8("Unk1", pkt.Unk1), zap.Uint8("Op", pkt.Op),
zap.Uint32("GuildID", pkt.GuildID), zap.Uint32("GuildID", pkt.GuildID),
zap.Uint8("Unk3", pkt.Unk3), zap.Uint8("Unk1", pkt.Unk1),
zap.Uint16("Floors", pkt.Floors), zap.Uint16("Floors", pkt.Floors),
zap.Uint16("Antiques", pkt.Antiques), zap.Uint16("Antiques", pkt.Antiques),
zap.Uint16("Chests", pkt.Chests), zap.Uint16("Chests", pkt.Chests),
@@ -308,10 +375,10 @@ func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) {
gemInfo := []GemInfo{} gemInfo := []GemInfo{}
gemHistory := []GemHistory{} gemHistory := []GemHistory{}
tempGems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" tempGems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&tempGems) s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&tempGems)
for i, v := range stringsupport.CSVElems(tempGems) { for i, v := range stringsupport.CSVElems(tempGems) {
gemInfo = append(gemInfo, GemInfo{uint16(((i / 3) * 256) + ((i % 3) + 1)), uint16(v)}) gemInfo = append(gemInfo, GemInfo{uint16(((i / 5) * 256) + ((i % 5) + 1)), uint16(v)})
} }
switch pkt.Unk0 { switch pkt.Unk0 {
@@ -351,11 +418,11 @@ func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {
) )
} }
gems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" gems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&gems) s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&gems)
switch pkt.Op { switch pkt.Op {
case 1: // Add gem case 1: // Add gem
i := int(((pkt.Gem / 256) * 3) + (((pkt.Gem - ((pkt.Gem / 256) * 256)) - 1) % 3)) i := int(((pkt.Gem / 256) * 5) + (((pkt.Gem - ((pkt.Gem / 256) * 256)) - 1) % 5))
s.server.db.Exec(`UPDATE tower SET gems=$1 WHERE char_id=$2`, stringsupport.CSVSetIndex(gems, i, stringsupport.CSVGetIndex(gems, i)+int(pkt.Quantity)), s.charID) s.server.db.Exec(`UPDATE tower SET gems=$1 WHERE char_id=$2`, stringsupport.CSVSetIndex(gems, i, stringsupport.CSVGetIndex(gems, i)+int(pkt.Quantity)), s.charID)
case 2: // Transfer gem case 2: // Transfer gem
// no way im doing this for now // no way im doing this for now