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
type MsgSysOperateRegister struct {
AckHandle uint32
RegisterID uint32
SemaphoreID uint32
fixedZero uint16
RawDataPayload []byte
}
@@ -24,7 +24,7 @@ func (m *MsgSysOperateRegister) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.RegisterID = bf.ReadUint32()
m.SemaphoreID = bf.ReadUint32()
m.fixedZero = bf.ReadUint16()
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.
func (m *MsgSysOperateRegister) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle)
bf.WriteUint32(m.RegisterID)
bf.WriteUint32(m.SemaphoreID)
bf.WriteUint16(0)
bf.WriteUint16(uint16(len(m.RawDataPayload)))
bf.WriteBytes(m.RawDataPayload)

View File

@@ -1,7 +1,6 @@
package channelserver
import (
"encoding/hex"
"erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket"
)
@@ -10,129 +9,7 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysOperateRegister)
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
s.server.raviente.Lock()
switch pkt.RegisterID {
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:
if pkt.SemaphoreID == s.server.raviente.state.semaphoreID {
resp := byteframe.NewByteFrame()
size := 6
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
if damageMultiplier == 1 {
resp.WriteUint32(*ref + data)
*ref += data
} else {
resp.WriteUint32(*ref + data)
*ref += data
}
} else {
resp.WriteUint32(*ref + data * damageMultiplier)
resp.WriteUint32(*ref + data*damageMultiplier)
*ref += data * damageMultiplier
}
case 13:
@@ -170,8 +47,7 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 851997:
} else if pkt.SemaphoreID == s.server.raviente.support.semaphoreID {
resp := byteframe.NewByteFrame()
size := 6
for i := 0; i < len(bf.Data())-1; i += size {
@@ -196,6 +72,126 @@ func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) {
}
resp.WriteUint8(0)
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.server.raviente.Unlock()
@@ -205,74 +201,66 @@ func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysLoadRegister)
r := pkt.Unk1
switch r {
case 12:
if pkt.RegisterID == 983077 {
data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
doAckBufFail(s, pkt.AckHandle, data)
} else if pkt.RegisterID == 983069 {
data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
doAckBufFail(s, pkt.AckHandle, data)
}
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
resp.WriteUint8(12)
resp.WriteUint32(s.server.raviente.register.nextTime)
resp.WriteUint32(s.server.raviente.register.startTime)
resp.WriteUint32(s.server.raviente.register.killedTime)
resp.WriteUint32(s.server.raviente.register.postTime)
resp.WriteUint32(s.server.raviente.register.register[0])
resp.WriteUint32(s.server.raviente.register.carveQuest)
resp.WriteUint32(s.server.raviente.register.register[1])
resp.WriteUint32(s.server.raviente.register.register[2])
resp.WriteUint32(s.server.raviente.register.register[3])
resp.WriteUint32(s.server.raviente.register.maxPlayers)
resp.WriteUint32(s.server.raviente.register.ravienteType)
resp.WriteUint32(s.server.raviente.register.register[4])
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 29:
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
resp.WriteUint8(29)
for _, v := range s.server.raviente.state.stateData {
resp.WriteUint32(v)
}
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 25:
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())
case 12:
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
resp.WriteUint8(12)
resp.WriteUint32(s.server.raviente.register.nextTime)
resp.WriteUint32(s.server.raviente.register.startTime)
resp.WriteUint32(s.server.raviente.register.killedTime)
resp.WriteUint32(s.server.raviente.register.postTime)
resp.WriteUint32(s.server.raviente.register.register[0])
resp.WriteUint32(s.server.raviente.register.carveQuest)
resp.WriteUint32(s.server.raviente.register.register[1])
resp.WriteUint32(s.server.raviente.register.register[2])
resp.WriteUint32(s.server.raviente.register.register[3])
resp.WriteUint32(s.server.raviente.register.maxPlayers)
resp.WriteUint32(s.server.raviente.register.ravienteType)
resp.WriteUint32(s.server.raviente.register.register[4])
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 29:
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
resp.WriteUint8(29)
for _, v := range s.server.raviente.state.stateData {
resp.WriteUint32(v)
}
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 25:
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() {
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 {
for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
session.QueueSend(raviNotif.Data())
}
} else if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
for session := range s.server.semaphore["hs_l0u3B5129k3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
session.QueueSend(raviNotif.Data())
}
} else if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
for session := range s.server.semaphore["hs_l0u3B512Ak3"].clients {
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D})
session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D})
session.QueueSend(raviNotif.Data())
}
}
}
@@ -288,27 +276,28 @@ func checkRaviSemaphore(s *Session) bool {
return false
}
func releaseRaviSemaphore(s *Session) {
s.server.raviente.Lock()
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
if len(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots) == 0 {
resetRavi(s)
}
}
if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
if len(s.server.semaphore["hs_l0u3B5129k3"].reservedClientSlots) == 0 {
resetRavi(s)
}
}
if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
if len(s.server.semaphore["hs_l0u3B512Ak3"].reservedClientSlots) == 0 {
resetRavi(s)
}
}
s.server.raviente.Unlock()
}
//func releaseRaviSemaphore(s *Session) {
// s.server.raviente.Lock()
// if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
// if len(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots) == 0 {
// resetRavi(s)
// }
// }
// if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
// if len(s.server.semaphore["hs_l0u3B5129k3"].reservedClientSlots) == 0 {
// resetRavi(s)
// }
// }
// if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
// if len(s.server.semaphore["hs_l0u3B512Ak3"].reservedClientSlots) == 0 {
// resetRavi(s)
// }
// }
// s.server.raviente.Unlock()
//}
func resetRavi(s *Session) {
s.server.raviente.Lock()
s.server.raviente.register.nextTime = 0
s.server.raviente.register.startTime = 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.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.Unlock()
}
// 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
import (
"erupe-ce/common/byteframe"
"fmt"
"go.uber.org/zap"
"strings"
"erupe-ce/network/mhfpacket"
@@ -10,11 +12,13 @@ import (
func removeSessionFromSemaphore(s *Session) {
s.server.semaphoreLock.Lock()
for _, semaphore := range s.server.semaphore {
if _, exists := semaphore.reservedClientSlots[s.charID]; exists {
delete(semaphore.reservedClientSlots, s.charID)
}
if _, exists := semaphore.clients[s]; exists {
delete(semaphore.clients, s)
}
}
releaseRaviSemaphore(s)
s.server.semaphoreLock.Unlock()
}
@@ -23,54 +27,50 @@ func handleMsgSysCreateSemaphore(s *Session, p mhfpacket.MHFPacket) {
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) {
pkt := p.(*mhfpacket.MsgSysDeleteSemaphore)
sem := pkt.AckHandle
if s.server.semaphore != nil {
destructEmptySemaphores(s)
s.server.semaphoreLock.Lock()
for id := range s.server.semaphore {
switch sem {
case 917533:
if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k3" {
delete(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots, s.charID)
delete(s.server.semaphore["hs_l0u3B51J9k3"].clients, s)
} 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)
}
for id, sema := range s.server.semaphore {
if sema.id == sem {
if strings.HasPrefix(id, "hs_l0u3B51") {
releaseRaviSemaphore(s, sema)
s.server.semaphoreLock.Unlock()
return
}
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()
@@ -81,15 +81,22 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysCreateAcquireSemaphore)
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)
if !gotNewStage {
if !exists {
s.server.semaphoreLock.Lock()
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 {
s.server.semaphore[SemaphoreID] = NewSemaphore(SemaphoreID, 1)
s.server.semaphore[SemaphoreID] = NewSemaphore(s.server, SemaphoreID, 1)
}
newSemaphore = s.server.semaphore[SemaphoreID]
s.server.semaphoreLock.Unlock()
@@ -98,35 +105,18 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
newSemaphore.Lock()
defer newSemaphore.Unlock()
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 {
switch SemaphoreID {
case "hs_l0u3B51J9k3", "hs_l0u3B5129k3", "hs_l0u3B512Ak3":
newSemaphore.reservedClientSlots[s.charID] = nil
newSemaphore.clients[s] = s.charID
s.Lock()
s.semaphore = newSemaphore
s.Unlock()
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0E, 0x00, 0x1D})
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})
}
newSemaphore.reservedClientSlots[s.charID] = nil
newSemaphore.clients[s] = s.charID
s.Lock()
s.semaphore = newSemaphore
s.Unlock()
bf := byteframe.NewByteFrame()
bf.WriteUint32(newSemaphore.id)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
} else {
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) {
//pkt := p.(*mhfpacket.MsgSysReleaseSemaphore)
releaseRaviSemaphore(s)
}
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()
defer s.server.Unlock()
for _, stage := range s.server.stages {
@@ -134,7 +134,8 @@ func removeSessionFromStage(s *Session) {
}
}
s.stage.Unlock()
removeEmptyStages(s)
destructEmptyStages(s)
destructEmptySemaphores(s)
}
func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) {

View File

@@ -71,8 +71,9 @@ type Server struct {
userBinaryParts map[userBinaryPartID][]byte
// Semaphore
semaphoreLock sync.RWMutex
semaphore map[string]*Semaphore
semaphoreLock sync.RWMutex
semaphore map[string]*Semaphore
semaphoreIndex uint32
// Discord chat integration
discordBot *discordbot.DiscordBot
@@ -92,55 +93,58 @@ type Raviente struct {
}
type RavienteRegister struct {
nextTime uint32
startTime uint32
postTime uint32
killedTime uint32
semaphoreID uint32
nextTime uint32
startTime uint32
postTime uint32
killedTime uint32
ravienteType uint32
maxPlayers uint32
carveQuest uint32
register []uint32
maxPlayers uint32
carveQuest uint32
register []uint32
}
type RavienteState struct {
semaphoreID uint32
damageMultiplier uint32
stateData []uint32
stateData []uint32
}
type RavienteSupport struct {
semaphoreID uint32
supportData []uint32
}
// Set up the Raviente variables for the server
func NewRaviente() *Raviente {
ravienteRegister := &RavienteRegister {
nextTime: 0,
startTime: 0,
killedTime: 0,
postTime: 0,
ravienteRegister := &RavienteRegister{
nextTime: 0,
startTime: 0,
killedTime: 0,
postTime: 0,
ravienteType: 0,
maxPlayers: 0,
carveQuest: 0,
maxPlayers: 0,
carveQuest: 0,
}
ravienteState := &RavienteState {
ravienteState := &RavienteState{
damageMultiplier: 1,
}
ravienteSupport := &RavienteSupport { }
ravienteSupport := &RavienteSupport{}
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}
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,
state: ravienteState,
support: ravienteSupport,
state: ravienteState,
support: ravienteSupport,
}
return raviente
}
// NewServer creates a new Server type.
func NewServer(config *Config) *Server {
s := &Server {
s := &Server{
ID: config.ID,
logger: config.Logger,
db: config.DB,
@@ -151,6 +155,7 @@ func NewServer(config *Config) *Server {
stages: make(map[string]*Stage),
userBinaryParts: make(map[userBinaryPartID][]byte),
semaphore: make(map[string]*Semaphore),
semaphoreIndex: 0,
discordBot: config.DiscordBot,
name: config.Name,
enable: config.Enable,
@@ -401,3 +406,8 @@ func (s *Server) FindStageObjectByChar(charID uint32) *StageObject {
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
id_semaphore string
id uint32
// Map of session -> charID.
// These are clients that are CURRENTLY in the stage
clients map[*Session]uint32
@@ -26,21 +28,21 @@ type Semaphore struct {
}
// NewStage creates a new stage with intialized values.
func NewSemaphore(ID string, MaxPlayers uint16) *Semaphore {
s := &Semaphore{
func NewSemaphore(s *Server, ID string, MaxPlayers uint16) *Semaphore {
sema := &Semaphore{
id_semaphore: ID,
id: s.NextSemaphoreID(),
clients: make(map[*Session]uint32),
reservedClientSlots: make(map[uint32]interface{}),
maxPlayers: MaxPlayers,
}
return s
return sema
}
func (s *Semaphore) BroadcastRavi(pkt mhfpacket.MHFPacket) {
// Broadcast the data.
for session := range s.clients {
// Make the header
bf := byteframe.NewByteFrame()
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.
session.QueueSendNonBlocking(bf.Data())
}
}
}