Merge pull request #57 from ZeruLight/feature/rasta

feature/rasta
This commit is contained in:
wish
2023-01-29 21:14:00 +11:00
committed by GitHub
6 changed files with 99 additions and 36 deletions

View File

@@ -1,15 +1,20 @@
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"
) )
// MsgMhfContractMercenary represents the MSG_MHF_CONTRACT_MERCENARY // MsgMhfContractMercenary represents the MSG_MHF_CONTRACT_MERCENARY
type MsgMhfContractMercenary struct{} type MsgMhfContractMercenary struct {
AckHandle uint32
PactMercID uint32
CID uint32
Op uint8
}
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
func (m *MsgMhfContractMercenary) Opcode() network.PacketID { func (m *MsgMhfContractMercenary) Opcode() network.PacketID {
@@ -18,7 +23,11 @@ func (m *MsgMhfContractMercenary) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfContractMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfContractMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED") m.AckHandle = bf.ReadUint32()
m.PactMercID = bf.ReadUint32()
m.CID = bf.ReadUint32()
m.Op = bf.ReadUint8()
return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -12,7 +12,7 @@ import (
type MsgMhfReadMercenaryM struct { type MsgMhfReadMercenaryM struct {
AckHandle uint32 AckHandle uint32
CharID uint32 CharID uint32
Unk0 uint32 MercID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +24,7 @@ func (m *MsgMhfReadMercenaryM) Opcode() network.PacketID {
func (m *MsgMhfReadMercenaryM) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReadMercenaryM) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.MercID = bf.ReadUint32()
return nil return nil
} }

View File

@@ -11,7 +11,7 @@ import (
// MsgMhfReadMercenaryW represents the MSG_MHF_READ_MERCENARY_W // MsgMhfReadMercenaryW represents the MSG_MHF_READ_MERCENARY_W
type MsgMhfReadMercenaryW struct { type MsgMhfReadMercenaryW struct {
AckHandle uint32 AckHandle uint32
Unk0 bool Op uint8
Unk1 uint8 Unk1 uint8
Unk2 uint16 // Hardcoded 0 in the binary Unk2 uint16 // Hardcoded 0 in the binary
} }
@@ -24,7 +24,7 @@ func (m *MsgMhfReadMercenaryW) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadBool() m.Op = bf.ReadUint8()
m.Unk1 = bf.ReadUint8() m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16() m.Unk2 = bf.ReadUint16()
return nil return nil

View File

@@ -10,11 +10,10 @@ import (
// MsgMhfSaveMercenary represents the MSG_MHF_SAVE_MERCENARY // MsgMhfSaveMercenary represents the MSG_MHF_SAVE_MERCENARY
type MsgMhfSaveMercenary struct { type MsgMhfSaveMercenary struct {
AckHandle uint32 AckHandle uint32
GCP uint32 GCP uint32
Unk0 uint32 PactMercID uint32
MercData []byte MercData []byte
Unk1 uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -27,9 +26,10 @@ func (m *MsgMhfSaveMercenary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
bf.ReadUint32() // lenData bf.ReadUint32() // lenData
m.GCP = bf.ReadUint32() m.GCP = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.PactMercID = bf.ReadUint32()
m.MercData = bf.ReadBytes(uint(bf.ReadUint32())) dataSize := bf.ReadUint32()
m.Unk1 = bf.ReadUint32() _ = bf.ReadUint32() // Merc index?
m.MercData = bf.ReadBytes(uint(dataSize))
return nil return nil
} }

View File

@@ -0,0 +1,9 @@
BEGIN;
UPDATE characters SET savemercenary = NULL;
ALTER TABLE characters ADD rasta_id INT;
ALTER TABLE characters ADD pact_id INT;
END;

View File

@@ -11,6 +11,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"time"
) )
func handleMsgMhfLoadPartner(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfLoadPartner(s *Session, p mhfpacket.MHFPacket) {
@@ -122,15 +123,11 @@ func handleMsgMhfEnumerateMercenaryLog(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfCreateMercenary(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfCreateMercenary(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfCreateMercenary) pkt := p.(*mhfpacket.MsgMhfCreateMercenary)
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
var nextID uint32 var nextID uint32
s.server.db.QueryRow("SELECT nextval('rasta_id_seq')").Scan(&nextID) _ = s.server.db.QueryRow("SELECT nextval('rasta_id_seq')").Scan(&nextID)
s.server.db.Exec("UPDATE characters SET rasta_id=$1 WHERE id=$2", nextID, s.charID)
bf.WriteUint32(nextID) // New MercID bf.WriteUint32(nextID)
bf.WriteUint32(0xDEADBEEF) // Unk
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
} }
@@ -138,29 +135,66 @@ func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfSaveMercenary) pkt := p.(*mhfpacket.MsgMhfSaveMercenary)
dumpSaveData(s, pkt.MercData, "mercenary") dumpSaveData(s, pkt.MercData, "mercenary")
if len(pkt.MercData) > 0 { if len(pkt.MercData) > 0 {
s.server.db.Exec("UPDATE characters SET savemercenary=$1 WHERE id=$2", pkt.MercData, s.charID) temp := byteframe.NewByteFrameFromBytes(pkt.MercData)
s.server.db.Exec("UPDATE characters SET savemercenary=$1, rasta_id=$2 WHERE id=$3", pkt.MercData, temp.ReadUint32(), s.charID)
} }
s.server.db.Exec("UPDATE characters SET gcp=$1 WHERE id=$2", pkt.GCP, s.charID) s.server.db.Exec("UPDATE characters SET gcp=$1, pact_id=$2 WHERE id=$3", pkt.GCP, pkt.PactMercID, s.charID)
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
} }
func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfReadMercenaryW(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfReadMercenaryW) pkt := p.(*mhfpacket.MsgMhfReadMercenaryW)
if pkt.Unk0 { if pkt.Op > 0 {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 2)) bf := byteframe.NewByteFrame()
var pactID uint32
var name string
var cid uint32
s.server.db.QueryRow("SELECT pact_id FROM characters WHERE id=$1", s.charID).Scan(&pactID)
if pactID > 0 {
s.server.db.QueryRow("SELECT name, id FROM characters WHERE rasta_id = $1", pactID).Scan(&name, &cid)
bf.WriteUint8(1) // numLends
bf.WriteUint32(pactID)
bf.WriteUint32(cid)
bf.WriteBool(false) // ?
bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -8).Unix()))
bf.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -1).Unix()))
bf.WriteBytes(stringsupport.PaddedString(name, 18, true))
} else {
bf.WriteUint8(0)
}
if pkt.Op < 2 {
var loans uint8
temp := byteframe.NewByteFrame()
rows, _ := s.server.db.Query("SELECT name, id, pact_id FROM characters WHERE pact_id=(SELECT rasta_id FROM characters WHERE id=$1)", s.charID)
for rows.Next() {
loans++
rows.Scan(&name, &cid, &pactID)
temp.WriteUint32(pactID)
temp.WriteUint32(cid)
temp.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -8).Unix()))
temp.WriteUint32(uint32(Time_Current_Adjusted().Add(time.Hour * 24 * -1).Unix()))
temp.WriteBytes(stringsupport.PaddedString(name, 18, true))
}
bf.WriteUint8(loans)
bf.WriteBytes(temp.Data())
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
return return
} }
var data []byte var data []byte
var gcp uint32 var gcp uint32
s.server.db.QueryRow("SELECT savemercenary FROM characters WHERE id = $1", s.charID).Scan(&data) s.server.db.QueryRow("SELECT savemercenary FROM characters WHERE id=$1", s.charID).Scan(&data)
s.server.db.QueryRow("SELECT COALESCE(gcp, 0) FROM characters WHERE id = $1", s.charID).Scan(&gcp) s.server.db.QueryRow("SELECT COALESCE(gcp, 0) FROM characters WHERE id=$1", s.charID).Scan(&gcp)
resp := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
resp.WriteUint16(0)
if len(data) == 0 { if len(data) == 0 {
resp.WriteBytes(make([]byte, 3)) resp.WriteBool(false)
} else { } else {
resp.WriteBytes(data[1:]) resp.WriteBool(true)
resp.WriteUint32(0) // Unk resp.WriteBytes(data)
} }
resp.WriteUint32(gcp) resp.WriteUint32(gcp)
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
@@ -174,12 +208,23 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) {
if len(data) == 0 { if len(data) == 0 {
resp.WriteBool(false) resp.WriteBool(false)
} else { } else {
resp.WriteBytes(data[4:]) resp.WriteBytes(data)
} }
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfContractMercenary)
switch pkt.Op {
case 0:
s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, s.charID)
case 1: // Cancel lend
s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID)
case 2: // Cancel loan
s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", pkt.CID)
}
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}
func handleMsgMhfLoadOtomoAirou(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfLoadOtomoAirou(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfLoadOtomoAirou) pkt := p.(*mhfpacket.MsgMhfLoadOtomoAirou)