From ff5d32ef7f1751ff9f7858ddf2b8cf791138980d Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 26 Jul 2022 04:14:19 +1000 Subject: [PATCH] implement semaphore indexes --- .../mhfpacket/msg_sys_operate_register.go | 6 +- .../server/channelserver/handlers_register.go | 398 +++++++++--------- .../channelserver/handlers_semaphore.go | 141 +++---- Erupe/server/channelserver/handlers_stage.go | 5 +- .../channelserver/sys_channel_server.go | 56 ++- Erupe/server/channelserver/sys_semaphore.go | 12 +- 6 files changed, 305 insertions(+), 313 deletions(-) diff --git a/Erupe/network/mhfpacket/msg_sys_operate_register.go b/Erupe/network/mhfpacket/msg_sys_operate_register.go index 62e551d78..e4213d45d 100644 --- a/Erupe/network/mhfpacket/msg_sys_operate_register.go +++ b/Erupe/network/mhfpacket/msg_sys_operate_register.go @@ -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) diff --git a/Erupe/server/channelserver/handlers_register.go b/Erupe/server/channelserver/handlers_register.go index 7d8293cbe..4da6e9a8c 100644 --- a/Erupe/server/channelserver/handlers_register.go +++ b/Erupe/server/channelserver/handlers_register.go @@ -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) {} \ No newline at end of file +func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} diff --git a/Erupe/server/channelserver/handlers_semaphore.go b/Erupe/server/channelserver/handlers_semaphore.go index 117e46d4f..630105ea3 100644 --- a/Erupe/server/channelserver/handlers_semaphore.go +++ b/Erupe/server/channelserver/handlers_semaphore.go @@ -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) { diff --git a/Erupe/server/channelserver/handlers_stage.go b/Erupe/server/channelserver/handlers_stage.go index d7891ba7b..8f03dd4dd 100644 --- a/Erupe/server/channelserver/handlers_stage.go +++ b/Erupe/server/channelserver/handlers_stage.go @@ -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) { diff --git a/Erupe/server/channelserver/sys_channel_server.go b/Erupe/server/channelserver/sys_channel_server.go index 89bfa2584..6d6933062 100644 --- a/Erupe/server/channelserver/sys_channel_server.go +++ b/Erupe/server/channelserver/sys_channel_server.go @@ -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 +} diff --git a/Erupe/server/channelserver/sys_semaphore.go b/Erupe/server/channelserver/sys_semaphore.go index c923d4247..369e481b6 100644 --- a/Erupe/server/channelserver/sys_semaphore.go +++ b/Erupe/server/channelserver/sys_semaphore.go @@ -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()) } -} \ No newline at end of file +}