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,8 +9,70 @@ 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)
ref := &s.server.raviente.state.stateData[dest]
damageMultiplier := s.server.raviente.state.damageMultiplier
switch op {
case 2:
resp.WriteUint32(*ref)
if dest == 28 { // Berserk resurrection tracker
resp.WriteUint32(*ref + data)
*ref += data
} else if dest == 17 { // Berserk poison tracker
if damageMultiplier == 1 {
resp.WriteUint32(*ref + data)
*ref += data
} else {
resp.WriteUint32(*ref + data)
}
} else {
resp.WriteUint32(*ref + data*damageMultiplier)
*ref += data * damageMultiplier
}
case 13:
fallthrough
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} else if pkt.SemaphoreID == s.server.raviente.support.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)
ref := &s.server.raviente.support.supportData[dest]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + data)
*ref += data
case 13:
fallthrough
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} else if pkt.SemaphoreID == s.server.raviente.register.semaphoreID {
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 {
@@ -131,71 +192,6 @@ 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())
case 917533:
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)
ref := &s.server.raviente.state.stateData[dest]
damageMultiplier := s.server.raviente.state.damageMultiplier
switch op {
case 2:
resp.WriteUint32(*ref)
if dest == 28 { // Berserk resurrection tracker
resp.WriteUint32(*ref + data)
*ref += data
} else if dest == 17 { // Berserk poison tracker
if damageMultiplier == 1 {
resp.WriteUint32(*ref + data)
} else {
resp.WriteUint32(*ref + data)
*ref += data
}
} else {
resp.WriteUint32(*ref + data * damageMultiplier)
*ref += data * damageMultiplier
}
case 13:
fallthrough
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
case 851997:
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)
ref := &s.server.raviente.support.supportData[dest]
switch op {
case 2:
resp.WriteUint32(*ref)
resp.WriteUint32(*ref + data)
*ref += data
case 13:
fallthrough
case 14:
resp.WriteUint32(0)
resp.WriteUint32(data)
*ref = data
}
}
resp.WriteUint8(0)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
} }
s.notifyall() s.notifyall()
s.server.raviente.Unlock() s.server.raviente.Unlock()
@@ -206,13 +202,6 @@ func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) {
r := pkt.Unk1 r := pkt.Unk1
switch r { switch r {
case 12: 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 := byteframe.NewByteFrame()
resp.WriteUint8(0) resp.WriteUint8(0)
resp.WriteUint8(12) resp.WriteUint8(12)
@@ -248,31 +237,30 @@ func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) {
} }
} }
// 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

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 {
case "hs_l0u3B51J9k3", "hs_l0u3B5129k3", "hs_l0u3B512Ak3":
newSemaphore.reservedClientSlots[s.charID] = nil newSemaphore.reservedClientSlots[s.charID] = nil
newSemaphore.clients[s] = s.charID newSemaphore.clients[s] = s.charID
s.Lock() s.Lock()
s.semaphore = newSemaphore s.semaphore = newSemaphore
s.Unlock() s.Unlock()
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0E, 0x00, 0x1D}) bf := byteframe.NewByteFrame()
case "hs_l0u3B51J9k4", "hs_l0u3B5129k4", "hs_l0u3B512Ak4": bf.WriteUint32(newSemaphore.id)
newSemaphore.reservedClientSlots[s.charID] = nil doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
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

@@ -73,6 +73,7 @@ type Server struct {
// 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,6 +93,7 @@ type Raviente struct {
} }
type RavienteRegister struct { type RavienteRegister struct {
semaphoreID uint32
nextTime uint32 nextTime uint32
startTime uint32 startTime uint32
postTime uint32 postTime uint32
@@ -103,11 +105,13 @@ type RavienteRegister struct {
} }
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
} }
@@ -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()))