mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-12 23:14:36 +01:00
initial ravi-v3 commit
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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"])
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user