From 1685f409e711bfa10aec273921f3cfd5c8dbfb78 Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 27 Aug 2023 22:16:51 +1000 Subject: [PATCH] initial ravi-v3 commit --- network/mhfpacket/msg_sys_load_register.go | 4 +- network/mhfpacket/msg_sys_operate_register.go | 3 +- server/channelserver/handlers_cast_binary.go | 18 +- server/channelserver/handlers_register.go | 281 +++--------------- server/channelserver/sys_channel_server.go | 86 +++--- 5 files changed, 103 insertions(+), 289 deletions(-) diff --git a/network/mhfpacket/msg_sys_load_register.go b/network/mhfpacket/msg_sys_load_register.go index 730616d65..7e1ac5950 100644 --- a/network/mhfpacket/msg_sys_load_register.go +++ b/network/mhfpacket/msg_sys_load_register.go @@ -11,7 +11,7 @@ import ( type MsgSysLoadRegister struct { AckHandle uint32 RegisterID uint32 - Unk1 uint8 + Values uint8 } // Opcode returns the ID associated with this packet type. @@ -23,7 +23,7 @@ func (m *MsgSysLoadRegister) Opcode() network.PacketID { func (m *MsgSysLoadRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.RegisterID = bf.ReadUint32() - m.Unk1 = bf.ReadUint8() + m.Values = bf.ReadUint8() _ = bf.ReadUint8() _ = bf.ReadUint16() return nil diff --git a/network/mhfpacket/msg_sys_operate_register.go b/network/mhfpacket/msg_sys_operate_register.go index 6978609b1..c51a483e3 100644 --- a/network/mhfpacket/msg_sys_operate_register.go +++ b/network/mhfpacket/msg_sys_operate_register.go @@ -25,7 +25,8 @@ func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl m.SemaphoreID = bf.ReadUint32() _ = bf.ReadUint16() dataSize := bf.ReadUint16() - m.RawDataPayload = bf.ReadBytes(uint(dataSize)) + m.RawDataPayload = bf.ReadBytes(uint(dataSize) - 1) + _ = bf.ReadBytes(1) // Null terminator return nil } diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index d93cf1a04..bd6ea053c 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -263,32 +263,32 @@ func parseChatCommand(s *Session, command string) { sendServerChatMessage(s, s.server.dict["commandRaviNoCommand"]) } else { if strings.HasPrefix(command, "!ravi start") { - if s.server.raviente.register.startTime == 0 { - s.server.raviente.register.startTime = s.server.raviente.register.postTime + if s.server.raviente.register[1] == 0 { + s.server.raviente.register[1] = s.server.raviente.register[3] sendServerChatMessage(s, s.server.dict["commandRaviStartSuccess"]) s.notifyRavi() } else { sendServerChatMessage(s, s.server.dict["commandRaviStartError"]) } } else if strings.HasPrefix(command, "!ravi cm") || strings.HasPrefix(command, "!ravi checkmultiplier") { - sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRaviMultiplier"], s.server.raviente.GetRaviMultiplier(s.server))) + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRaviMultiplier"], s.server.GetRaviMultiplier())) } else if strings.HasPrefix(command, "!ravi sr") || strings.HasPrefix(command, "!ravi sendres") { - if s.server.raviente.state.stateData[28] > 0 { + if s.server.raviente.state[28] > 0 { sendServerChatMessage(s, s.server.dict["commandRaviResSuccess"]) - s.server.raviente.state.stateData[28] = 0 + s.server.raviente.state[28] = 0 } else { sendServerChatMessage(s, s.server.dict["commandRaviResError"]) } } else if strings.HasPrefix(command, "!ravi ss") || strings.HasPrefix(command, "!ravi sendsed") { sendServerChatMessage(s, s.server.dict["commandRaviSedSuccess"]) // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP + HP := s.server.raviente.state[0] + s.server.raviente.state[1] + s.server.raviente.state[2] + s.server.raviente.state[3] + s.server.raviente.state[4] + s.server.raviente.support[1] = HP } else if strings.HasPrefix(command, "!ravi rs") || strings.HasPrefix(command, "!ravi reqsed") { sendServerChatMessage(s, s.server.dict["commandRaviRequest"]) // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP + 12 + HP := s.server.raviente.state[0] + s.server.raviente.state[1] + s.server.raviente.state[2] + s.server.raviente.state[3] + s.server.raviente.state[4] + s.server.raviente.support[1] = HP + 12 } else { sendServerChatMessage(s, s.server.dict["commandRaviError"]) } diff --git a/server/channelserver/handlers_register.go b/server/channelserver/handlers_register.go index 33261a94e..be423d206 100644 --- a/server/channelserver/handlers_register.go +++ b/server/channelserver/handlers_register.go @@ -3,243 +3,69 @@ package channelserver import ( "erupe-ce/common/byteframe" "erupe-ce/network/mhfpacket" + "go.uber.org/zap" "strings" ) +type RaviUpdate struct { + Op uint8 + Dest uint8 + Data uint32 +} + func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysOperateRegister) + + var raviUpdates []RaviUpdate + var raviUpdate RaviUpdate bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) - s.server.raviente.Lock() - switch pkt.SemaphoreID { - case 4: - 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.GetRaviMultiplier(s.server) - 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) - } - } else { - data = uint32(float64(data) * damageMultiplier) - 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()) - case 5: - 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()) - case 6: - 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 + 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 + 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 + 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 + 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 + 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()) + for i := len(pkt.RawDataPayload) / 6; i > 0; i-- { + raviUpdate.Op = bf.ReadUint8() + raviUpdate.Dest = bf.ReadUint8() + raviUpdate.Data = bf.ReadUint32() + s.logger.Debug("RaviOps", zap.Uint8s("Op/Dest", []uint8{raviUpdate.Op, raviUpdate.Dest}), zap.Uint32s("Sema/Data", []uint32{pkt.SemaphoreID, raviUpdate.Data})) + raviUpdates = append(raviUpdates, raviUpdate) } + bf = byteframe.NewByteFrame() + + var _old, _new uint32 + s.server.raviente.Lock() + for _, update := range raviUpdates { + switch update.Op { + case 2: + _old, _new = s.server.UpdateRavi(pkt.SemaphoreID, update.Dest, update.Data, true) + case 13, 14: + _old, _new = s.server.UpdateRavi(pkt.SemaphoreID, update.Dest, update.Data, false) + } + bf.WriteUint8(1) + bf.WriteUint8(update.Dest) + bf.WriteUint32(_old) + bf.WriteUint32(_new) + } + s.server.raviente.Unlock() + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) + if s.server.erupeConfig.GameplayOptions.LowLatencyRaviente { s.notifyRavi() } - s.server.raviente.Unlock() } func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysLoadRegister) - r := pkt.Unk1 - switch r { - 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) + bf := byteframe.NewByteFrame() + bf.WriteUint8(0) + bf.WriteUint8(pkt.Values) + for i := uint8(0); i < pkt.Values; i++ { + switch pkt.RegisterID { + case 4: + bf.WriteUint32(s.server.raviente.state[i]) + case 5: + bf.WriteUint32(s.server.raviente.support[i]) + case 6: + bf.WriteUint32(s.server.raviente.register[i]) } - 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()) } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func (s *Session) notifyRavi() { @@ -282,18 +108,7 @@ func getRaviSemaphore(s *Server) *Semaphore { } 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 - s.server.raviente.register.postTime = 0 - s.server.raviente.register.ravienteType = 0 - s.server.raviente.register.maxPlayers = 0 - s.server.raviente.register.carveQuest = 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.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() + s.server.raviente = NewRaviente() } func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index cad64bbe4..6273a7939 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -76,61 +76,25 @@ type Server struct { type Raviente struct { sync.Mutex - - register *RavienteRegister - state *RavienteState - support *RavienteSupport + register []uint32 + state []uint32 + support []uint32 } -type RavienteRegister struct { - nextTime uint32 - startTime uint32 - postTime uint32 - killedTime uint32 - ravienteType uint32 - maxPlayers uint32 - carveQuest uint32 - register []uint32 -} - -type RavienteState struct { - stateData []uint32 -} - -type RavienteSupport struct { - supportData []uint32 -} - -// Set up the Raviente variables for the server func NewRaviente() *Raviente { - ravienteRegister := &RavienteRegister{ - nextTime: 0, - startTime: 0, - killedTime: 0, - postTime: 0, - ravienteType: 0, - maxPlayers: 0, - carveQuest: 0, - } - ravienteState := &RavienteState{} - 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{ - register: ravienteRegister, - state: ravienteState, - support: ravienteSupport, + register: make([]uint32, 30), + state: make([]uint32, 30), + support: make([]uint32, 30), } return raviente } -func (r *Raviente) GetRaviMultiplier(s *Server) float64 { +func (s *Server) GetRaviMultiplier() float64 { raviSema := getRaviSemaphore(s) if raviSema != nil { var minPlayers int - if r.register.maxPlayers > 8 { + if s.raviente.register[9] > 8 { minPlayers = 24 } else { minPlayers = 4 @@ -143,6 +107,40 @@ func (r *Raviente) GetRaviMultiplier(s *Server) float64 { return 0 } +func (s *Server) UpdateRavi(semaID uint32, index uint8, value uint32, update bool) (uint32, uint32) { + var prev uint32 + switch semaID { + case 4: + switch index { + case 17, 28: // Ignore res and poison + break + default: + value = uint32(float64(value) * s.GetRaviMultiplier()) + } + prev = s.raviente.state[index] + if prev != 0 && !update { + return prev, prev + } + s.raviente.state[index] += value + return prev, s.raviente.state[index] + case 5: + prev = s.raviente.support[index] + if prev != 0 && !update { + return prev, prev + } + s.raviente.support[index] += value + return prev, s.raviente.support[index] + case 6: + prev = s.raviente.register[index] + if prev != 0 && !update { + return prev, prev + } + s.raviente.register[index] += value + return prev, s.raviente.register[index] + } + return 0, 0 +} + // NewServer creates a new Server type. func NewServer(config *Config) *Server { s := &Server{