implement semaphore indexes

This commit is contained in:
wish
2022-07-26 04:14:19 +10:00
parent b7c293812c
commit ff5d32ef7f
6 changed files with 305 additions and 313 deletions

View File

@@ -11,7 +11,7 @@ import (
// MsgSysOperateRegister represents the MSG_SYS_OPERATE_REGISTER // MsgSysOperateRegister represents the MSG_SYS_OPERATE_REGISTER
type MsgSysOperateRegister struct { type MsgSysOperateRegister struct {
AckHandle uint32 AckHandle uint32
RegisterID uint32 SemaphoreID uint32
fixedZero uint16 fixedZero uint16
RawDataPayload []byte RawDataPayload []byte
} }
@@ -24,7 +24,7 @@ func (m *MsgSysOperateRegister) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.RegisterID = bf.ReadUint32() m.SemaphoreID = bf.ReadUint32()
m.fixedZero = bf.ReadUint16() m.fixedZero = bf.ReadUint16()
if m.fixedZero != 0 { if m.fixedZero != 0 {
@@ -39,7 +39,7 @@ func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgSysOperateRegister) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysOperateRegister) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) bf.WriteUint32(m.AckHandle)
bf.WriteUint32(m.RegisterID) bf.WriteUint32(m.SemaphoreID)
bf.WriteUint16(0) bf.WriteUint16(0)
bf.WriteUint16(uint16(len(m.RawDataPayload))) bf.WriteUint16(uint16(len(m.RawDataPayload)))
bf.WriteBytes(m.RawDataPayload) bf.WriteBytes(m.RawDataPayload)

View File

