mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-05 17:47:05 +01:00
Merge branch 'main' into main
This commit is contained in:
@@ -12,6 +12,8 @@ type OperateMailOperation uint8
|
||||
|
||||
const (
|
||||
OPERATE_MAIL_DELETE = 0x01
|
||||
OPERATE_MAIL_LOCK = 0x02
|
||||
OPERATE_MAIL_UNLOCK = 0x03
|
||||
OPERATE_MAIL_ACQUIRE_ITEM = 0x05
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,14 @@ import (
|
||||
)
|
||||
|
||||
// MsgMhfTransitMessage represents the MSG_MHF_TRANSIT_MESSAGE
|
||||
type MsgMhfTransitMessage struct{}
|
||||
type MsgMhfTransitMessage struct {
|
||||
AckHandle uint32
|
||||
Unk0 uint8
|
||||
Unk1 uint8
|
||||
Unk2 uint16
|
||||
Unk3 uint16
|
||||
TargetID uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfTransitMessage) Opcode() network.PacketID {
|
||||
@@ -18,7 +25,13 @@ func (m *MsgMhfTransitMessage) Opcode() network.PacketID {
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfTransitMessage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.Unk1 = bf.ReadUint8()
|
||||
m.Unk2 = bf.ReadUint16()
|
||||
m.Unk3 = bf.ReadUint16()
|
||||
m.TargetID = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
|
||||
@@ -183,13 +183,12 @@ func logoutPlayer(s *Session) {
|
||||
return
|
||||
}
|
||||
|
||||
s.stage.RLock()
|
||||
for client := range s.stage.clients {
|
||||
client.QueueSendMHF(&mhfpacket.MsgSysDeleteUser{
|
||||
s.server.BroadcastMHF(&mhfpacket.MsgSysDeleteUser {
|
||||
CharID: s.charID,
|
||||
})
|
||||
}
|
||||
s.stage.RUnlock()
|
||||
}, s)
|
||||
|
||||
delete(s.server.sessions, s.rawConn)
|
||||
s.rawConn.Close()
|
||||
|
||||
if s.server.erupeConfig.DevModeOptions.ServerName != "" {
|
||||
_, err := s.server.db.Exec("UPDATE servers SET current_players=$1 WHERE server_name=$2", uint32(len(s.server.sessions)), s.server.erupeConfig.DevModeOptions.ServerName)
|
||||
@@ -198,13 +197,16 @@ func logoutPlayer(s *Session) {
|
||||
}
|
||||
}
|
||||
|
||||
removeSessionFromStage(s)
|
||||
s.server.Lock()
|
||||
for _, stage := range s.server.stages {
|
||||
if _, exists := stage.reservedClientSlots[s.charID]; exists {
|
||||
delete(stage.reservedClientSlots, s.charID)
|
||||
}
|
||||
}
|
||||
s.server.Unlock()
|
||||
|
||||
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
|
||||
if _, ok := s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots[s.charID]; ok {
|
||||
removeSessionFromSemaphore(s)
|
||||
}
|
||||
}
|
||||
removeSessionFromStage(s)
|
||||
|
||||
var timePlayed int
|
||||
err := s.server.db.QueryRow("SELECT time_played FROM characters WHERE id = $1", s.charID).Scan(&timePlayed)
|
||||
@@ -213,7 +215,7 @@ func logoutPlayer(s *Session) {
|
||||
|
||||
var rpGained int
|
||||
|
||||
if s.rights == 0x08091e4e || s.rights == 0x08091e0e { // N Course
|
||||
if s.rights > 0x40000000 { // N Course
|
||||
rpGained = timePlayed / 900
|
||||
timePlayed = timePlayed % 900
|
||||
} else {
|
||||
@@ -326,7 +328,13 @@ func handleMsgSysRightsReload(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
|
||||
func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) {}
|
||||
func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfTransitMessage)
|
||||
// TODO: figure out what this is supposed to return
|
||||
// probably what world+land the targeted character is on?
|
||||
// stubbed response will just say user not found
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
func handleMsgCaExchangeItem(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
@@ -699,241 +707,726 @@ func handleMsgMhfUpdateGuacot(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
|
||||
func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
pkt := p.(*mhfpacket.MsgMhfInfoScenarioCounter)
|
||||
|
||||
scenarioCounter := []struct {
|
||||
Unk0 uint32 // Main ID?
|
||||
Unk1 uint8
|
||||
Unk2 uint8
|
||||
MainID uint32
|
||||
Unk1 uint8 // Bool item exchange?
|
||||
// 0 = basic, 1 = veteran, 3 = other, 6 = pallone, 7 = diva
|
||||
CategoryID uint8
|
||||
}{
|
||||
//000000110000
|
||||
{
|
||||
Unk0: 0x00000000,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000011, Unk1: 0, CategoryID: 0,
|
||||
},
|
||||
// 0000005D0001
|
||||
{
|
||||
Unk0: 0x00000001,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x0000005D, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 0000005C0001
|
||||
{
|
||||
Unk0: 0x00000002,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x0000005C, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000510001
|
||||
{
|
||||
Unk0: 0x00000003,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000051, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 0000005B0001
|
||||
{
|
||||
Unk0: 0x00000004,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x0000005B, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 0000005A0001
|
||||
{
|
||||
Unk0: 0x00000005,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x0000005A, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000590001
|
||||
{
|
||||
Unk0: 0x00000006,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000059, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000580001
|
||||
{
|
||||
Unk0: 0x00000007,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000058, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000570001
|
||||
{
|
||||
Unk0: 0x00000008,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000057, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000560001
|
||||
{
|
||||
Unk0: 0x00000009,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000056, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000550001
|
||||
{
|
||||
Unk0: 0x0000000A,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000055, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000540001
|
||||
{
|
||||
Unk0: 0x0000000B,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000054, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000530001
|
||||
{
|
||||
Unk0: 0x0000000C,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000053, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000520001
|
||||
{
|
||||
Unk0: 0x0000000D,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000052, Unk1: 0, CategoryID: 1,
|
||||
},
|
||||
// 000000570103
|
||||
{
|
||||
Unk0: 0x0000000E,
|
||||
Unk1: 1,
|
||||
Unk2: 4,
|
||||
MainID: 0x00000057, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000580103
|
||||
{
|
||||
Unk0: 0x00000032,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000058, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000590103
|
||||
{
|
||||
Unk0: 0x00000033,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000059, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000005A0103
|
||||
{
|
||||
Unk0: 0x00000034,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000005A, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000005B0103
|
||||
{
|
||||
Unk0: 0x00000035,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000005B, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000005C0103
|
||||
{
|
||||
Unk0: 0x00000036,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000005C, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000530103
|
||||
{
|
||||
Unk0: 0x00000037,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000053, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000560103
|
||||
{
|
||||
Unk0: 0x00000038,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000056, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000003C0103
|
||||
{
|
||||
Unk0: 0x0000003A,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000003C, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000003A0103
|
||||
{
|
||||
Unk0: 0x0000003F,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000003A, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000003B0103
|
||||
{
|
||||
Unk0: 0x00000040,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000003B, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000001B0103
|
||||
{
|
||||
Unk0: 0x00000041,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000001B, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000190103
|
||||
{
|
||||
Unk0: 0x00000047,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000019, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000001A0103
|
||||
{
|
||||
Unk0: 0x0000004B,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000001A, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000170103
|
||||
{
|
||||
Unk0: 0x0000003D,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000017, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000020103
|
||||
{
|
||||
Unk0: 0x00000044,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000002, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000030103
|
||||
{
|
||||
Unk0: 0x00000042,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000003, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000040103
|
||||
{
|
||||
Unk0: 0x0000004C,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000004, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000001F0103
|
||||
{
|
||||
Unk0: 0x00000046,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x0000001F, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000200103
|
||||
{
|
||||
Unk0: 0x0000004D,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000020, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000210103
|
||||
{
|
||||
Unk0: 0x00000048,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000021, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000220103
|
||||
{
|
||||
Unk0: 0x0000004A,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000022, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000230103
|
||||
{
|
||||
Unk0: 0x00000049,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000023, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000240103
|
||||
{
|
||||
Unk0: 0x0000004E,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000024, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000250103
|
||||
{
|
||||
Unk0: 0x00000045,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000025, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000280103
|
||||
{
|
||||
Unk0: 0x0000003E,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000028, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000260103
|
||||
{
|
||||
Unk0: 0x0000004F,
|
||||
Unk1: 1,
|
||||
Unk2: 5,
|
||||
MainID: 0x00000026, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000270103
|
||||
{
|
||||
MainID: 0x00000027, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 000000300103
|
||||
{
|
||||
MainID: 0x00000030, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000000C0103
|
||||
{
|
||||
MainID: 0x0000000C, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000000D0103
|
||||
{
|
||||
MainID: 0x0000000D, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000001E0103
|
||||
{
|
||||
MainID: 0x0000001E, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000001D0103
|
||||
{
|
||||
MainID: 0x0000001D, Unk1: 1, CategoryID: 3,
|
||||
},
|
||||
// 0000002E0003
|
||||
{
|
||||
MainID: 0x0000002E, Unk1: 0, CategoryID: 3,
|
||||
},
|
||||
// 000000000004
|
||||
{
|
||||
MainID: 0x00000000, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000010004
|
||||
{
|
||||
MainID: 0x00000001, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000020004
|
||||
{
|
||||
MainID: 0x00000002, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000030004
|
||||
{
|
||||
MainID: 0x00000003, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000040004
|
||||
{
|
||||
MainID: 0x00000004, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000050004
|
||||
{
|
||||
MainID: 0x00000005, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000060004
|
||||
{
|
||||
MainID: 0x00000006, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000070004
|
||||
{
|
||||
MainID: 0x00000007, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000080004
|
||||
{
|
||||
MainID: 0x00000008, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000090004
|
||||
{
|
||||
MainID: 0x00000009, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 0000000A0004
|
||||
{
|
||||
MainID: 0x0000000A, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 0000000B0004
|
||||
{
|
||||
MainID: 0x0000000B, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 0000000C0004
|
||||
{
|
||||
MainID: 0x0000000C, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 0000000D0004
|
||||
{
|
||||
MainID: 0x0000000D, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 0000000E0004
|
||||
{
|
||||
MainID: 0x0000000E, Unk1: 0, CategoryID: 4,
|
||||
},
|
||||
// 000000320005
|
||||
{
|
||||
MainID: 0x00000032, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000330005
|
||||
{
|
||||
MainID: 0x00000033, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000340005
|
||||
{
|
||||
MainID: 0x00000034, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000350005
|
||||
{
|
||||
MainID: 0x00000035, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000360005
|
||||
{
|
||||
MainID: 0x00000036, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000370005
|
||||
{
|
||||
MainID: 0x00000037, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000380005
|
||||
{
|
||||
MainID: 0x00000038, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000003A0005
|
||||
{
|
||||
MainID: 0x0000003A, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000003F0005
|
||||
{
|
||||
MainID: 0x0000003F, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000400005
|
||||
{
|
||||
MainID: 0x00000040, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000410005
|
||||
{
|
||||
MainID: 0x00000041, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000430005
|
||||
{
|
||||
MainID: 0x00000043, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000470005
|
||||
{
|
||||
MainID: 0x00000047, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004B0005
|
||||
{
|
||||
MainID: 0x0000004B, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000003D0005
|
||||
{
|
||||
MainID: 0x0000003D, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000440005
|
||||
{
|
||||
MainID: 0x00000044, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000420005
|
||||
{
|
||||
MainID: 0x00000042, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004C0005
|
||||
{
|
||||
MainID: 0x0000004C, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000460005
|
||||
{
|
||||
MainID: 0x00000046, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004D0005
|
||||
{
|
||||
MainID: 0x0000004D, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000480005
|
||||
{
|
||||
MainID: 0x00000048, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004A0005
|
||||
{
|
||||
MainID: 0x0000004A, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000490005
|
||||
{
|
||||
MainID: 0x00000049, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004E0005
|
||||
{
|
||||
MainID: 0x0000004E, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000450005
|
||||
{
|
||||
MainID: 0x00000045, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000003E0005
|
||||
{
|
||||
MainID: 0x0000003E, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 0000004F0005
|
||||
{
|
||||
MainID: 0x0000004F, Unk1: 0, CategoryID: 5,
|
||||
},
|
||||
// 000000000106
|
||||
{
|
||||
MainID: 0x00000000, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000010106
|
||||
{
|
||||
MainID: 0x00000001, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000020106
|
||||
{
|
||||
MainID: 0x00000002, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000030106
|
||||
{
|
||||
MainID: 0x00000003, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000040106
|
||||
{
|
||||
MainID: 0x00000004, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000050106
|
||||
{
|
||||
MainID: 0x00000005, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000060106
|
||||
{
|
||||
MainID: 0x00000006, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000070106
|
||||
{
|
||||
MainID: 0x00000007, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000080106
|
||||
{
|
||||
MainID: 0x00000008, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000090106
|
||||
{
|
||||
MainID: 0x00000009, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000110106
|
||||
{
|
||||
MainID: 0x00000011, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000A0106
|
||||
{
|
||||
MainID: 0x0000000A, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000B0106
|
||||
{
|
||||
MainID: 0x0000000B, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000C0106
|
||||
{
|
||||
MainID: 0x0000000C, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000D0106
|
||||
{
|
||||
MainID: 0x0000000D, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000E0106
|
||||
{
|
||||
MainID: 0x0000000E, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 0000000F0106
|
||||
{
|
||||
MainID: 0x0000000F, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000100106
|
||||
{
|
||||
MainID: 0x00000010, Unk1: 1, CategoryID: 6,
|
||||
},
|
||||
// 000000320107
|
||||
{
|
||||
MainID: 0x00000032, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000350107
|
||||
{
|
||||
MainID: 0x00000035, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000003E0107
|
||||
{
|
||||
MainID: 0x0000003E, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000340107
|
||||
{
|
||||
MainID: 0x00000034, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000380107
|
||||
{
|
||||
MainID: 0x00000038, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000330107
|
||||
{
|
||||
MainID: 0x00000033, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000310107
|
||||
{
|
||||
MainID: 0x00000031, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000360107
|
||||
{
|
||||
MainID: 0x00000036, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000390107
|
||||
{
|
||||
MainID: 0x00000039, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000370107
|
||||
{
|
||||
MainID: 0x00000037, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000003D0107
|
||||
{
|
||||
MainID: 0x0000003D, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000003A0107
|
||||
{
|
||||
MainID: 0x0000003A, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000003C0107
|
||||
{
|
||||
MainID: 0x0000003C, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000003B0107
|
||||
{
|
||||
MainID: 0x0000003B, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002A0107
|
||||
{
|
||||
MainID: 0x0000002A, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000300107
|
||||
{
|
||||
MainID: 0x00000030, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000280107
|
||||
{
|
||||
MainID: 0x00000028, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000270107
|
||||
{
|
||||
MainID: 0x00000027, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002B0107
|
||||
{
|
||||
MainID: 0x0000002B, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002E0107
|
||||
{
|
||||
MainID: 0x0000002E, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000290107
|
||||
{
|
||||
MainID: 0x00000029, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002C0107
|
||||
{
|
||||
MainID: 0x0000002C, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002D0107
|
||||
{
|
||||
MainID: 0x0000002D, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000002F0107
|
||||
{
|
||||
MainID: 0x0000002F, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000250107
|
||||
{
|
||||
MainID: 0x00000025, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000220107
|
||||
{
|
||||
MainID: 0x00000022, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000210107
|
||||
{
|
||||
MainID: 0x00000021, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000200107
|
||||
{
|
||||
MainID: 0x00000020, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001C0107
|
||||
{
|
||||
MainID: 0x0000001C, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001A0107
|
||||
{
|
||||
MainID: 0x0000001A, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000240107
|
||||
{
|
||||
MainID: 0x00000024, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000260107
|
||||
{
|
||||
MainID: 0x00000026, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000230107
|
||||
{
|
||||
MainID: 0x00000023, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001B0107
|
||||
{
|
||||
MainID: 0x0000001B, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001E0107
|
||||
{
|
||||
MainID: 0x0000001E, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001F0107
|
||||
{
|
||||
MainID: 0x0000001F, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 0000001D0107
|
||||
{
|
||||
MainID: 0x0000001D, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000180107
|
||||
{
|
||||
MainID: 0x00000018, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000170107
|
||||
{
|
||||
MainID: 0x00000017, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000160107
|
||||
{
|
||||
MainID: 0x00000016, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000150107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000015, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000190107
|
||||
{
|
||||
MainID: 0x00000019, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000140107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000014, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000070107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000007, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000090107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000009, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000D0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000D, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000100107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000010, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000C0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000C, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000E0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000E, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000F0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000F, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000130107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000013, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000A0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000A, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000080107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000008, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 0000000B0107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x0000000B, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000120107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000012, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000110107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000011, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000060107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000006, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000050107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000005, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000040107
|
||||
// Missing file
|
||||
// {
|
||||
// MainID: 0x00000004, Unk1: 1, CategoryID: 7,
|
||||
// },
|
||||
// 000000030107
|
||||
{
|
||||
MainID: 0x00000003, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000020107
|
||||
{
|
||||
MainID: 0x00000002, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000010107
|
||||
{
|
||||
MainID: 0x00000001, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
// 000000000107
|
||||
{
|
||||
MainID: 0x00000000, Unk1: 1, CategoryID: 7,
|
||||
},
|
||||
}
|
||||
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint8(uint8(len(scenarioCounter))) // Entry count
|
||||
for _, entry := range scenarioCounter {
|
||||
resp.WriteUint32(entry.Unk0)
|
||||
resp.WriteUint32(entry.MainID)
|
||||
resp.WriteUint8(entry.Unk1)
|
||||
resp.WriteUint8(entry.Unk2)
|
||||
resp.WriteUint8(entry.CategoryID)
|
||||
}
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
|
||||
// DEBUG, DELETE ME!
|
||||
/*
|
||||
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "debug/info_scenario_counter_resp.bin"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
func handleMsgMhfGetBbsSnsStatus(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
@@ -22,7 +22,7 @@ const (
|
||||
const (
|
||||
BroadcastTypeTargeted = 0x01
|
||||
BroadcastTypeStage = 0x03
|
||||
BroadcastTypeRavi = 0x06
|
||||
BroadcastTypeSemaphore = 0x06
|
||||
BroadcastTypeWorld = 0x0a
|
||||
)
|
||||
|
||||
@@ -93,10 +93,24 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.server.BroadcastMHF(resp, s)
|
||||
case BroadcastTypeStage:
|
||||
s.stage.BroadcastMHF(resp, s)
|
||||
case BroadcastTypeRavi:
|
||||
case BroadcastTypeSemaphore:
|
||||
if pkt.MessageType == 1 {
|
||||
session := s.server.semaphore["hs_l0u3B51J9k3"]
|
||||
var session *Semaphore
|
||||
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
|
||||
session = s.server.semaphore["hs_l0u3B51J9k3"]
|
||||
} else if _, exists := s.server.semaphore["hs_l0u3B5129k3"]; exists {
|
||||
session = s.server.semaphore["hs_l0u3B5129k3"]
|
||||
} else if _, exists := s.server.semaphore["hs_l0u3B512Ak3"]; exists {
|
||||
session = s.server.semaphore["hs_l0u3B512Ak3"]
|
||||
}
|
||||
(*session).BroadcastMHF(resp, s)
|
||||
} else {
|
||||
s.Lock()
|
||||
haveStage := s.stage != nil
|
||||
if haveStage {
|
||||
s.stage.BroadcastMHF(resp, s)
|
||||
}
|
||||
s.Unlock()
|
||||
}
|
||||
case BroadcastTypeTargeted:
|
||||
for _, targetID := range (*msgBinTargeted).TargetCharIDs {
|
||||
@@ -133,113 +147,66 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message)
|
||||
}
|
||||
|
||||
// RAVI COMMANDS
|
||||
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
|
||||
s.server.semaphoreLock.Lock()
|
||||
getSemaphore := s.server.semaphore["hs_l0u3B51J9k3"]
|
||||
s.server.semaphoreLock.Unlock()
|
||||
if _, exists := getSemaphore.reservedClientSlots[s.charID]; exists {
|
||||
if strings.HasPrefix(chatMessage.Message, "!ravistart") {
|
||||
row := s.server.db.QueryRow("SELECT raviposttime, ravistarted FROM raviregister WHERE refid = 12")
|
||||
var raviPosted, raviStarted uint32
|
||||
err := row.Scan(&raviPosted, &raviStarted)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
if raviStarted == 0 {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Raviente will start in less than 10 seconds"))
|
||||
s.server.db.Exec("UPDATE raviregister SET ravistarted = $1", raviPosted)
|
||||
// RAVI COMMANDS V2
|
||||
if strings.HasPrefix(chatMessage.Message, "!ravi") {
|
||||
if checkRaviSemaphore(s) {
|
||||
s.server.raviente.Lock()
|
||||
if !strings.HasPrefix(chatMessage.Message, "!ravi ") {
|
||||
sendServerChatMessage(s, "No Raviente command specified!")
|
||||
} else {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Raviente has already started"))
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(chatMessage.Message, "!bressend") {
|
||||
row := s.server.db.QueryRow("SELECT unknown20 FROM ravistate WHERE refid = 29")
|
||||
var berserkRes uint32
|
||||
err := row.Scan(&berserkRes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
if berserkRes > 0 {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Sending ressurection support"))
|
||||
s.server.db.Exec("UPDATE ravistate SET unknown20 = $1", 0)
|
||||
if strings.HasPrefix(chatMessage.Message, "!ravi start") {
|
||||
if s.server.raviente.register.startTime == 0 {
|
||||
s.server.raviente.register.startTime = s.server.raviente.register.postTime
|
||||
sendServerChatMessage(s, "The Great Slaying will begin in a moment")
|
||||
s.notifyall()
|
||||
} else {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Ressurection support has not been requested"))
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(chatMessage.Message, "!bsedsend") {
|
||||
hprow := s.server.db.QueryRow("SELECT phase1hp, phase2hp, phase3hp, phase4hp, phase5hp FROM ravistate WHERE refid = 29")
|
||||
var phase1HP, phase2HP, phase3HP, phase4HP, phase5HP uint32
|
||||
hperr := hprow.Scan(&phase1HP, &phase2HP, &phase3HP, &phase4HP, &phase5HP)
|
||||
if hperr != nil {
|
||||
panic(hperr)
|
||||
return
|
||||
}
|
||||
row := s.server.db.QueryRow("SELECT support2 FROM ravisupport WHERE refid = 25")
|
||||
var berserkTranq uint32
|
||||
err := row.Scan(&berserkTranq)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
sendServerChatMessage(s, fmt.Sprintf("Sending sedation support if requested"))
|
||||
s.server.db.Exec("UPDATE ravisupport SET support2 = $1", (phase1HP + phase2HP + phase3HP + phase4HP + phase5HP))
|
||||
}
|
||||
if strings.HasPrefix(chatMessage.Message, "!bsedreq") {
|
||||
hprow := s.server.db.QueryRow("SELECT phase1hp, phase2hp, phase3hp, phase4hp, phase5hp FROM ravistate WHERE refid = 29")
|
||||
var phase1HP, phase2HP, phase3HP, phase4HP, phase5HP uint32
|
||||
hperr := hprow.Scan(&phase1HP, &phase2HP, &phase3HP, &phase4HP, &phase5HP)
|
||||
if hperr != nil {
|
||||
panic(hperr)
|
||||
return
|
||||
}
|
||||
row := s.server.db.QueryRow("SELECT support2 FROM ravisupport WHERE refid = 25")
|
||||
var berserkTranq uint32
|
||||
err := row.Scan(&berserkTranq)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
sendServerChatMessage(s, fmt.Sprintf("Requesting sedation support"))
|
||||
s.server.db.Exec("UPDATE ravisupport SET support2 = $1", ((phase1HP + phase2HP + phase3HP + phase4HP + phase5HP) + 12))
|
||||
}
|
||||
if strings.HasPrefix(chatMessage.Message, "!setmultiplier ") {
|
||||
var num uint8
|
||||
n, numerr := fmt.Sscanf(chatMessage.Message, "!setmultiplier %d", &num)
|
||||
row := s.server.db.QueryRow("SELECT damagemultiplier FROM ravistate WHERE refid = 29")
|
||||
var damageMultiplier uint32
|
||||
err := row.Scan(&damageMultiplier)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
sendServerChatMessage(s, "The Great Slaying has already begun!")
|
||||
}
|
||||
} else if strings.HasPrefix(chatMessage.Message, "!ravi sm") || strings.HasPrefix(chatMessage.Message, "!ravi setmultiplier") {
|
||||
var num uint16
|
||||
n, numerr := fmt.Sscanf(chatMessage.Message, "!ravi sm %d", &num)
|
||||
if numerr != nil || n != 1 {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Please use the format !setmultiplier x"))
|
||||
} else if damageMultiplier == 1 {
|
||||
if num > 20 {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Max multiplier for Ravi is 20, setting to this value"))
|
||||
s.server.db.Exec("UPDATE ravistate SET damagemultiplier = $1", 20)
|
||||
sendServerChatMessage(s, "Error in command. Format: !ravi sm n")
|
||||
} else if s.server.raviente.state.damageMultiplier == 1 {
|
||||
if num > 65535 {
|
||||
sendServerChatMessage(s, "Raviente multiplier too high, defaulting to 20x")
|
||||
s.server.raviente.state.damageMultiplier = 65535
|
||||
} else {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Setting Ravi damage multiplier to %d", num))
|
||||
s.server.db.Exec("UPDATE ravistate SET damagemultiplier = $1", num)
|
||||
sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier set to %dx", num))
|
||||
s.server.raviente.state.damageMultiplier = uint32(num)
|
||||
}
|
||||
} else {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Multiplier can only be set once, please restart Ravi to set again"))
|
||||
sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is already set to %dx!", s.server.raviente.state.damageMultiplier))
|
||||
}
|
||||
} else if strings.HasPrefix(chatMessage.Message, "!ravi cm") || strings.HasPrefix(chatMessage.Message, "!ravi checkmultiplier") {
|
||||
sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.state.damageMultiplier))
|
||||
} else if strings.HasPrefix(chatMessage.Message, "!ravi sr") || strings.HasPrefix(chatMessage.Message, "!ravi sendres") {
|
||||
if s.server.raviente.state.stateData[28] > 0 {
|
||||
sendServerChatMessage(s, "Sending resurrection support!")
|
||||
s.server.raviente.state.stateData[28] = 0
|
||||
} else {
|
||||
sendServerChatMessage(s, "Resurrection support has not been requested!")
|
||||
}
|
||||
} else if strings.HasPrefix(chatMessage.Message, "!ravi ss") || strings.HasPrefix(chatMessage.Message, "!ravi sendsed") {
|
||||
sendServerChatMessage(s, "Sending sedation support if requested!")
|
||||
// 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
|
||||
} else if strings.HasPrefix(chatMessage.Message, "!ravi rs") || strings.HasPrefix(chatMessage.Message, "!ravi reqsed") {
|
||||
sendServerChatMessage(s, "Requesting sedation support!")
|
||||
// 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
|
||||
} else {
|
||||
sendServerChatMessage(s, "Raviente command not recognised!")
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(chatMessage.Message, "!checkmultiplier") {
|
||||
var damageMultiplier uint32
|
||||
row := s.server.db.QueryRow("SELECT damagemultiplier FROM ravistate WHERE refid = 29").Scan(&damageMultiplier)
|
||||
if row != nil {
|
||||
return
|
||||
} else {
|
||||
sendServerChatMessage(s, "No one has joined the Great Slaying!")
|
||||
}
|
||||
sendServerChatMessage(s, fmt.Sprintf("Ravi's current damage multiplier is %d", damageMultiplier))
|
||||
s.server.raviente.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
// END OF RAVI COMMANDS
|
||||
// END RAVI COMMANDS V2
|
||||
|
||||
if strings.HasPrefix(chatMessage.Message, "!tele ") {
|
||||
var x, y int16
|
||||
|
||||
@@ -128,16 +128,5 @@ func (save *CharacterSaveData) updateStructWithSaveData() {
|
||||
|
||||
func handleMsgMhfSexChanger(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfSexChanger)
|
||||
if pkt.Gender == 0 {
|
||||
_, err := s.server.db.Exec("UPDATE characters SET is_female=true WHERE id=$1", s.charID)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update gender in db", zap.Error(err))
|
||||
}
|
||||
} else {
|
||||
_, err := s.server.db.Exec("UPDATE characters SET is_female=false WHERE id=$1", s.charID)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update gender in db", zap.Error(err))
|
||||
}
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"github.com/Solenataris/Erupe/common/bfutil"
|
||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||
"github.com/Solenataris/Erupe/server/channelserver/compression/deltacomp"
|
||||
@@ -32,17 +33,16 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.logger.Fatal("Failed to decompress diff", zap.Error(err))
|
||||
}
|
||||
// Perform diff.
|
||||
characterSaveData.SetBaseSaveData(deltacomp.ApplyDataDiff(diff, characterSaveData.BaseSaveData()))
|
||||
s.logger.Info("Diffing...")
|
||||
characterSaveData.SetBaseSaveData(deltacomp.ApplyDataDiff(diff, characterSaveData.BaseSaveData()))
|
||||
} else {
|
||||
// Regular blob update.
|
||||
saveData, err := nullcomp.Decompress(pkt.RawDataPayload)
|
||||
|
||||
characterSaveData.SetBaseSaveData(saveData)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to decompress savedata from packet", zap.Error(err))
|
||||
}
|
||||
s.logger.Info("Updating save with blob")
|
||||
characterSaveData.SetBaseSaveData(saveData)
|
||||
}
|
||||
characterSaveData.IsNewCharacter = false
|
||||
characterBaseSaveData := characterSaveData.BaseSaveData()
|
||||
@@ -193,7 +193,10 @@ func handleMsgMhfLoaddata(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfSaveScenarioData)
|
||||
|
||||
_, err := s.server.db.Exec("UPDATE characters SET scenariodata = $1 WHERE characters.id = $2", pkt.RawDataPayload, int(s.charID))
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update scenario data in db", zap.Error(err))
|
||||
}
|
||||
// Do this ack manually because it uses a non-(0|1) error code
|
||||
s.QueueSendMHF(&mhfpacket.MsgSysAck{
|
||||
AckHandle: pkt.AckHandle,
|
||||
@@ -205,7 +208,19 @@ func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfLoadScenarioData)
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||
var scenarioData []byte
|
||||
bf := byteframe.NewByteFrame()
|
||||
err := s.server.db.QueryRow("SELECT scenariodata FROM characters WHERE characters.id = $1", int(s.charID)).Scan(&scenarioData)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to get scenario data contents in db", zap.Error(err))
|
||||
} else {
|
||||
if len(scenarioData) == 0 {
|
||||
bf.WriteUint32(0x00)
|
||||
} else {
|
||||
bf.WriteBytes(scenarioData)
|
||||
}
|
||||
}
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGetPaperData(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
@@ -26,7 +26,6 @@ type ItemDist struct {
|
||||
func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfEnumerateDistItem)
|
||||
bf := byteframe.NewByteFrame()
|
||||
|
||||
distCount := 0
|
||||
dists, err := s.server.db.Queryx(`
|
||||
SELECT d.id, event_name, description, times_acceptable,
|
||||
@@ -55,7 +54,6 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
if err != nil {
|
||||
s.logger.Error("Error parsing item distribution data", zap.Error(err))
|
||||
}
|
||||
|
||||
bf.WriteUint32(distData.ID)
|
||||
bf.WriteUint32(distData.Deadline)
|
||||
bf.WriteUint32(0) // Unk
|
||||
@@ -119,18 +117,15 @@ func handleMsgMhfAcquireDistItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfGetDistDescription(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetDistDescription)
|
||||
|
||||
var itemDesc string
|
||||
err := s.server.db.QueryRow("SELECT description FROM distribution WHERE id = $1", pkt.DistributionID).Scan(&itemDesc)
|
||||
|
||||
var desc string
|
||||
err := s.server.db.QueryRow("SELECT description FROM distribution WHERE id = $1", pkt.DistributionID).Scan(&desc)
|
||||
if err != nil {
|
||||
s.logger.Error("Error parsing item distribution description", zap.Error(err))
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
bf := byteframe.NewByteFrame()
|
||||
description, _ := stringsupport.ConvertUTF8ToShiftJIS(itemDesc)
|
||||
description, _ := stringsupport.ConvertUTF8ToShiftJIS(desc)
|
||||
bf.WriteUint16(uint16(len(description)+1))
|
||||
bf.WriteNullTerminatedBytes(description)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/Solenataris/Erupe/common/stringsupport"
|
||||
"github.com/Solenataris/Erupe/network/binpacket"
|
||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
@@ -19,9 +18,10 @@ type Mail struct {
|
||||
Body string `db:"body"`
|
||||
Read bool `db:"read"`
|
||||
Deleted bool `db:"deleted"`
|
||||
Locked bool `db:"locked"`
|
||||
AttachedItemReceived bool `db:"attached_item_received"`
|
||||
AttachedItemID *uint16 `db:"attached_item"`
|
||||
AttachedItemAmount int16 `db:"attached_item_amount"`
|
||||
AttachedItemID uint16 `db:"attached_item"`
|
||||
AttachedItemAmount uint16 `db:"attached_item_amount"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
IsGuildInvite bool `db:"is_guild_invite"`
|
||||
SenderName string `db:"sender_name"`
|
||||
@@ -49,8 +49,8 @@ func (m *Mail) Send(s *Session, transaction *sql.Tx) error {
|
||||
zap.Uint32("recipientID", m.RecipientID),
|
||||
zap.String("subject", m.Subject),
|
||||
zap.String("body", m.Body),
|
||||
zap.Uint16p("itemID", m.AttachedItemID),
|
||||
zap.Int16("itemAmount", m.AttachedItemAmount),
|
||||
zap.Uint16("itemID", m.AttachedItemID),
|
||||
zap.Uint16("itemAmount", m.AttachedItemAmount),
|
||||
zap.Bool("isGuildInvite", m.IsGuildInvite),
|
||||
)
|
||||
return err
|
||||
@@ -110,6 +110,23 @@ func (m *Mail) MarkAcquired(s *Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mail) MarkLocked(s *Session, locked bool) error {
|
||||
_, err := s.server.db.Exec(`
|
||||
UPDATE mail SET locked = $1 WHERE id = $2
|
||||
`, locked, m.ID)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error(
|
||||
"failed to mark mail as locked",
|
||||
zap.Error(err),
|
||||
zap.Int("mailID", m.ID),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
||||
rows, err := s.server.db.Queryx(`
|
||||
SELECT
|
||||
@@ -124,6 +141,7 @@ func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
||||
m.created_at,
|
||||
m.is_guild_invite,
|
||||
m.deleted,
|
||||
m.locked,
|
||||
c.name as sender_name
|
||||
FROM mail m
|
||||
JOIN characters c ON c.id = m.sender_id
|
||||
@@ -171,6 +189,7 @@ func GetMailByID(s *Session, ID int) (*Mail, error) {
|
||||
m.created_at,
|
||||
m.is_guild_invite,
|
||||
m.deleted,
|
||||
m.locked,
|
||||
c.name as sender_name
|
||||
FROM mail m
|
||||
JOIN characters c ON c.id = m.sender_id
|
||||
@@ -255,8 +274,9 @@ func handleMsgMhfReadMail(s *Session, p mhfpacket.MHFPacket) {
|
||||
_ = mail.MarkRead(s)
|
||||
|
||||
bf := byteframe.NewByteFrame()
|
||||
bodyBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(mail.Body)
|
||||
bf.WriteNullTerminatedBytes(bodyBytes)
|
||||
|
||||
body := s.clientContext.StrConv.MustEncode(mail.Body)
|
||||
bf.WriteNullTerminatedBytes(body)
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
@@ -286,9 +306,10 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.mailList[accIndex] = m.ID
|
||||
s.mailAccIndex++
|
||||
|
||||
itemAttached := m.AttachedItemID != nil
|
||||
subjectBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(m.Subject)
|
||||
senderNameBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(m.SenderName)
|
||||
|
||||
itemAttached := m.AttachedItemID != 0
|
||||
subject := s.clientContext.StrConv.MustEncode(m.Subject)
|
||||
sender := s.clientContext.StrConv.MustEncode(m.SenderName)
|
||||
|
||||
msg.WriteUint32(m.SenderID)
|
||||
msg.WriteUint32(uint32(m.CreatedAt.Unix()))
|
||||
@@ -302,28 +323,34 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
|
||||
flags |= 0x01
|
||||
}
|
||||
|
||||
if m.AttachedItemReceived {
|
||||
if m.Locked {
|
||||
flags |= 0x02
|
||||
}
|
||||
|
||||
// System message, hides ID
|
||||
// flags |= 0x04
|
||||
|
||||
// Mitigate game crash
|
||||
flags |= 0x08
|
||||
if m.AttachedItemReceived {
|
||||
// flags |= 0x08
|
||||
}
|
||||
|
||||
if m.IsGuildInvite {
|
||||
// Guild Invite
|
||||
flags |= 0x10
|
||||
|
||||
// System message?
|
||||
flags |= 0x04
|
||||
}
|
||||
|
||||
msg.WriteUint8(flags)
|
||||
msg.WriteBool(itemAttached)
|
||||
msg.WriteUint8(uint8(len(subjectBytes)+1))
|
||||
msg.WriteUint8(uint8(len(senderNameBytes)+1))
|
||||
msg.WriteNullTerminatedBytes(subjectBytes)
|
||||
msg.WriteNullTerminatedBytes(senderNameBytes)
|
||||
msg.WriteUint8(uint8(len(subject)+1))
|
||||
msg.WriteUint8(uint8(len(sender)+1))
|
||||
msg.WriteNullTerminatedBytes(subject)
|
||||
msg.WriteNullTerminatedBytes(sender)
|
||||
|
||||
// TODO: The game will crash if it attempts to receive items
|
||||
if itemAttached {
|
||||
msg.WriteInt16(m.AttachedItemAmount)
|
||||
msg.WriteUint16(*m.AttachedItemID)
|
||||
msg.WriteUint16(m.AttachedItemAmount)
|
||||
msg.WriteUint16(m.AttachedItemID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +374,18 @@ func handleMsgMhfOprtMail(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||
panic(err)
|
||||
}
|
||||
case mhfpacket.OPERATE_MAIL_LOCK:
|
||||
err = mail.MarkLocked(s, true)
|
||||
if err != nil {
|
||||
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||
panic(err)
|
||||
}
|
||||
case mhfpacket.OPERATE_MAIL_UNLOCK:
|
||||
err = mail.MarkLocked(s, false)
|
||||
if err != nil {
|
||||
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||
panic(err)
|
||||
}
|
||||
case mhfpacket.OPERATE_MAIL_ACQUIRE_ITEM:
|
||||
err = mail.MarkAcquired(s)
|
||||
if err != nil {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,22 @@ package channelserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||
)
|
||||
|
||||
func removeSessionFromSemaphore(s *Session) {
|
||||
s.server.semaphoreLock.Lock()
|
||||
for _, semaphore := range s.server.semaphore {
|
||||
if _, exists := semaphore.clients[s]; exists {
|
||||
delete(semaphore.clients, s)
|
||||
}
|
||||
}
|
||||
releaseRaviSemaphore(s)
|
||||
s.server.semaphoreLock.Unlock()
|
||||
}
|
||||
|
||||
func handleMsgSysCreateSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysCreateSemaphore)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x03, 0x00, 0x0d})
|
||||
@@ -22,18 +34,40 @@ func handleMsgSysDeleteSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
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" {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -52,11 +86,7 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
fmt.Printf("Got reserve stage req, StageID: %v\n\n", SemaphoreID)
|
||||
if !gotNewStage {
|
||||
s.server.semaphoreLock.Lock()
|
||||
if SemaphoreID == "hs_l0u3B51J9k1" ||
|
||||
SemaphoreID == "hs_l0u3B51J9k2" ||
|
||||
SemaphoreID == "hs_l0u3B51J9k3" ||
|
||||
SemaphoreID == "hs_l0u3B51J9k4" ||
|
||||
SemaphoreID == "hs_l0u3B51J9k5" {
|
||||
if strings.HasPrefix(SemaphoreID, "hs_l0u3B51") {
|
||||
s.server.semaphore[SemaphoreID] = NewSemaphore(SemaphoreID, 32)
|
||||
} else {
|
||||
s.server.semaphore[SemaphoreID] = NewSemaphore(SemaphoreID, 1)
|
||||
@@ -68,24 +98,23 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
newSemaphore.Lock()
|
||||
defer newSemaphore.Unlock()
|
||||
if _, exists := newSemaphore.reservedClientSlots[s.charID]; exists {
|
||||
s.logger.Info("IS ALREADY EXIST !")
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x1D})
|
||||
} else if uint16(len(newSemaphore.reservedClientSlots)) < newSemaphore.maxPlayers {
|
||||
switch SemaphoreID {
|
||||
case "hs_l0u3B51J9k3":
|
||||
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":
|
||||
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":
|
||||
case "hs_l0u3B51J9k5", "hs_l0u3B5129k5", "hs_l0u3B512Ak5":
|
||||
newSemaphore.reservedClientSlots[s.charID] = nil
|
||||
s.Lock()
|
||||
s.semaphore = newSemaphore
|
||||
@@ -109,29 +138,16 @@ func handleMsgSysAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgSysReleaseSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
//pkt := p.(*mhfpacket.MsgSysReleaseSemaphore)
|
||||
if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists {
|
||||
reset := len(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots)
|
||||
if reset == 0 {
|
||||
s.server.db.Exec("CALL ravireset($1)", 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeSessionFromSemaphore(s *Session) {
|
||||
|
||||
s.server.semaphoreLock.Lock()
|
||||
for id := range s.server.semaphore {
|
||||
delete(s.server.semaphore[id].reservedClientSlots, s.charID)
|
||||
if id == "hs_l0u3B51J9k3" {
|
||||
delete(s.server.semaphore[id].clients, s)
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.server.semaphoreLock.Unlock()
|
||||
releaseRaviSemaphore(s)
|
||||
}
|
||||
|
||||
func handleMsgSysCheckSemaphore(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysCheckSemaphore)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
resp := []byte{0x00, 0x00, 0x00, 0x00}
|
||||
s.server.semaphoreLock.Lock()
|
||||
if _, exists := s.server.semaphore[pkt.StageID]; exists {
|
||||
resp = []byte{0x00, 0x00, 0x00, 0x01}
|
||||
}
|
||||
s.server.semaphoreLock.Unlock()
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, resp)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package channelserver
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"strings"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
@@ -11,13 +12,16 @@ import (
|
||||
|
||||
func handleMsgSysCreateStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysCreateStage)
|
||||
|
||||
s.server.stagesLock.Lock()
|
||||
s.server.Lock()
|
||||
defer s.server.Unlock()
|
||||
if _, exists := s.server.stages[pkt.StageID]; exists {
|
||||
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
} else {
|
||||
stage := NewStage(pkt.StageID)
|
||||
stage.maxPlayers = uint16(pkt.PlayerCount)
|
||||
s.server.stages[stage.id] = stage
|
||||
s.server.stagesLock.Unlock()
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
}
|
||||
|
||||
func handleMsgSysStageDestruct(s *Session, p mhfpacket.MHFPacket) {}
|
||||
@@ -64,30 +68,31 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
// Notify existing stage clients that this new client has entered.
|
||||
s.logger.Info("Sending MsgSysInsertUser")
|
||||
if s.stage != nil { // avoids lock up when using bed for dream quests
|
||||
s.stage.BroadcastMHF(&mhfpacket.MsgSysInsertUser{
|
||||
// Add character to everyone elses stage
|
||||
s.stage.BroadcastMHF(&mhfpacket.MsgSysInsertUser {
|
||||
CharID: s.charID,
|
||||
}, s)
|
||||
|
||||
// It seems to be acceptable to recast all MSG_SYS_SET_USER_BINARY messages so far,
|
||||
// players are still notified when a new player has joined the stage.
|
||||
// These extra messages may not be needed
|
||||
//s.stage.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary{
|
||||
// CharID: s.charID,
|
||||
// BinaryType: 1,
|
||||
//}, s)
|
||||
//s.stage.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary{
|
||||
// CharID: s.charID,
|
||||
// BinaryType: 2,
|
||||
//}, s)
|
||||
//s.stage.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary{
|
||||
// CharID: s.charID,
|
||||
// BinaryType: 3,
|
||||
//}, s)
|
||||
// Update others binary of your session
|
||||
s.server.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary {
|
||||
CharID: s.charID,
|
||||
BinaryType: 1,
|
||||
}, s)
|
||||
s.server.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary {
|
||||
CharID: s.charID,
|
||||
BinaryType: 2,
|
||||
}, s)
|
||||
s.server.BroadcastMHF(&mhfpacket.MsgSysNotifyUserBinary {
|
||||
CharID: s.charID,
|
||||
BinaryType: 3,
|
||||
}, s)
|
||||
|
||||
//Notify the entree client about all of the existing clients in the stage.
|
||||
// Notify the entree client about all of the existing clients in the stage.
|
||||
s.logger.Info("Notifying entree about existing stage clients")
|
||||
s.stage.RLock()
|
||||
clientNotif := byteframe.NewByteFrame()
|
||||
|
||||
// Get other players in the stage
|
||||
for session := range s.stage.clients {
|
||||
var cur mhfpacket.MHFPacket
|
||||
cur = &mhfpacket.MsgSysInsertUser{
|
||||
@@ -95,6 +100,12 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
}
|
||||
clientNotif.WriteUint16(uint16(cur.Opcode()))
|
||||
cur.Build(clientNotif, session.clientContext)
|
||||
}
|
||||
|
||||
// Get every players binary
|
||||
for session := range s.server.sessions {
|
||||
var cur mhfpacket.MHFPacket
|
||||
session := s.server.sessions[session]
|
||||
|
||||
cur = &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: session.charID,
|
||||
@@ -143,6 +154,18 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
}
|
||||
}
|
||||
|
||||
func removeEmptyStages(s *Session) {
|
||||
s.server.Lock()
|
||||
for sid, stage := range s.server.stages {
|
||||
if len(stage.reservedClientSlots) == 0 && len(stage.clients) == 0 {
|
||||
if strings.HasPrefix(sid, "sl1Qs") || strings.HasPrefix(sid, "sl2Qs") || strings.HasPrefix(sid, "sl3Qs") {
|
||||
delete(s.server.stages, sid)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.server.Unlock()
|
||||
}
|
||||
|
||||
func removeSessionFromStage(s *Session) {
|
||||
s.stage.Lock()
|
||||
defer s.stage.Unlock()
|
||||
@@ -151,6 +174,15 @@ func removeSessionFromStage(s *Session) {
|
||||
delete(s.stage.clients, s)
|
||||
delete(s.stage.reservedClientSlots, s.charID)
|
||||
|
||||
// Remove client from all reservations
|
||||
s.server.Lock()
|
||||
for _, stage := range s.server.stages {
|
||||
if _, exists := stage.reservedClientSlots[s.charID]; exists {
|
||||
delete(stage.reservedClientSlots, s.charID)
|
||||
}
|
||||
}
|
||||
s.server.Unlock()
|
||||
|
||||
// Delete old stage objects owned by the client.
|
||||
s.logger.Info("Sending MsgSysDeleteObject to old stage clients")
|
||||
for objID, stageObject := range s.stage.objects {
|
||||
@@ -163,7 +195,7 @@ func removeSessionFromStage(s *Session) {
|
||||
// Actually delete it form the objects map.
|
||||
delete(s.stage.objects, objID)
|
||||
}
|
||||
}
|
||||
}
|
||||
for objListID, stageObjectList := range s.stage.objectList {
|
||||
if stageObjectList.charid == s.charID {
|
||||
//Added to prevent duplicates from flooding ObjectMap and causing server hangs
|
||||
@@ -171,6 +203,8 @@ func removeSessionFromStage(s *Session) {
|
||||
s.stage.objectList[objListID].charid=0
|
||||
}
|
||||
}
|
||||
|
||||
removeEmptyStages(s)
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +286,9 @@ func handleMsgSysReserveStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.server.stagesLock.Unlock()
|
||||
|
||||
if !gotStage {
|
||||
s.logger.Fatal("Failed to get stage", zap.String("StageID", stageID))
|
||||
s.logger.Error("Failed to get stage", zap.String("StageID", stageID))
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
// Try to reserve a slot, fail if full.
|
||||
@@ -427,15 +463,17 @@ func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
// Build the response
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint16(uint16(len(s.server.stages)))
|
||||
bf := byteframe.NewByteFrame()
|
||||
var joinable int
|
||||
for sid, stage := range s.server.stages {
|
||||
stage.RLock()
|
||||
defer stage.RUnlock()
|
||||
if len(stage.reservedClientSlots)+len(stage.clients) == 0 {
|
||||
if len(stage.reservedClientSlots) == 0 && len(stage.clients) == 0 {
|
||||
continue
|
||||
}
|
||||
joinable++
|
||||
|
||||
resp.WriteUint16(uint16(len(stage.reservedClientSlots))) // Current players.
|
||||
resp.WriteUint16(uint16(len(stage.reservedClientSlots))) // Reserved players.
|
||||
resp.WriteUint16(0) // Unknown value
|
||||
|
||||
var hasDeparted uint16
|
||||
@@ -448,6 +486,8 @@ func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
resp.WriteUint8(uint8(len(sid)))
|
||||
resp.WriteBytes([]byte(sid))
|
||||
}
|
||||
bf.WriteUint16(uint16(joinable))
|
||||
bf.WriteBytes(resp.Data())
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
@@ -248,10 +248,15 @@ function switchPrompt() {
|
||||
}
|
||||
} catch (e) {
|
||||
addLog('Error parsing character info XML: '+e, 'error');
|
||||
switchPrompt();
|
||||
return;
|
||||
}
|
||||
let uid = localStorage.getItem('uid');
|
||||
if (uid != 'null' && uids.indexOf(uid) >= 0) {
|
||||
setUidIndex(uids.indexOf(uid));
|
||||
} else {
|
||||
addLog('Error setting character ID: '+e, 'error');
|
||||
switchPrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user