Init Conquest

This commit is contained in:
stratic-dev
2024-07-31 18:13:40 +01:00
parent 2d0cce719b
commit ed5489571b
7 changed files with 192 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ package mhfpacket
import ( import (
"errors" "errors"
"fmt"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
@@ -10,9 +11,9 @@ import (
// MsgMhfGetBreakSeibatuLevelReward represents the MSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARD // MsgMhfGetBreakSeibatuLevelReward represents the MSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARD
type MsgMhfGetBreakSeibatuLevelReward struct { type MsgMhfGetBreakSeibatuLevelReward struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 Unk0 uint32
Unk1 int32 EarthMonster int32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +25,8 @@ func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID {
func (m *MsgMhfGetBreakSeibatuLevelReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfGetBreakSeibatuLevelReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadInt32() m.EarthMonster = bf.ReadInt32()
fmt.Printf("MsgMhfGetBreakSeibatuLevelReward: Unk0:[%d] EarthMonster:[%d] \n\n", m.Unk0, m.EarthMonster)
return nil return nil
} }

View File

@@ -2,6 +2,7 @@ package mhfpacket
import ( import (
"errors" "errors"
"fmt"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
@@ -10,12 +11,12 @@ import (
// MsgMhfGetFixedSeibatuRankingTable represents the MSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLE // MsgMhfGetFixedSeibatuRankingTable represents the MSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLE
type MsgMhfGetFixedSeibatuRankingTable struct { type MsgMhfGetFixedSeibatuRankingTable struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 Unk0 uint32
Unk1 int32 Unk1 int32
Unk2 int32 EarthMonster int32
Unk3 int32 Unk3 int32
Unk4 int32 Unk4 int32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -28,9 +29,10 @@ func (m *MsgMhfGetFixedSeibatuRankingTable) Parse(bf *byteframe.ByteFrame, ctx *
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadInt32() m.Unk1 = bf.ReadInt32()
m.Unk2 = bf.ReadInt32() m.EarthMonster = bf.ReadInt32()
m.Unk3 = bf.ReadInt32() m.Unk3 = bf.ReadInt32()
m.Unk4 = bf.ReadInt32() m.Unk4 = bf.ReadInt32()
fmt.Printf("MsgMhfGetFixedSeibatuRankingTable: Unk0:[%d] Unk1:[%d] EarthMonster:[%d] Unk3:[%d] Unk4:[%d]\n\n", m.Unk0, m.Unk1, m.EarthMonster, m.Unk3, m.Unk4)
return nil return nil
} }

View File

@@ -12,7 +12,7 @@ import (
type MsgMhfReadBeatLevelAllRanking struct { type MsgMhfReadBeatLevelAllRanking struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 Unk0 uint32
GuildID int32 MonsterID int32
Unk2 int32 Unk2 int32
} }
@@ -25,7 +25,7 @@ func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID {
func (m *MsgMhfReadBeatLevelAllRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReadBeatLevelAllRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.GuildID = bf.ReadInt32() m.MonsterID = bf.ReadInt32()
m.Unk2 = bf.ReadInt32() m.Unk2 = bf.ReadInt32()
return nil return nil
} }

View File

@@ -2,6 +2,7 @@ package mhfpacket
import ( import (
"errors" "errors"
"fmt"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
@@ -10,9 +11,9 @@ import (
// MsgMhfReadLastWeekBeatRanking represents the MSG_MHF_READ_LAST_WEEK_BEAT_RANKING // MsgMhfReadLastWeekBeatRanking represents the MSG_MHF_READ_LAST_WEEK_BEAT_RANKING
type MsgMhfReadLastWeekBeatRanking struct { type MsgMhfReadLastWeekBeatRanking struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 Unk0 uint32
Unk1 int32 EarthMonster int32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +25,9 @@ func (m *MsgMhfReadLastWeekBeatRanking) Opcode() network.PacketID {
func (m *MsgMhfReadLastWeekBeatRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReadLastWeekBeatRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadInt32() m.EarthMonster = bf.ReadInt32()
fmt.Printf("MsgMhfGetFixedSeibatuRankingTable: Unk0:[%d] EarthMonster:[%d] \n\n", m.Unk0, m.EarthMonster)
return nil return nil
} }

View File

@@ -0,0 +1,5 @@
BEGIN;
ALTER TABLE public.characters ADD COLUMN IF NOT EXISTS conquest_data BYTEA;
END;

View File

@@ -60,6 +60,7 @@ func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) {
} }
func cleanupEarthStatus(s *Session) { func cleanupEarthStatus(s *Session) {
s.server.db.Exec(`DELETE FROM events WHERE event_type='earth'`) s.server.db.Exec(`DELETE FROM events WHERE event_type='earth'`)
s.server.db.Exec(`UPDATE characters SET conquest_data=NULL`)
} }
func generateEarthStatusTimestamps(s *Session, start uint32, debug bool) []uint32 { func generateEarthStatusTimestamps(s *Session, start uint32, debug bool) []uint32 {

View File

@@ -2,17 +2,74 @@ package channelserver
import ( import (
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/stringsupport"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
) )
type BreakSeibatuLevelReward struct {
Item int32
Quantity int32
Level int32
Unk int32
}
func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetBreakSeibatuLevelReward) pkt := p.(*mhfpacket.MsgMhfGetBreakSeibatuLevelReward)
bf := byteframe.NewByteFrame() var data []*byteframe.ByteFrame
bf.WriteInt32(0) var weeklySeibatuRankingRewards []BreakSeibatuLevelReward
bf.WriteInt32(0)
bf.WriteInt32(0) switch pkt.EarthMonster {
bf.WriteInt32(0) case 116:
doAckBufSucceed(s, pkt.AckHandle, bf.Data()) weeklySeibatuRankingRewards = []BreakSeibatuLevelReward{
{8, 3, 2, 0},
{8, 3, 2, 0},
{8, 3, 2, 0},
{8, 3, 3, 0},
{8, 3, 3, 0},
{8, 3, 3, 0},
{8, 3, 3, 0}}
case 107:
weeklySeibatuRankingRewards = []BreakSeibatuLevelReward{
{4, 3, 1, 0},
{4, 3, 2, 0},
{4, 3, 3, 0},
{4, 3, 4, 0},
{4, 3, 5, 0}}
case 2:
weeklySeibatuRankingRewards = []BreakSeibatuLevelReward{
{5, 3, 1, 0},
{5, 3, 2, 0},
{5, 3, 3, 0},
{5, 3, 4, 0},
{5, 3, 5, 0}}
case 36:
weeklySeibatuRankingRewards = []BreakSeibatuLevelReward{
{7, 3, 1, 0},
{7, 3, 2, 0},
{7, 3, 3, 0},
{7, 3, 4, 0},
{7, 3, 5, 0}}
default:
weeklySeibatuRankingRewards = []BreakSeibatuLevelReward{
{1, 3, 1, 0},
{1, 3, 2, 0},
{1, 3, 3, 0},
{1, 3, 4, 0},
{1, 3, 5, 0}}
}
for _, seibatuData := range weeklySeibatuRankingRewards {
bf := byteframe.NewByteFrame()
bf.WriteInt32(seibatuData.Item)
bf.WriteInt32(seibatuData.Quantity)
bf.WriteInt32(seibatuData.Level)
bf.WriteInt32(seibatuData.Unk)
data = append(data, bf)
}
doAckEarthSucceed(s, pkt.AckHandle, data)
} }
type WeeklySeibatuRankingRewardData struct { type WeeklySeibatuRankingRewardData struct {
@@ -558,44 +615,128 @@ func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket
doAckEarthSucceed(s, pkt.AckHandle, data) doAckEarthSucceed(s, pkt.AckHandle, data)
} }
type FixedSeibatuRankingTable struct {
Rank int32
Level int32
Name string
}
func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetFixedSeibatuRankingTable) pkt := p.(*mhfpacket.MsgMhfGetFixedSeibatuRankingTable)
var fixedSeibatuRankingTable []FixedSeibatuRankingTable
//Interestingly doesn't trigger the pkt on EarthStatus 1 But menu option is there is this Seibatu instead?
switch pkt.EarthMonster {
case 116:
fixedSeibatuRankingTable = []FixedSeibatuRankingTable{
{1, 1, "Hunter 1"},
{2, 1, "Hunter 2"},
{3, 1, "Hunter 3"},
{4, 1, "Hunter 4"},
{5, 1, "Hunter 5"},
{6, 1, "Hunter 6"},
{7, 1, "Hunter 7"},
{8, 1, "Hunter 8"},
{9, 1, "Hunter 9"},
}
case 107:
fixedSeibatuRankingTable = []FixedSeibatuRankingTable{
{1, 2, "Hunter 1"},
{2, 2, "Hunter 2"},
{3, 2, "Hunter 3"},
{4, 2, "Hunter 4"},
{5, 2, "Hunter 5"},
{6, 2, "Hunter 6"},
{7, 2, "Hunter 7"},
{8, 2, "Hunter 8"},
{9, 2, "Hunter 9"},
}
case 2:
fixedSeibatuRankingTable = []FixedSeibatuRankingTable{
{1, 3, "Hunter 1"},
{2, 3, "Hunter 2"},
{3, 3, "Hunter 3"},
{4, 3, "Hunter 4"},
{5, 3, "Hunter 5"},
{6, 3, "Hunter 6"},
{7, 3, "Hunter 7"},
{8, 3, "Hunter 8"},
{9, 3, "Hunter 9"},
}
case 36:
fixedSeibatuRankingTable = []FixedSeibatuRankingTable{
{1, 4, "Hunter 1"},
{2, 4, "Hunter 2"},
{3, 4, "Hunter 3"},
{4, 4, "Hunter 4"},
{5, 4, "Hunter 5"},
{6, 4, "Hunter 6"},
{7, 4, "Hunter 7"},
{8, 4, "Hunter 8"},
{9, 4, "Hunter 9"},
}
default:
fixedSeibatuRankingTable = []FixedSeibatuRankingTable{
{1, 1, "Hunter 1"},
{2, 1, "Hunter 2"},
{3, 1, "Hunter 3"},
{4, 1, "Hunter 4"},
{5, 1, "Hunter 5"},
{6, 1, "Hunter 6"},
{7, 1, "Hunter 7"},
{8, 1, "Hunter 8"},
{9, 1, "Hunter 9"},
}
}
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteInt32(0) for _, seibatuData := range fixedSeibatuRankingTable {
bf.WriteInt32(0) bf.WriteInt32(seibatuData.Rank)
bf.WriteBytes(make([]byte, 32)) bf.WriteInt32(seibatuData.Level)
bf.WriteBytes(stringsupport.PaddedString(seibatuData.Name, 32, true))
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data()) doAckBufSucceed(s, pkt.AckHandle, bf.Data())
} }
func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfReadBeatLevel) pkt := p.(*mhfpacket.MsgMhfReadBeatLevel)
// This response is fixed and will never change on JP, var data []byte
// but I've left it dynamic for possible other client differences. err := s.server.db.QueryRow(`SELECT conquest_data FROM characters WHERE id = $1`, s.charID).Scan(&data)
if err != nil || len(data) == 0 {
data = []byte{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1}
}
bf := byteframe.NewByteFrameFromBytes(data)
resp := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
for i := 0; i < int(pkt.ValidIDCount); i++ { for i := 0; i < int(pkt.ValidIDCount); i++ {
resp.WriteUint32(pkt.IDs[i]) resp.WriteUint32(pkt.IDs[i])
resp.WriteUint32(1) resp.WriteUint32(bf.ReadUint32())
resp.WriteUint32(1) resp.WriteUint32(0)
resp.WriteUint32(1) resp.WriteUint32(0)
} }
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) {
//Controls the monster headings for the other menus
pkt := p.(*mhfpacket.MsgMhfReadLastWeekBeatRanking) pkt := p.(*mhfpacket.MsgMhfReadLastWeekBeatRanking)
bf := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
bf.WriteInt32(0) resp.WriteUint32(uint32(pkt.EarthMonster))
bf.WriteInt32(0) resp.WriteUint32(0)
bf.WriteInt32(0) resp.WriteUint32(0)
bf.WriteInt32(0) resp.WriteUint32(0)
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel) pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel)
bf := byteframe.NewByteFrame()
for i := 0; i < 4; i++ {
bf.WriteInt32(pkt.Data2[i])
}
s.server.db.Exec(`UPDATE characters SET conquest_data = $1 WHERE id = $2`, bf.Data(), s.charID)
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
} }