mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-16 17:05:03 +01:00
Add support for party chat in town
This commit is contained in:
48
network/binpacket/msg_cast_bin_private_message.go
Normal file
48
network/binpacket/msg_cast_bin_private_message.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package binpacket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Andoryuuta/Erupe/network"
|
||||||
|
"github.com/Andoryuuta/byteframe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChatTargetType uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
CHAT_TARGET_PRIVATE = 0x05
|
||||||
|
CHAT_TARGET_PARTY = 0x04
|
||||||
|
)
|
||||||
|
|
||||||
|
type MsgBinTargetedChatMessage struct {
|
||||||
|
// I can't see a reason if this is indeed the number of targets, that
|
||||||
|
// it should use 2 bytes
|
||||||
|
TargetCount uint16
|
||||||
|
TargetCharIDs []uint32
|
||||||
|
TargetType uint16
|
||||||
|
RawDataPayload []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opcode returns the ID associated with this packet type.
|
||||||
|
func (m *MsgBinTargetedChatMessage) Opcode() network.PacketID {
|
||||||
|
return network.MSG_SYS_CAST_BINARY
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgBinTargetedChatMessage) Parse(bf *byteframe.ByteFrame) error {
|
||||||
|
m.TargetCount = bf.ReadUint16()
|
||||||
|
i := uint16(0)
|
||||||
|
|
||||||
|
m.TargetCharIDs = make([]uint32, m.TargetCount)
|
||||||
|
|
||||||
|
for ; i < m.TargetCount; i++ {
|
||||||
|
m.TargetCharIDs[i] = bf.ReadUint32()
|
||||||
|
}
|
||||||
|
|
||||||
|
m.TargetType = bf.ReadUint16()
|
||||||
|
m.RawDataPayload = bf.DataFromCurrent()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build builds a binary packet from the current data.
|
||||||
|
func (m *MsgBinTargetedChatMessage) Build(bf *byteframe.ByteFrame) error {
|
||||||
|
panic("Not implemented")
|
||||||
|
}
|
||||||
@@ -167,3 +167,15 @@ func (s *Server) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session)
|
|||||||
session.QueueSendNonBlocking(bf.Data())
|
session.QueueSendNonBlocking(bf.Data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) FindSessionByCharID(charID uint32) *Session {
|
||||||
|
for _, stage := range s.stages {
|
||||||
|
for client := range stage.clients {
|
||||||
|
if client.charID == charID {
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Andoryuuta/Erupe/network/binpacket"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -198,12 +200,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CHAT_TYPE_WORLD uint8 = iota
|
CHAT_TYPE_WORLD = 0x0a
|
||||||
CHAT_TYPE_LOCAL
|
CHAT_TYPE_STAGE = 0x03
|
||||||
CHAT_TYPE_GUILD
|
CHAT_TYPE_TARGETED = 0x01
|
||||||
CHAT_TYPE_ALLIANCE
|
|
||||||
CHAT_TYPE_PARTY
|
|
||||||
CHAT_TYPE_WHISPER
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -217,20 +216,48 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pkt.Type1 == BINARY_MESSAGE_TYPE_CHAT {
|
if pkt.Type1 == BINARY_MESSAGE_TYPE_CHAT {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteBytes(pkt.RawDataPayload)
|
||||||
|
bf.Seek(0, io.SeekStart)
|
||||||
|
|
||||||
fmt.Println("Got chat message!")
|
fmt.Println("Got chat message!")
|
||||||
|
|
||||||
switch chatType := pkt.RawDataPayload[2]; chatType {
|
switch pkt.Type0 {
|
||||||
case CHAT_TYPE_WORLD:
|
case CHAT_TYPE_WORLD:
|
||||||
s.server.BroadcastMHF(resp, s)
|
s.server.BroadcastMHF(resp, s)
|
||||||
case CHAT_TYPE_LOCAL:
|
case CHAT_TYPE_STAGE:
|
||||||
s.stage.BroadcastMHF(resp, s)
|
s.stage.BroadcastMHF(resp, s)
|
||||||
case CHAT_TYPE_PARTY:
|
case CHAT_TYPE_TARGETED:
|
||||||
if s.reservationStage != nil {
|
chatMessage := &binpacket.MsgBinTargetedChatMessage{}
|
||||||
// Party messages seem to work partially when a party member starts the quest
|
err := chatMessage.Parse(bf)
|
||||||
// In town it is not working yet, the client now sends the chat packets
|
|
||||||
// however the other member does not accept it.
|
if err != nil {
|
||||||
s.reservationStage.BroadcastMHF(resp, s)
|
s.logger.Warn("failed to parse chat message")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chatBf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
|
chatBf.WriteUint16(0x04)
|
||||||
|
|
||||||
|
chatBf.WriteBytes(chatMessage.RawDataPayload)
|
||||||
|
|
||||||
|
resp = &mhfpacket.MsgSysCastedBinary{
|
||||||
|
CharID: s.charID,
|
||||||
|
Type0: pkt.Type0,
|
||||||
|
Type1: pkt.Type1,
|
||||||
|
RawDataPayload: chatBf.Data(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, targetID := range chatMessage.TargetCharIDs {
|
||||||
|
char := s.server.FindSessionByCharID(targetID)
|
||||||
|
|
||||||
|
if char != nil {
|
||||||
|
char.QueueSendMHF(resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s.stage.BroadcastMHF(resp, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -605,7 +632,7 @@ func handleMsgSysReserveStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
pkt := p.(*mhfpacket.MsgSysReserveStage)
|
pkt := p.(*mhfpacket.MsgSysReserveStage)
|
||||||
|
|
||||||
stageID := stripNullTerminator(pkt.StageID)
|
stageID := stripNullTerminator(pkt.StageID)
|
||||||
fmt.Printf("Got reserve stage req, Unk0:%v, StageID:%v\n", pkt.Unk0, stageID)
|
fmt.Printf("Got reserve stage req, TargetCount:%v, StageID:%v\n", pkt.Unk0, stageID)
|
||||||
|
|
||||||
// Try to get the stage
|
// Try to get the stage
|
||||||
s.server.stagesLock.Lock()
|
s.server.stagesLock.Lock()
|
||||||
@@ -910,7 +937,7 @@ func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
// Response to our requesting client.
|
// Response to our requesting client.
|
||||||
resp := byteframe.NewByteFrame()
|
resp := byteframe.NewByteFrame()
|
||||||
resp.WriteUint32(0) // Unk, is this echoed back from pkt.Unk0?
|
resp.WriteUint32(0) // Unk, is this echoed back from pkt.TargetCount?
|
||||||
resp.WriteUint32(objID) // New local obj handle.
|
resp.WriteUint32(objID) // New local obj handle.
|
||||||
s.QueueAck(pkt.AckHandle, resp.Data())
|
s.QueueAck(pkt.AckHandle, resp.Data())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user