compat pass 2
This commit is contained in:
parent
9cc3273a81
commit
c692b25ac0
@ -8,7 +8,6 @@ import (
|
||||
)
|
||||
|
||||
// ProtoPacket handles low-level protocol features including EQ2-specific operations
|
||||
// Merges functionality from EQProtocolPacket and EQ2Packet
|
||||
type ProtoPacket struct {
|
||||
*Packet
|
||||
|
||||
@ -16,7 +15,7 @@ type ProtoPacket struct {
|
||||
flags uint8 // bit 0: compressed, bit 1: prepared, bit 2: encrypted, bit 3: acked
|
||||
|
||||
// EQ2-specific
|
||||
LoginOp opcodes.EmuOpcode // From EQ2Packet
|
||||
LoginOp opcodes.EmuOpcode
|
||||
|
||||
// Reliability and sequencing
|
||||
Sequence int32
|
||||
@ -39,7 +38,7 @@ const (
|
||||
FlagAcked
|
||||
)
|
||||
|
||||
// Default compression threshold (compress packets larger than this)
|
||||
// Default compression threshold
|
||||
const DefaultCompressThreshold = 100
|
||||
|
||||
// NewProtoPacket creates a protocol packet with opcode and buffer
|
||||
@ -190,7 +189,7 @@ func (p *ProtoPacket) EncodeChat() {
|
||||
return
|
||||
}
|
||||
|
||||
if IsChatPacket(p.Opcode) {
|
||||
if p.IsChatPacket() {
|
||||
ChatEncode(p.Buffer, p.EncodeKey)
|
||||
p.SetEncrypted(true)
|
||||
}
|
||||
@ -206,6 +205,29 @@ func (p *ProtoPacket) DecodeChat() {
|
||||
p.SetEncrypted(false)
|
||||
}
|
||||
|
||||
// IsChatPacket checks if this is a chat packet using opcode manager
|
||||
func (p *ProtoPacket) IsChatPacket() bool {
|
||||
if p.manager == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get emulator opcode
|
||||
emuOp := p.manager.EQToEmu(p.Opcode)
|
||||
|
||||
// Check against known chat opcodes
|
||||
switch emuOp {
|
||||
case opcodes.OP_ChatMsg,
|
||||
opcodes.OP_TellMsg,
|
||||
opcodes.OP_ChatLeaveChannelMsg,
|
||||
opcodes.OP_ChatTellChannelMsg,
|
||||
opcodes.OP_ChatTellUserMsg,
|
||||
opcodes.OP_GuildsayMsg:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Copy creates a deep copy of this protocol packet
|
||||
func (p *ProtoPacket) Copy() *ProtoPacket {
|
||||
newPacket := &ProtoPacket{
|
||||
@ -255,7 +277,7 @@ func (p *ProtoPacket) Serialize(dest []byte, offset int8) uint32 {
|
||||
return uint32(len(p.Buffer)-int(offset)) + uint32(pos)
|
||||
}
|
||||
|
||||
// PreparePacket prepares an EQ2 packet for transmission (from EQ2Packet)
|
||||
// PreparePacket prepares an EQ2 packet for transmission
|
||||
func (p *ProtoPacket) PreparePacket(maxLen int16) int8 {
|
||||
if p.IsPrepared() {
|
||||
return 0
|
||||
@ -367,53 +389,122 @@ func (p *ProtoPacket) MakeApplicationPacket(opcodeSize uint8) *AppPacket {
|
||||
return app
|
||||
}
|
||||
|
||||
// AppCombine combines this packet with another for efficient transmission (from EQ2Packet)
|
||||
// AppCombine combines this packet with another for efficient transmission
|
||||
func (p *ProtoPacket) AppCombine(rhs *ProtoPacket) bool {
|
||||
const opAppCombined = 0x19 // OP_AppCombined value
|
||||
const opAppCombined = 0x19 // OP_AppCombined
|
||||
|
||||
// Apply compression to both packets before combining
|
||||
p.CompressPacket()
|
||||
rhs.CompressPacket()
|
||||
// Calculate sizes
|
||||
lhsSize := p.Size()
|
||||
rhsSize := rhs.Size()
|
||||
|
||||
// Case 1: This packet is already a combined packet
|
||||
if p.Opcode == opAppCombined && (len(p.Buffer)+len(rhs.Buffer)+3) < 255 {
|
||||
tmpSize := len(rhs.Buffer) - 2
|
||||
overSized := tmpSize >= 255
|
||||
// Check max combined size
|
||||
if lhsSize+rhsSize > MaxCombinedSize {
|
||||
return false
|
||||
}
|
||||
|
||||
// If this packet is already combined, add to it
|
||||
if p.Opcode == opAppCombined {
|
||||
// Calculate new size
|
||||
var newSize int
|
||||
if overSized {
|
||||
newSize = len(p.Buffer) + tmpSize + 3
|
||||
if rhsSize >= 255 {
|
||||
newSize = len(p.Buffer) + int(rhsSize) + 3 // oversized header
|
||||
} else {
|
||||
newSize = len(p.Buffer) + tmpSize + 1
|
||||
newSize = len(p.Buffer) + int(rhsSize) + 1 // normal header
|
||||
}
|
||||
|
||||
tmpBuffer := make([]byte, newSize)
|
||||
// Check size limit
|
||||
if newSize > MaxCombinedSize {
|
||||
return false
|
||||
}
|
||||
|
||||
// Create new buffer
|
||||
newBuffer := make([]byte, newSize)
|
||||
pos := 0
|
||||
|
||||
// Copy existing combined packet data
|
||||
copy(tmpBuffer, p.Buffer)
|
||||
pos += len(p.Buffer)
|
||||
// Copy existing combined data
|
||||
copy(newBuffer, p.Buffer)
|
||||
pos = len(p.Buffer)
|
||||
|
||||
// Add size information for the new packet
|
||||
if overSized {
|
||||
tmpBuffer[pos] = 255
|
||||
// Add new packet with size header
|
||||
if rhsSize >= 255 {
|
||||
newBuffer[pos] = 255 // Oversized marker
|
||||
pos++
|
||||
binary.BigEndian.PutUint16(tmpBuffer[pos:], uint16(tmpSize))
|
||||
binary.BigEndian.PutUint16(newBuffer[pos:], uint16(rhsSize))
|
||||
pos += 2
|
||||
} else {
|
||||
tmpBuffer[pos] = byte(tmpSize)
|
||||
newBuffer[pos] = byte(rhsSize)
|
||||
pos++
|
||||
}
|
||||
|
||||
// Copy the new packet data (skip first 2 bytes which are opcode)
|
||||
if len(rhs.Buffer) > 2 {
|
||||
copy(tmpBuffer[pos:], rhs.Buffer[2:])
|
||||
}
|
||||
// Serialize rhs packet
|
||||
tmpBuf := make([]byte, rhsSize)
|
||||
rhs.Serialize(tmpBuf, 0)
|
||||
copy(newBuffer[pos:], tmpBuf)
|
||||
|
||||
p.Buffer = tmpBuffer
|
||||
p.Buffer = newBuffer
|
||||
return true
|
||||
}
|
||||
|
||||
// Case 2: Create new combined packet (simplified)
|
||||
return false
|
||||
// Create new combined packet from two non-combined packets
|
||||
// Calculate total size: size1(1-3) + packet1 + size2(1-3) + packet2
|
||||
var totalSize int
|
||||
if lhsSize >= 255 {
|
||||
totalSize += 3 + int(lhsSize)
|
||||
} else {
|
||||
totalSize += 1 + int(lhsSize)
|
||||
}
|
||||
if rhsSize >= 255 {
|
||||
totalSize += 3 + int(rhsSize)
|
||||
} else {
|
||||
totalSize += 1 + int(rhsSize)
|
||||
}
|
||||
|
||||
// Check size limit
|
||||
if totalSize > MaxCombinedSize {
|
||||
return false
|
||||
}
|
||||
|
||||
// Build combined packet
|
||||
newBuffer := make([]byte, totalSize)
|
||||
pos := 0
|
||||
|
||||
// Add first packet with size header
|
||||
if lhsSize >= 255 {
|
||||
newBuffer[pos] = 255
|
||||
pos++
|
||||
binary.BigEndian.PutUint16(newBuffer[pos:], uint16(lhsSize))
|
||||
pos += 2
|
||||
} else {
|
||||
newBuffer[pos] = byte(lhsSize)
|
||||
pos++
|
||||
}
|
||||
|
||||
// Serialize first packet
|
||||
tmpBuf := make([]byte, lhsSize)
|
||||
p.Serialize(tmpBuf, 0)
|
||||
copy(newBuffer[pos:], tmpBuf)
|
||||
pos += int(lhsSize)
|
||||
|
||||
// Add second packet with size header
|
||||
if rhsSize >= 255 {
|
||||
newBuffer[pos] = 255
|
||||
pos++
|
||||
binary.BigEndian.PutUint16(newBuffer[pos:], uint16(rhsSize))
|
||||
pos += 2
|
||||
} else {
|
||||
newBuffer[pos] = byte(rhsSize)
|
||||
pos++
|
||||
}
|
||||
|
||||
// Serialize second packet
|
||||
tmpBuf = make([]byte, rhsSize)
|
||||
rhs.Serialize(tmpBuf, 0)
|
||||
copy(newBuffer[pos:], tmpBuf)
|
||||
|
||||
// Update this packet to be combined
|
||||
p.Opcode = opAppCombined
|
||||
p.Buffer = newBuffer
|
||||
p.SetPrepared(false) // Need to re-prepare
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func (f *StreamFactory) OnBoot(eng gnet.Engine) gnet.Action {
|
||||
func (f *StreamFactory) OnOpen(c gnet.Conn) ([]byte, gnet.Action) {
|
||||
// Create stream configuration
|
||||
streamCfg := &Config{
|
||||
SessionID: uint32(time.Now().UnixNano()), // Generate session ID
|
||||
SessionID: uint32(time.Now().UnixNano()),
|
||||
CRCKey: f.crcKey,
|
||||
MaxPacketSize: f.maxPacketSize,
|
||||
EncodeKey: f.encodeKey,
|
||||
@ -181,13 +181,17 @@ func (f *StreamFactory) OnTraffic(c gnet.Conn) gnet.Action {
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
// OnTick called periodically
|
||||
// OnTick called periodically to process stream queues
|
||||
func (f *StreamFactory) OnTick() (time.Duration, gnet.Action) {
|
||||
f.mu.RLock()
|
||||
defer f.mu.RUnlock()
|
||||
|
||||
// Process retransmissions for all streams
|
||||
streams := make([]*Stream, 0, len(f.streams))
|
||||
for _, stream := range f.streams {
|
||||
streams = append(streams, stream)
|
||||
}
|
||||
f.mu.RUnlock()
|
||||
|
||||
// Process queues for all streams
|
||||
for _, stream := range streams {
|
||||
stream.processQueues()
|
||||
}
|
||||
|
||||
|
1032
stream/stream.go
1032
stream/stream.go
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user