@@ -1,7 +1,6 @@
package channelserver package channelserver
import ( import (
"encoding/hex"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
) )
@@ -10,129 +9,7 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysOperateRegister) pkt := p.(*mhfpacket.MsgSysOperateRegister)
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
s.server.raviente.Lock() s.server.raviente.Lock()
switch pkt.RegisterID { if pkt.SemaphoreID == s.server.raviente.state.semaphoreID {
case 786461:
resp := byteframe.NewByteFrame()
size := 6
for i := 0; i < len(bf.Data())-1; i += size {
op := bf.ReadUint8()
dest := bf.ReadUint8()
data := bf.ReadUint32()
resp.WriteUint8(1)
resp.WriteUint8(dest)
switch dest {
case 0:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.nextTime = data
case 1:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.startTime = data
case 2:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.killedTime = data
case 3:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.postTime = data
case 4:
ref := &s.server.raviente.register.register[0]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 5:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.carveQuest = data
case 6:
ref := &s.server.raviente.register.register[1]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 7:
ref := &s.server.raviente.register.register[2]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 8:
ref := &s.server.raviente.register.register[3]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 9:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.maxPlayers = data
case 10:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.ravienteType = data
case 11:
ref := &s.server.raviente.register.register[4]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
default:
resp.WriteUint32(0)
resp.WriteUint32(0)
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 917533:
resp := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
size := 6 size := 6
for i := 0; i < len(bf.Data())-1; i += size { for i := 0; i < len(bf.Data())-1; i += size {
@@ -152,12 +29,12 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
} else if dest == 17 { // Berserk poison tracker } else if dest == 17 { // Berserk poison tracker
if damageMultiplier == 1 { if damageMultiplier == 1 {
resp.WriteUint32(*ref + data) resp.WriteUint32(*ref + data)
*ref += data
} else { } else {
resp.WriteUint32(*ref + data) resp.WriteUint32(*ref + data)
*ref += data
} }
} else { } else {
resp.WriteUint32(*ref + data * damageMultiplier) resp.WriteUint32(*ref + data*damageMultiplier)
*ref += data * damageMultiplier *ref += data * damageMultiplier
} }
case 13: case 13:
@@ -170,8 +47,7 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
} }
resp.WriteUint8(0) resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} else if pkt.SemaphoreID == s.server.raviente.support.semaphoreID {
case 851997:
resp := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
size := 6 size := 6
for i := 0; i < len(bf.Data())-1; i += size { for i := 0; i < len(bf.Data())-1; i += size {
@@ -196,6 +72,126 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
} }
resp.WriteUint8(0) resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} else if pkt.SemaphoreID == s.server.raviente.register.semaphoreID {
resp := byteframe.NewByteFrame()
size := 6
for i := 0; i < len(bf.Data())-1; i += size {
op := bf.ReadUint8()
dest := bf.ReadUint8()
data := bf.ReadUint32()
resp.WriteUint8(1)
resp.WriteUint8(dest)
switch dest {
case 0:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.nextTime = data
case 1:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.startTime = data
case 2:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.killedTime = data
case 3:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.postTime = data
case 4:
ref := &s.server.raviente.register.register[0]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 5:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.carveQuest = data
case 6:
ref := &s.server.raviente.register.register[1]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 7:
ref := &s.server.raviente.register.register[2]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 8:
ref := &s.server.raviente.register.register[3]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
case 9:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.maxPlayers = data
case 10:
resp.WriteUint32(0)
resp.WriteUint32(data)
s.server.raviente.register.ravienteType = data
case 11:
ref := &s.server.raviente.register.register[4]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + uint32(data))
*ref += data
case 13:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
}
default:
resp.WriteUint32(0)
resp.WriteUint32(0)
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
s.notifyall() s.notifyall()
s.server.raviente.Unlock() s.server.raviente.Unlock()
@@ -205,74 +201,66 @@ func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysLoadRegister) pkt := p.(*mhfpacket.MsgSysLoadRegister)
r := pkt.Unk1 r := pkt.Unk1
switch r { switch r {
case 12: case 12:
if pkt.RegisterID == 983077 { resp := byteframe.NewByteFrame()
data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") resp.WriteUint8(0)
doAckBufFail(s, pkt.AckHandle, data) resp.WriteUint8(12)
} else if pkt.RegisterID == 983069 { resp.WriteUint32(s.server.raviente.register.nextTime)
data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") resp.WriteUint32(s.server.raviente.register.startTime)
doAckBufFail(s, pkt.AckHandle, data) resp.WriteUint32(s.server.raviente.register.killedTime)
} resp.WriteUint32(s.server.raviente.register.postTime)
resp := byteframe.NewByteFrame() resp.WriteUint32(s.server.raviente.register.register[0])
resp.WriteUint8(0) resp.WriteUint32(s.server.raviente.register.carveQuest)
resp.WriteUint8(12) resp.WriteUint32(s.server.raviente.register.register[1])
resp.WriteUint32(s.server.raviente.register.nextTime) resp.WriteUint32(s.server.raviente.register.register[2])
resp.WriteUint32(s.server.raviente.register.startTime) resp.WriteUint32(s.server.raviente.register.register[3])
resp.WriteUint32(s.server.raviente.register.killedTime) resp.WriteUint32(s.server.raviente.register.maxPlayers)
resp.WriteUint32(s.server.raviente.register.postTime) resp.WriteUint32(s.server.raviente.register.ravienteType)
resp.WriteUint32(s.server.raviente.register.register[0]) resp.WriteUint32(s.server.raviente.register.register[4])
resp.WriteUint32(s.server.raviente.register.carveQuest) doAckBufSucceed(s, pkt.AckHandle, resp.Data())
resp.WriteUint32(s.server.raviente.register.register[1]) case 29:
resp.WriteUint32(s.server.raviente.register.register[2]) resp := byteframe.NewByteFrame()
resp.WriteUint32(s.server.raviente.register.register[3]) resp.WriteUint8(0)
resp.WriteUint32(s.server.raviente.register.maxPlayers) resp.WriteUint8(29)
resp.WriteUint32(s.server.raviente.register.ravienteType) for _, v := range s.server.raviente.state.stateData {
resp.WriteUint32(s.server.raviente.register.register[4]) resp.WriteUint32(v)
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) }
case 29: doAckBufSucceed(s, pkt.AckHandle, resp.Data())
resp := byteframe.NewByteFrame() case 25:
resp.WriteUint8(0) resp := byteframe.NewByteFrame()
resp.WriteUint8(29) resp.WriteUint8(0)
for _, v := range s.server.raviente.state.stateData { resp.WriteUint8(25)
resp.WriteUint32(v) for _, v := range s.server.raviente.support.supportData {
} resp.WriteUint32(v)
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) }
case 25: doAckBufSucceed(s, pkt.AckHandle, resp.Data())
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
resp.WriteUint8(25)
for _, v := range s.server.raviente.support.supportData {
resp.WriteUint32(v)
}
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
} }
// Unused
func (s *Session) notifyplayer() {
s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D})
}
func (s *Session) notifyall() { func (s *Session) notifyall() {
var temp mhfpacket.MHFPacket
raviNotif := byteframe.NewByteFrame()
temp = &mhfpacket.MsgSysNotifyRegister{RegisterID: s.server.raviente.support.semaphoreID}
raviNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(raviNotif, s.clientContext)
temp = &mhfpacket.MsgSysNotifyRegister{RegisterID: s.server.raviente.state.semaphoreID}
raviNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(raviNotif, s.clientContext)
temp = &mhfpacket.MsgSysNotifyRegister{RegisterID: s.server.raviente.register.semaphoreID}
raviNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(raviNotif, s.clientContext)
raviNotif.WriteUint16(0x0010) // End it.
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists { if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients { for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D}) session.QueueSend(raviNotif.Data())
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
} }
} else if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists { } else if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
for session := range s.server.semaphore["hs_l0u3B5129k3"].clients { for session := range s.server.semaphore["hs_l0u3B5129k3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D}) session.QueueSend(raviNotif.Data())
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
} }
} else if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists { } else if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
for session := range s.server.semaphore["hs_l0u3B512Ak3"].clients { for session := range s.server.semaphore["hs_l0u3B512Ak3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D}) session.QueueSend(raviNotif.Data())
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
} }
} }
} }
@@ -288,27 +276,28 @@ func checkRaviSemaphore(s *Session) bool {
return false return false
} }
func releaseRaviSemaphore(s *Session) { //func releaseRaviSemaphore(s *Session) {
s.server.raviente.Lock() // s.server.raviente.Lock()
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists { // if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
if len(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots) == 0 { // if len(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots) == 0 {
resetRavi(s) // resetRavi(s)
} // }
} // }
if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists { // if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
if len(s.server.semaphore["hs_l0u3B5129k3"].reservedClientSlots) == 0 { // if len(s.server.semaphore["hs_l0u3B5129k3"].reservedClientSlots) == 0 {
resetRavi(s) // resetRavi(s)
} // }
} // }
if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists { // if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
if len(s.server.semaphore["hs_l0u3B512Ak3"].reservedClientSlots) == 0 { // if len(s.server.semaphore["hs_l0u3B512Ak3"].reservedClientSlots) == 0 {
resetRavi(s) // resetRavi(s)
} // }
} // }
s.server.raviente.Unlock() // s.server.raviente.Unlock()
} //}
func resetRavi(s *Session) { func resetRavi(s *Session) {
s.server.raviente.Lock()
s.server.raviente.register.nextTime = 0 s.server.raviente.register.nextTime = 0
s.server.raviente.register.startTime = 0 s.server.raviente.register.startTime = 0
s.server.raviente.register.killedTime = 0 s.server.raviente.register.killedTime = 0
@@ -320,6 +309,7 @@ func resetRavi(s *Session) {
s.server.raviente.register.register = []uint32{0, 0, 0, 0, 0} s.server.raviente.register.register = []uint32{0, 0, 0, 0, 0}
s.server.raviente.state.stateData = []uint32{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.raviente.state.stateData = []uint32{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.raviente.support.supportData = []uint32{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.raviente.support.supportData = []uint32{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.raviente.Unlock()
} }
// Unused // Unused
@@ -334,4 +324,4 @@ func (s *Session) notifyticker() {
} }
} }
func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {}

View File

@@ -1,7 +1,9 @@
package channelserver package channelserver
import ( import (
"erupe-ce/common/byteframe"
"fmt" "fmt"
"go.uber.org/zap"
"strings" "strings"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
@@ -10,11 +12,13 @@ import (
func removeSessionFromSemaphore(s *Session) { func removeSessionFromSemaphore(s *Session) {
s.server.semaphoreLock.Lock() s.server.semaphoreLock.Lock()
for _, semaphore := range s.server.semaphore { for _, semaphore := range s.server.semaphore {
if _, exists := semaphore.reservedClientSlots[s.charID]; exists {
delete(semaphore.reservedClientSlots, s.charID)
}
if _, exists := semaphore.clients[s]; exists { if _, exists := semaphore.clients[s]; exists {
delete(semaphore.clients, s) delete(semaphore.clients, s)
} }
} }
releaseRaviSemaphore(s)
s.server.semaphoreLock.Unlock() s.server.semaphoreLock.Unlock()
} }
@@ -23,54 +27,50 @@ func handleMsgSysCreateSemaphore(s *Session, p mhfpacket.MHFPacket) {
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x03, 0x00, 0x0d}) doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x03, 0x00, 0x0d})
} }
func destructEmptySemaphores(s *Session) {
s.server.semaphoreLock.Lock()
for id, sema := range s.server.semaphore {
if len(sema.reservedClientSlots) == 0 && len(sema.clients) == 0 {
s.server.semaphoreLock.Unlock()
delete(s.server.semaphore, id)
s.server.semaphoreLock.Lock()
if strings.HasPrefix(id, "hs_l0u3B51") {
releaseRaviSemaphore(s, sema)
}
s.logger.Debug("Destructed semaphore", zap.String("sema.id_semaphore", id))
}
}
s.server.semaphoreLock.Unlock()
}
func releaseRaviSemaphore(s *Session, sema *Semaphore) {
if !strings.HasSuffix(sema.id_semaphore, "5") {
delete(sema.reservedClientSlots, s.charID)
delete(sema.clients, s)
}
if len(sema.reservedClientSlots) == 0 && len(sema.clients) == 0 {
s.logger.Debug("Raviente semaphore is empty, resetting")
resetRavi(s)
}
}
func handleMsgSysDeleteSemaphore(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysDeleteSemaphore(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysDeleteSemaphore) pkt := p.(*mhfpacket.MsgSysDeleteSemaphore)
sem := pkt.AckHandle sem := pkt.AckHandle
if s.server.semaphore != nil { if s.server.semaphore != nil {
destructEmptySemaphores(s)
s.server.semaphoreLock.Lock() s.server.semaphoreLock.Lock()
for id := range s.server.semaphore { for id, sema := range s.server.semaphore {
switch sem { if sema.id == sem {
case 917533: if strings.HasPrefix(id, "hs_l0u3B51") {
if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k3" { releaseRaviSemaphore(s, sema)
delete(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots, s.charID) s.server.semaphoreLock.Unlock()
delete(s.server.semaphore["hs_l0u3B51J9k3"].clients, s) return
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B5129k3" {
delete(s.server.semaphore["hs_l0u3B5129k3"].reservedClientSlots, s.charID)
delete(s.server.semaphore["hs_l0u3B5129k3"].clients, s)
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B512Ak3" {
delete(s.server.semaphore["hs_l0u3B512Ak3"].reservedClientSlots, s.charID)
delete(s.server.semaphore["hs_l0u3B512Ak3"].clients, s)
}
case 851997:
if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k4" {
delete(s.server.semaphore["hs_l0u3B51J9k4"].reservedClientSlots, s.charID)
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B5129k4" {
delete(s.server.semaphore["hs_l0u3B5129k4"].reservedClientSlots, s.charID)
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B512Ak4" {
delete(s.server.semaphore["hs_l0u3B512Ak4"].reservedClientSlots, s.charID)
}
case 786461:
if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k5" {
delete(s.server.semaphore["hs_l0u3B51J9k5"].reservedClientSlots, s.charID)
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B5129k5" {
delete(s.server.semaphore["hs_l0u3B5129k5"].reservedClientSlots, s.charID)
} else if s.server.semaphore[id].id_semaphore == "hs_l0u3B512Ak5" {
delete(s.server.semaphore["hs_l0u3B512Ak5"].reservedClientSlots, s.charID)
}
default:
if len(s.server.semaphore[id].reservedClientSlots) != 0 {
if s.server.semaphore[id].id_semaphore != "hs_l0u3B51J9k3" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B51J9k4" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B51J9k5" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B5129k3" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B5129k4" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B5129k5" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B512Ak3" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B512Ak4" &&
s.server.semaphore[id].id_semaphore != "hs_l0u3B512Ak5" {
delete(s.server.semaphore[id].reservedClientSlots, s.charID)
}
} }
s.server.semaphoreLock.Unlock()
delete(s.server.semaphore, id)
s.logger.Debug("Destructed semaphore", zap.String("sema.id_semaphore", id))
return
} }
} }
s.server.semaphoreLock.Unlock() s.server.semaphoreLock.Unlock()
@@ -81,15 +81,22 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysCreateAcquireSemaphore) pkt := p.(*mhfpacket.MsgSysCreateAcquireSemaphore)
SemaphoreID := pkt.SemaphoreID SemaphoreID := pkt.SemaphoreID
newSemaphore, gotNewStage := s.server.semaphore[SemaphoreID] newSemaphore, exists := s.server.semaphore[SemaphoreID]
fmt.Printf("Got reserve stage req, StageID: %v\n\n", SemaphoreID) fmt.Printf("Got reserve stage req, StageID: %v\n\n", SemaphoreID)
if !gotNewStage { if !exists {
s.server.semaphoreLock.Lock() s.server.semaphoreLock.Lock()
if strings.HasPrefix(SemaphoreID, "hs_l0u3B51") { if strings.HasPrefix(SemaphoreID, "hs_l0u3B51") {
s.server.semaphore[SemaphoreID] = NewSemaphore(SemaphoreID, 32) s.server.semaphore[SemaphoreID] = NewSemaphore(s.server, SemaphoreID, 32)
if strings.HasSuffix(SemaphoreID, "3") {
s.server.raviente.state.semaphoreID = s.server.semaphore[SemaphoreID].id
} else if strings.HasSuffix(SemaphoreID, "4") {
s.server.raviente.support.semaphoreID = s.server.semaphore[SemaphoreID].id
} else if strings.HasSuffix(SemaphoreID, "5") {
s.server.raviente.register.semaphoreID = s.server.semaphore[SemaphoreID].id
}
} else { } else {
s.server.semaphore[SemaphoreID] = NewSemaphore(SemaphoreID, 1) s.server.semaphore[SemaphoreID] = NewSemaphore(s.server, SemaphoreID, 1)
} }
newSemaphore = s.server.semaphore[SemaphoreID] newSemaphore = s.server.semaphore[SemaphoreID]
s.server.semaphoreLock.Unlock() s.server.semaphoreLock.Unlock()
@@ -98,35 +105,18 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
newSemaphore.Lock() newSemaphore.Lock()
defer newSemaphore.Unlock() defer newSemaphore.Unlock()
if _, exists := newSemaphore.reservedClientSlots[s.charID]; exists { if _, exists := newSemaphore.reservedClientSlots[s.charID]; exists {
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x1D}) bf := byteframe.NewByteFrame()
bf.WriteUint32(newSemaphore.id)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
} else if uint16(len(newSemaphore.reservedClientSlots)) < newSemaphore.maxPlayers { } else if uint16(len(newSemaphore.reservedClientSlots)) < newSemaphore.maxPlayers {
switch SemaphoreID { newSemaphore.reservedClientSlots[s.charID] = nil
case "hs_l0u3B51J9k3", "hs_l0u3B5129k3", "hs_l0u3B512Ak3": newSemaphore.clients[s] = s.charID
newSemaphore.reservedClientSlots[s.charID] = nil s.Lock()
newSemaphore.clients[s] = s.charID s.semaphore = newSemaphore
s.Lock() s.Unlock()
s.semaphore = newSemaphore bf := byteframe.NewByteFrame()
s.Unlock() bf.WriteUint32(newSemaphore.id)
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0E, 0x00, 0x1D}) doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
case "hs_l0u3B51J9k4", "hs_l0u3B5129k4", "hs_l0u3B512Ak4":
newSemaphore.reservedClientSlots[s.charID] = nil
s.Lock()
s.semaphore = newSemaphore
s.Unlock()
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0D, 0x00, 0x1D})
case "hs_l0u3B51J9k5", "hs_l0u3B5129k5", "hs_l0u3B512Ak5":
newSemaphore.reservedClientSlots[s.charID] = nil
s.Lock()
s.semaphore = newSemaphore
s.Unlock()
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0C, 0x00, 0x1D})
default:
newSemaphore.reservedClientSlots[s.charID] = nil
s.Lock()
s.semaphore = newSemaphore
s.Unlock()
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x25})
}
} else { } else {
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
} }
@@ -138,7 +128,6 @@ func handleMsgSysAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
func handleMsgSysReleaseSemaphore(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysReleaseSemaphore(s *Session, p mhfpacket.MHFPacket) {
//pkt := p.(*mhfpacket.MsgSysReleaseSemaphore) //pkt := p.(*mhfpacket.MsgSysReleaseSemaphore)
releaseRaviSemaphore(s)
} }
func handleMsgSysCheckSemaphore(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysCheckSemaphore(s *Session, p mhfpacket.MHFPacket) {

View File

@@ -86,7 +86,7 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
} }
} }
func removeEmptyStages(s *Session) { func destructEmptyStages(s *Session) {
s.server.Lock() s.server.Lock()
defer s.server.Unlock() defer s.server.Unlock()
for _, stage := range s.server.stages { for _, stage := range s.server.stages {
@@ -134,7 +134,8 @@ func removeSessionFromStage(s *Session) {
} }
} }
s.stage.Unlock() s.stage.Unlock()
removeEmptyStages(s) destructEmptyStages(s)
destructEmptySemaphores(s)
} }
func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) {

View File

@@ -71,8 +71,9 @@ type Server struct {
userBinaryParts map[userBinaryPartID][]byte userBinaryParts map[userBinaryPartID][]byte
// Semaphore // Semaphore
semaphoreLock sync.RWMutex semaphoreLock sync.RWMutex
semaphore map[string]*Semaphore semaphore map[string]*Semaphore
semaphoreIndex uint32
// Discord chat integration // Discord chat integration
discordBot *discordbot.DiscordBot discordBot *discordbot.DiscordBot
@@ -92,55 +93,58 @@ type Raviente struct {
} }
type RavienteRegister struct { type RavienteRegister struct {
nextTime uint32 semaphoreID uint32
startTime uint32 nextTime uint32
postTime uint32 startTime uint32
killedTime uint32 postTime uint32
killedTime uint32
ravienteType uint32 ravienteType uint32
maxPlayers uint32 maxPlayers uint32
carveQuest uint32 carveQuest uint32
register []uint32 register []uint32
} }
type RavienteState struct { type RavienteState struct {
semaphoreID uint32
damageMultiplier uint32 damageMultiplier uint32
stateData []uint32 stateData []uint32
} }
type RavienteSupport struct { type RavienteSupport struct {
semaphoreID uint32
supportData []uint32 supportData []uint32
} }
// Set up the Raviente variables for the server // Set up the Raviente variables for the server
func NewRaviente() *Raviente { func NewRaviente() *Raviente {
ravienteRegister := &RavienteRegister { ravienteRegister := &RavienteRegister{
nextTime: 0, nextTime: 0,
startTime: 0, startTime: 0,
killedTime: 0, killedTime: 0,
postTime: 0, postTime: 0,
ravienteType: 0, ravienteType: 0,
maxPlayers: 0, maxPlayers: 0,
carveQuest: 0, carveQuest: 0,
} }
ravienteState := &RavienteState { ravienteState := &RavienteState{
damageMultiplier: 1, damageMultiplier: 1,
} }
ravienteSupport := &RavienteSupport { } ravienteSupport := &RavienteSupport{}
ravienteRegister.register = []uint32{0, 0, 0, 0, 0} ravienteRegister.register = []uint32{0, 0, 0, 0, 0}
ravienteState.stateData = []uint32{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} ravienteState.stateData = []uint32{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}
ravienteSupport.supportData = []uint32{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} ravienteSupport.supportData = []uint32{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}
raviente := &Raviente { raviente := &Raviente{
register: ravienteRegister, register: ravienteRegister,
state: ravienteState, state: ravienteState,
support: ravienteSupport, support: ravienteSupport,
} }
return raviente return raviente
} }
// NewServer creates a new Server type. // NewServer creates a new Server type.
func NewServer(config *Config) *Server { func NewServer(config *Config) *Server {
s := &Server { s := &Server{
ID: config.ID, ID: config.ID,
logger: config.Logger, logger: config.Logger,
db: config.DB, db: config.DB,
@@ -151,6 +155,7 @@ func NewServer(config *Config) *Server {
stages: make(map[string]*Stage), stages: make(map[string]*Stage),
userBinaryParts: make(map[userBinaryPartID][]byte), userBinaryParts: make(map[userBinaryPartID][]byte),
semaphore: make(map[string]*Semaphore), semaphore: make(map[string]*Semaphore),
semaphoreIndex: 0,
discordBot: config.DiscordBot, discordBot: config.DiscordBot,
name: config.Name, name: config.Name,
enable: config.Enable, enable: config.Enable,
@@ -401,3 +406,8 @@ func (s *Server) FindStageObjectByChar(charID uint32) *StageObject {
return nil return nil
} }
func (s *Server) NextSemaphoreID() uint32 {
s.semaphoreIndex = s.semaphoreIndex + 1
return s.semaphoreIndex
}

View File

@@ -14,6 +14,8 @@ type Semaphore struct {
// Stage ID string // Stage ID string
id_semaphore string id_semaphore string
id uint32
// Map of session -> charID. // Map of session -> charID.
// These are clients that are CURRENTLY in the stage // These are clients that are CURRENTLY in the stage
clients map[*Session]uint32 clients map[*Session]uint32
@@ -26,21 +28,21 @@ type Semaphore struct {
} }
// NewStage creates a new stage with intialized values. // NewStage creates a new stage with intialized values.
func NewSemaphore(ID string, MaxPlayers uint16) *Semaphore { func NewSemaphore(s *Server, ID string, MaxPlayers uint16) *Semaphore {
s := &Semaphore{ sema := &Semaphore{
id_semaphore: ID, id_semaphore: ID,
id: s.NextSemaphoreID(),
clients: make(map[*Session]uint32), clients: make(map[*Session]uint32),
reservedClientSlots: make(map[uint32]interface{}), reservedClientSlots: make(map[uint32]interface{}),
maxPlayers: MaxPlayers, maxPlayers: MaxPlayers,
} }
return s return sema
} }
func (s *Semaphore) BroadcastRavi(pkt mhfpacket.MHFPacket) { func (s *Semaphore) BroadcastRavi(pkt mhfpacket.MHFPacket) {
// Broadcast the data. // Broadcast the data.
for session := range s.clients { for session := range s.clients {
// Make the header // Make the header
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint16(uint16(pkt.Opcode())) bf.WriteUint16(uint16(pkt.Opcode()))
@@ -71,4 +73,4 @@ func (s *Semaphore) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Sessio
// Enqueue in a non-blocking way that drops the packet if the connections send buffer channel is full. // Enqueue in a non-blocking way that drops the packet if the connections send buffer channel is full.
session.QueueSendNonBlocking(bf.Data()) session.QueueSendNonBlocking(bf.Data())
} }
} }