diff --git a/Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go b/Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go index 255294616..ffa193ffb 100644 --- a/Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go +++ b/Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go @@ -9,11 +9,22 @@ import ( ) // MsgMhfAcquireUdItem represents the MSG_MHF_ACQUIRE_UD_ITEM -type MsgMhfAcquireUdItem struct{ +type MsgMhfAcquireUdItem struct { AckHandle uint32 - // Valid field size(s), not sure about the types. Unk0 uint8 - Unk1 uint32 + // from gal + // daily = 0 + // personal = 1 + // personal rank = 2 + // guild rank = 3 + // gcp = 4 + // from cat + // treasure achievement = 5 + // personal achievement = 6 + // guild achievement = 7 + RewardType uint8 + Unk2 uint8 // Number of uint32s to read? + Unk3 []byte } // Opcode returns the ID associated with this packet type. @@ -25,9 +36,12 @@ func (m *MsgMhfAcquireUdItem) Opcode() network.PacketID { func (m *MsgMhfAcquireUdItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint8() - m.Unk1 = bf.ReadUint32() + m.RewardType = bf.ReadUint8() + m.Unk2 = bf.ReadUint8() + for i := uint8(0); i < m.Unk2; i++ { + bf.ReadUint32() + } return nil - //return errors.New("NOT IMPLEMENTED") } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_add_guild_weekly_bonus_exceptional_user.go b/Erupe/network/mhfpacket/msg_mhf_add_guild_weekly_bonus_exceptional_user.go index 9b024fef4..3a7976abb 100644 --- a/Erupe/network/mhfpacket/msg_mhf_add_guild_weekly_bonus_exceptional_user.go +++ b/Erupe/network/mhfpacket/msg_mhf_add_guild_weekly_bonus_exceptional_user.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,10 @@ import ( ) // MsgMhfAddGuildWeeklyBonusExceptionalUser represents the MSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USER -type MsgMhfAddGuildWeeklyBonusExceptionalUser struct{} +type MsgMhfAddGuildWeeklyBonusExceptionalUser struct { + AckHandle uint32 + NumUsers uint8 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Opcode() network.PacketID { @@ -18,7 +21,9 @@ func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.NumUsers = bf.ReadUint8() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_enumerate_guild.go b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild.go index 0fb4e4446..c01ef1a4f 100644 --- a/Erupe/network/mhfpacket/msg_mhf_enumerate_guild.go +++ b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,22 +11,25 @@ import ( type EnumerateGuildType uint8 const ( - _ = iota - ENUMERATE_GUILD_TYPE_NAME - //Numbers correspond to order in guild search menu - ENUMERATE_GUILD_TYPE_6 - ENUMERATE_GUILD_TYPE_LEADER_ID - ENUMERATE_GUILD_TYPE_3 - ENUMERATE_GUILD_TYPE_2 - ENUMERATE_GUILD_TYPE_7 - ENUMERATE_GUILD_TYPE_8 - ENUMERATE_GUILD_TYPE_NEW + ENUMERATE_GUILD_TYPE_GUILD_NAME = 0x01 + ENUMERATE_GUILD_TYPE_LEADER_NAME = 0x02 + ENUMERATE_GUILD_TYPE_LEADER_ID = 0x03 + ENUMERATE_GUILD_TYPE_ORDER_MEMBERS = 0x04 + ENUMERATE_GUILD_TYPE_ORDER_REGISTRATION = 0x05 + ENUMERATE_GUILD_TYPE_ORDER_RANK = 0x06 + ENUMERATE_GUILD_TYPE_MOTTO = 0x07 + ENUMERATE_GUILD_TYPE_RECRUITING = 0x08 + ENUMERATE_ALLIANCE_TYPE_ALLIANCE_NAME = 0x09 + ENUMERATE_ALLIANCE_TYPE_LEADER_NAME = 0x0A + ENUMERATE_ALLIANCE_TYPE_LEADER_ID = 0x0B + ENUMERATE_ALLIANCE_TYPE_ORDER_MEMBERS = 0x0C + ENUMERATE_ALLIANCE_TYPE_ORDER_REGISTRATION = 0x0D ) // MsgMhfEnumerateGuild represents the MSG_MHF_ENUMERATE_GUILD type MsgMhfEnumerateGuild struct { AckHandle uint32 - Type uint8 + Type EnumerateGuildType RawDataPayload []byte } @@ -38,9 +41,9 @@ func (m *MsgMhfEnumerateGuild) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Type = bf.ReadUint8() + m.Type = EnumerateGuildType(bf.ReadUint8()) m.RawDataPayload = bf.DataFromCurrent() - + bf.Seek(int64(len(bf.Data()) - 2), 0) return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_item.go b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_item.go index 9f39b5b79..915dfde8c 100644 --- a/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_item.go +++ b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_item.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,6 +11,8 @@ import ( // MsgMhfEnumerateGuildItem represents the MSG_MHF_ENUMERATE_GUILD_ITEM type MsgMhfEnumerateGuildItem struct { AckHandle uint32 + GuildId uint32 + Unk0 uint16 } // Opcode returns the ID associated with this packet type. @@ -20,8 +22,9 @@ func (m *MsgMhfEnumerateGuildItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() - + m.AckHandle = bf.ReadUint32() + m.GuildId = bf.ReadUint32() + m.Unk0 = bf.ReadUint16() return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_message_board.go b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_message_board.go new file mode 100644 index 000000000..487e39efe --- /dev/null +++ b/Erupe/network/mhfpacket/msg_mhf_enumerate_guild_message_board.go @@ -0,0 +1,37 @@ +package mhfpacket + +import ( + "errors" + + "github.com/Solenataris/Erupe/network/clientctx" + "github.com/Solenataris/Erupe/network" + "github.com/Andoryuuta/byteframe" +) + +// MsgMhfEnumerateGuildMessageBoard represents the MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD +type MsgMhfEnumerateGuildMessageBoard struct{ + AckHandle uint32 + Unk0 uint32 + MaxPosts uint32 // always 100, even on news (00000064) + // returning more than 4 news posts WILL softlock + BoardType uint32 // 0 => message, 1 => news +} + +// Opcode returns the ID associated with this packet type. +func (m *MsgMhfEnumerateGuildMessageBoard) Opcode() network.PacketID { + return network.MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD +} + +// Parse parses the packet from binary +func (m *MsgMhfEnumerateGuildMessageBoard) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.MaxPosts = bf.ReadUint32() + m.BoardType = bf.ReadUint32() + return nil +} + +// Build builds a binary packet from the current data. +func (m *MsgMhfEnumerateGuildMessageBoard) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { + return errors.New("NOT IMPLEMENTED") +} diff --git a/Erupe/network/mhfpacket/msg_mhf_enumerate_union_item.go b/Erupe/network/mhfpacket/msg_mhf_enumerate_union_item.go index 92a07935a..1ebafbea7 100644 --- a/Erupe/network/mhfpacket/msg_mhf_enumerate_union_item.go +++ b/Erupe/network/mhfpacket/msg_mhf_enumerate_union_item.go @@ -9,7 +9,10 @@ import ( ) // MsgMhfEnumerateUnionItem represents the MSG_MHF_ENUMERATE_UNION_ITEM -type MsgMhfEnumerateUnionItem struct{} +type MsgMhfEnumerateUnionItem struct { + AckHandle uint32 + Unk0 uint16 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfEnumerateUnionItem) Opcode() network.PacketID { @@ -18,7 +21,10 @@ func (m *MsgMhfEnumerateUnionItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint16() + + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_get_achievement.go b/Erupe/network/mhfpacket/msg_mhf_get_achievement.go index edba009ea..c77009c91 100644 --- a/Erupe/network/mhfpacket/msg_mhf_get_achievement.go +++ b/Erupe/network/mhfpacket/msg_mhf_get_achievement.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -10,10 +10,9 @@ import ( // MsgMhfGetAchievement represents the MSG_MHF_GET_ACHIEVEMENT type MsgMhfGetAchievement struct{ - AckHandle uint32 - Unk0 uint16 // id? + AckHandle uint32 + Unk0 uint32 // id? Unk1 uint32 // char? - Unk2 uint32 // pad? } // Opcode returns the ID associated with this packet type. @@ -23,10 +22,9 @@ func (m *MsgMhfGetAchievement) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() m.Unk1 = bf.ReadUint32() - m.Unk2 = bf.ReadUint32() return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_get_ud_ranking.go b/Erupe/network/mhfpacket/msg_mhf_get_ud_ranking.go index 33cfdbc1e..8a43b34b9 100644 --- a/Erupe/network/mhfpacket/msg_mhf_get_ud_ranking.go +++ b/Erupe/network/mhfpacket/msg_mhf_get_ud_ranking.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,6 +11,7 @@ import ( // MsgMhfGetUdRanking represents the MSG_MHF_GET_UD_RANKING type MsgMhfGetUdRanking struct{ AckHandle uint32 + Unk0 uint8 } // Opcode returns the ID associated with this packet type. @@ -20,8 +21,9 @@ func (m *MsgMhfGetUdRanking) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetUdRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() - return nil + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint8() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_get_ud_tactics_ranking.go b/Erupe/network/mhfpacket/msg_mhf_get_ud_tactics_ranking.go index feec60cc1..c27dc04ac 100644 --- a/Erupe/network/mhfpacket/msg_mhf_get_ud_tactics_ranking.go +++ b/Erupe/network/mhfpacket/msg_mhf_get_ud_tactics_ranking.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,10 @@ import ( ) // MsgMhfGetUdTacticsRanking represents the MSG_MHF_GET_UD_TACTICS_RANKING -type MsgMhfGetUdTacticsRanking struct{} +type MsgMhfGetUdTacticsRanking struct { + AckHandle uint32 + GuildID uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfGetUdTacticsRanking) Opcode() network.PacketID { @@ -18,7 +21,9 @@ func (m *MsgMhfGetUdTacticsRanking) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetUdTacticsRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.GuildID = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_list_mail.go b/Erupe/network/mhfpacket/msg_mhf_list_mail.go index 6080ecd81..f8cd945b0 100644 --- a/Erupe/network/mhfpacket/msg_mhf_list_mail.go +++ b/Erupe/network/mhfpacket/msg_mhf_list_mail.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,6 +11,7 @@ import ( // MsgMhfListMail represents the MSG_MHF_LIST_MAIL type MsgMhfListMail struct { AckHandle uint32 + Unk0 uint32 } // Opcode returns the ID associated with this packet type. @@ -21,6 +22,7 @@ func (m *MsgMhfListMail) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfListMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_operate_guild.go b/Erupe/network/mhfpacket/msg_mhf_operate_guild.go index 165f51161..1c2928d71 100644 --- a/Erupe/network/mhfpacket/msg_mhf_operate_guild.go +++ b/Erupe/network/mhfpacket/msg_mhf_operate_guild.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,14 +11,29 @@ import ( type OperateGuildAction uint8 const ( - OPERATE_GUILD_ACTION_DISBAND = 0x01 - OPERATE_GUILD_ACTION_APPLY = 0x02 - OPERATE_GUILD_ACTION_LEAVE = 0x03 - OPERATE_GUILD_SET_AVOID_LEADERSHIP_TRUE = 0x07 - OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE = 0x08 - OPERATE_GUILD_ACTION_UPDATE_COMMENT = 0x09 - OPERATE_GUILD_ACTION_DONATE = 0x0a - OPERATE_GUILD_ACTION_UPDATE_MOTTO = 0x0b + OPERATE_GUILD_DISBAND = 0x01 + OPERATE_GUILD_APPLY = 0x02 + OPERATE_GUILD_LEAVE = 0x03 + OPERATE_GUILD_RESIGN = 0x04 + OPERATE_GUILD_SET_APPLICATION_DENY = 0x05 + OPERATE_GUILD_SET_APPLICATION_ALLOW = 0x06 + OPERATE_GUILD_SET_AVOID_LEADERSHIP_TRUE = 0x07 + OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE = 0x08 + OPERATE_GUILD_UPDATE_COMMENT = 0x09 + OPERATE_GUILD_DONATE_RANK = 0x0a + OPERATE_GUILD_UPDATE_MOTTO = 0x0b + OPERATE_GUILD_RENAME_PUGI_1 = 0x0c + OPERATE_GUILD_RENAME_PUGI_2 = 0x0d + OPERATE_GUILD_RENAME_PUGI_3 = 0x0e + OPERATE_GUILD_CHANGE_PUGI_1 = 0x0f + OPERATE_GUILD_CHANGE_PUGI_2 = 0x10 + OPERATE_GUILD_CHANGE_PUGI_3 = 0x11 + // pugi something + OPERATE_GUILD_DONATE_EVENT = 0x15 + // pugi something + OPERATE_GUILD_CHANGE_DIVA_PUGI_1 = 0x19 + OPERATE_GUILD_CHANGE_DIVA_PUGI_2 = 0x1a + OPERATE_GUILD_CHANGE_DIVA_PUGI_3 = 0x1b ) // MsgMhfOperateGuild represents the MSG_MHF_OPERATE_GUILD @@ -40,7 +55,7 @@ func (m *MsgMhfOperateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien m.GuildID = bf.ReadUint32() m.Action = OperateGuildAction(bf.ReadUint8()) m.UnkData = bf.DataFromCurrent() - + bf.Seek(int64(len(bf.Data()) - 2), 0) return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_operate_joint.go b/Erupe/network/mhfpacket/msg_mhf_operate_joint.go index 34536628a..ff079d5b3 100644 --- a/Erupe/network/mhfpacket/msg_mhf_operate_joint.go +++ b/Erupe/network/mhfpacket/msg_mhf_operate_joint.go @@ -1,15 +1,29 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" "github.com/Andoryuuta/byteframe" ) +type OperateJointAction uint8 + +const ( + OPERATE_JOINT_DISBAND = 0x01 + OPERATE_JOINT_LEAVE = 0x03 + OPERATE_JOINT_KICK = 0x09 +) + // MsgMhfOperateJoint represents the MSG_MHF_OPERATE_JOINT -type MsgMhfOperateJoint struct{} +type MsgMhfOperateJoint struct { + AckHandle uint32 + AllianceID uint32 + GuildID uint32 + Action OperateJointAction + UnkData []byte +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfOperateJoint) Opcode() network.PacketID { @@ -18,7 +32,13 @@ func (m *MsgMhfOperateJoint) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfOperateJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.AllianceID = bf.ReadUint32() + m.GuildID = bf.ReadUint32() + m.Action = OperateJointAction(bf.ReadUint8()) + m.UnkData = bf.DataFromCurrent() + bf.Seek(int64(len(bf.Data()) - 2), 0) + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_oprt_mail.go b/Erupe/network/mhfpacket/msg_mhf_oprt_mail.go index 13fb7557a..c8d594ac9 100644 --- a/Erupe/network/mhfpacket/msg_mhf_oprt_mail.go +++ b/Erupe/network/mhfpacket/msg_mhf_oprt_mail.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,15 +11,20 @@ import ( type OperateMailOperation uint8 const ( - OperateMailOperationDelete OperateMailOperation = 0x01 + OPERATE_MAIL_DELETE = 0x01 + OPERATE_MAIL_ACQUIRE_ITEM = 0x05 ) // MsgMhfOprtMail represents the MSG_MHF_OPRT_MAIL type MsgMhfOprtMail struct { - AckHandle uint32 + AckHandle uint32 AccIndex uint8 Index uint8 - Operation uint8 + Operation OperateMailOperation + Unk0 uint8 + Data []byte + Amount uint16 + ItemID uint16 } // Opcode returns the ID associated with this packet type. @@ -29,10 +34,16 @@ func (m *MsgMhfOprtMail) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfOprtMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() + m.AckHandle = bf.ReadUint32() m.AccIndex = bf.ReadUint8() m.Index = bf.ReadUint8() - m.Operation = bf.ReadUint8() + m.Operation = OperateMailOperation(bf.ReadUint8()) + m.Unk0 = bf.ReadUint8() + switch m.Operation { + case OPERATE_MAIL_ACQUIRE_ITEM: + m.Amount = bf.ReadUint16() + m.ItemID = bf.ReadUint16() + } return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_read_mail.go b/Erupe/network/mhfpacket/msg_mhf_read_mail.go index ca0b45889..d4244aee3 100644 --- a/Erupe/network/mhfpacket/msg_mhf_read_mail.go +++ b/Erupe/network/mhfpacket/msg_mhf_read_mail.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -19,6 +19,7 @@ type MsgMhfReadMail struct { // This is the index within the current mail list Index uint8 + Unk0 uint16 } // Opcode returns the ID associated with this packet type. @@ -31,6 +32,7 @@ func (m *MsgMhfReadMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon m.AckHandle = bf.ReadUint32() m.AccIndex = bf.ReadUint8() m.Index = bf.ReadUint8() + m.Unk0 = bf.ReadUint16() return nil } diff --git a/Erupe/network/mhfpacket/msg_mhf_send_mail.go b/Erupe/network/mhfpacket/msg_mhf_send_mail.go index 56969a966..533d77dee 100644 --- a/Erupe/network/mhfpacket/msg_mhf_send_mail.go +++ b/Erupe/network/mhfpacket/msg_mhf_send_mail.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,16 @@ import ( ) // MsgMhfSendMail represents the MSG_MHF_SEND_MAIL -type MsgMhfSendMail struct{} +type MsgMhfSendMail struct { + AckHandle uint32 + RecipientID uint32 + SubjectLength uint16 + BodyLength uint16 + Quantity uint32 + ItemID uint16 + Subject []byte + Body []byte +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfSendMail) Opcode() network.PacketID { @@ -18,7 +27,15 @@ func (m *MsgMhfSendMail) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfSendMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.RecipientID = bf.ReadUint32() + m.SubjectLength = bf.ReadUint16() + m.BodyLength = bf.ReadUint16() + m.Quantity = bf.ReadUint32() + m.ItemID = bf.ReadUint16() + m.Subject = bf.ReadNullTerminatedBytes() + m.Body = bf.ReadNullTerminatedBytes() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_set_guild_mission_target.go b/Erupe/network/mhfpacket/msg_mhf_set_guild_mission_target.go index 55958258d..60d80549d 100644 --- a/Erupe/network/mhfpacket/msg_mhf_set_guild_mission_target.go +++ b/Erupe/network/mhfpacket/msg_mhf_set_guild_mission_target.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,10 @@ import ( ) // MsgMhfSetGuildMissionTarget represents the MSG_MHF_SET_GUILD_MISSION_TARGET -type MsgMhfSetGuildMissionTarget struct{} +type MsgMhfSetGuildMissionTarget struct { + AckHandle uint32 + MissionID uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfSetGuildMissionTarget) Opcode() network.PacketID { @@ -18,7 +21,9 @@ func (m *MsgMhfSetGuildMissionTarget) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfSetGuildMissionTarget) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.MissionID = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_update_guild_icon.go b/Erupe/network/mhfpacket/msg_mhf_update_guild_icon.go index cb0758de1..eaa13a739 100644 --- a/Erupe/network/mhfpacket/msg_mhf_update_guild_icon.go +++ b/Erupe/network/mhfpacket/msg_mhf_update_guild_icon.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -11,11 +11,12 @@ import ( type GuildIconMsgPart struct { Index uint16 ID uint16 - Unk0 uint8 + Page uint8 Size uint8 Rotation uint8 - Unk1 uint8 - Unk2 uint16 + Red uint8 + Green uint8 + Blue uint8 PosX uint16 PosY uint16 } @@ -47,11 +48,12 @@ func (m *MsgMhfUpdateGuildIcon) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl m.IconParts[i] = GuildIconMsgPart{ Index: bf.ReadUint16(), ID: bf.ReadUint16(), - Unk0: bf.ReadUint8(), + Page: bf.ReadUint8(), Size: bf.ReadUint8(), Rotation: bf.ReadUint8(), - Unk1: bf.ReadUint8(), - Unk2: bf.ReadUint16(), + Red: bf.ReadUint8(), + Green: bf.ReadUint8(), + Blue: bf.ReadUint8(), PosX: bf.ReadUint16(), PosY: bf.ReadUint16(), } diff --git a/Erupe/network/mhfpacket/msg_mhf_update_guild_item.go b/Erupe/network/mhfpacket/msg_mhf_update_guild_item.go index 02f626629..5a0edabf6 100644 --- a/Erupe/network/mhfpacket/msg_mhf_update_guild_item.go +++ b/Erupe/network/mhfpacket/msg_mhf_update_guild_item.go @@ -1,15 +1,28 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" "github.com/Andoryuuta/byteframe" ) +type Item struct{ + Unk0 uint32 + ItemId uint16 + Amount uint16 + Unk1 uint32 +} + // MsgMhfUpdateGuildItem represents the MSG_MHF_UPDATE_GUILD_ITEM -type MsgMhfUpdateGuildItem struct{} +type MsgMhfUpdateGuildItem struct{ + AckHandle uint32 + GuildId uint32 + Amount uint16 + Unk1 uint16 // 0x00 0x00 + Items []Item // Array of updated item IDs +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfUpdateGuildItem) Opcode() network.PacketID { @@ -18,7 +31,20 @@ func (m *MsgMhfUpdateGuildItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.GuildId = bf.ReadUint32() + m.Amount = bf.ReadUint16() + m.Unk1 = bf.ReadUint16() + m.Items = make([]Item, int(m.Amount)) + + for i := 0; i < int(m.Amount); i++ { + m.Items[i].Unk0 = bf.ReadUint32() + m.Items[i].ItemId = bf.ReadUint16() + m.Items[i].Amount = bf.ReadUint16() + m.Items[i].Unk1 = bf.ReadUint32() + } + + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_mhf_update_guild_message_board.go b/Erupe/network/mhfpacket/msg_mhf_update_guild_message_board.go new file mode 100644 index 000000000..266eef367 --- /dev/null +++ b/Erupe/network/mhfpacket/msg_mhf_update_guild_message_board.go @@ -0,0 +1,37 @@ +package mhfpacket + +import ( + "errors" + + "github.com/Solenataris/Erupe/network/clientctx" + "github.com/Solenataris/Erupe/network" + "github.com/Andoryuuta/byteframe" +) + +// MsgMhfUpdateGuildMessageBoard represents the MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD +type MsgMhfUpdateGuildMessageBoard struct { + AckHandle uint32 + MessageOp uint32 + Request []byte +} + +// Opcode returns the ID associated with this packet type. +func (m *MsgMhfUpdateGuildMessageBoard) Opcode() network.PacketID { + return network.MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD +} + +// Parse parses the packet from binary +func (m *MsgMhfUpdateGuildMessageBoard) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { + m.AckHandle = bf.ReadUint32() + m.MessageOp = bf.ReadUint32() + if m.MessageOp != 5 { + m.Request = bf.DataFromCurrent() + bf.Seek(int64(len(bf.Data()) - 2), 0) + } + return nil +} + +// Build builds a binary packet from the current data. +func (m *MsgMhfUpdateGuildMessageBoard) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { + return errors.New("NOT IMPLEMENTED") +} diff --git a/Erupe/network/mhfpacket/msg_mhf_update_union_item.go b/Erupe/network/mhfpacket/msg_mhf_update_union_item.go index 4e1ca8380..3617531d8 100644 --- a/Erupe/network/mhfpacket/msg_mhf_update_union_item.go +++ b/Erupe/network/mhfpacket/msg_mhf_update_union_item.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,12 @@ import ( ) // MsgMhfUpdateUnionItem represents the MSG_MHF_UPDATE_UNION_ITEM -type MsgMhfUpdateUnionItem struct{} +type MsgMhfUpdateUnionItem struct { + AckHandle uint32 + Amount uint16 + Unk1 uint16 // 0x00 0x00 + Items []Item // Array of updated item IDs +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID { @@ -18,7 +23,19 @@ func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Amount = bf.ReadUint16() + m.Unk1 = bf.ReadUint16() + m.Items = make([]Item, int(m.Amount)) + + for i := 0; i < int(m.Amount); i++ { + m.Items[i].Unk0 = bf.ReadUint32() + m.Items[i].ItemId = bf.ReadUint16() + m.Items[i].Amount = bf.ReadUint16() + m.Items[i].Unk1 = bf.ReadUint32() + } + + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/msg_sys_reserve202.go b/Erupe/network/mhfpacket/msg_sys_reserve202.go index f26a17815..2b39ad26a 100644 --- a/Erupe/network/mhfpacket/msg_sys_reserve202.go +++ b/Erupe/network/mhfpacket/msg_sys_reserve202.go @@ -1,27 +1 @@ -package mhfpacket - -import ( - "errors" - - "github.com/Solenataris/Erupe/network/clientctx" - "github.com/Solenataris/Erupe/network" - "github.com/Andoryuuta/byteframe" -) - -// MsgSysReserve202 represents the MSG_SYS_reserve202 -type MsgSysReserve202 struct{} - -// Opcode returns the ID associated with this packet type. -func (m *MsgSysReserve202) Opcode() network.PacketID { - return network.MSG_SYS_reserve202 -} - -// Parse parses the packet from binary -func (m *MsgSysReserve202) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") -} - -// Build builds a binary packet from the current data. -func (m *MsgSysReserve202) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") -} +package mhfpacket \ No newline at end of file diff --git a/Erupe/network/mhfpacket/msg_sys_reserve203.go b/Erupe/network/mhfpacket/msg_sys_reserve203.go index a6dc54408..2b39ad26a 100644 --- a/Erupe/network/mhfpacket/msg_sys_reserve203.go +++ b/Erupe/network/mhfpacket/msg_sys_reserve203.go @@ -1,36 +1 @@ -package mhfpacket - -import ( - "errors" - - "github.com/Solenataris/Erupe/network/clientctx" - "github.com/Solenataris/Erupe/network" - "github.com/Andoryuuta/byteframe" -) - -// TODO(Andoryuuta): Make up a name for this packet, not reserved anymore. Called "Is_update_guild_msg_board" - -// MsgSysReserve203 represents the MSG_SYS_reserve203 -type MsgSysReserve203 struct { - AckHandle uint32 - Unk0 uint16 // Hardcoded 0x0000 in the binary - Unk1 uint16 // Hardcoded 0x0500 in the binary. -} - -// Opcode returns the ID associated with this packet type. -func (m *MsgSysReserve203) Opcode() network.PacketID { - return network.MSG_SYS_reserve203 -} - -// Parse parses the packet from binary -func (m *MsgSysReserve203) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() - m.Unk1 = bf.ReadUint16() - return nil -} - -// Build builds a binary packet from the current data. -func (m *MsgSysReserve203) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") -} +package mhfpacket \ No newline at end of file diff --git a/Erupe/network/mhfpacket/msg_sys_reserve205.go b/Erupe/network/mhfpacket/msg_sys_reserve205.go index 28665324d..173d7464c 100644 --- a/Erupe/network/mhfpacket/msg_sys_reserve205.go +++ b/Erupe/network/mhfpacket/msg_sys_reserve205.go @@ -1,7 +1,7 @@ package mhfpacket -import ( - "errors" +import ( + "errors" "github.com/Solenataris/Erupe/network/clientctx" "github.com/Solenataris/Erupe/network" @@ -9,7 +9,12 @@ import ( ) // MsgSysReserve205 represents the MSG_SYS_reserve205 -type MsgSysReserve205 struct{} +type MsgSysReserve205 struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgSysReserve205) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgSysReserve205) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgSysReserve205) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/Erupe/network/mhfpacket/opcode_to_packet.go b/Erupe/network/mhfpacket/opcode_to_packet.go index 1cc9352ba..497fab17a 100644 --- a/Erupe/network/mhfpacket/opcode_to_packet.go +++ b/Erupe/network/mhfpacket/opcode_to_packet.go @@ -841,10 +841,10 @@ func FromOpcode(opcode network.PacketID) MHFPacket { return &MsgMhfUpdateForceGuildRank{} case network.MSG_MHF_RESET_TITLE: return &MsgMhfResetTitle{} - case network.MSG_SYS_reserve202: - return &MsgSysReserve202{} - case network.MSG_SYS_reserve203: - return &MsgSysReserve203{} + case network.MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD: + return &MsgMhfEnumerateGuildMessageBoard{} + case network.MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD: + return &MsgMhfUpdateGuildMessageBoard{} case network.MSG_SYS_reserve204: return &MsgSysReserve204{} case network.MSG_SYS_reserve205: diff --git a/Erupe/network/packetid.go b/Erupe/network/packetid.go index 7f9ee4d6c..005f5491a 100644 --- a/Erupe/network/packetid.go +++ b/Erupe/network/packetid.go @@ -423,8 +423,8 @@ const ( MSG_SYS_reserve19F MSG_MHF_UPDATE_FORCE_GUILD_RANK MSG_MHF_RESET_TITLE - MSG_SYS_reserve202 - MSG_SYS_reserve203 + MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD + MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD MSG_SYS_reserve204 MSG_SYS_reserve205 MSG_SYS_reserve206 diff --git a/Erupe/network/packetid_string.go b/Erupe/network/packetid_string.go index def56d278..b2702a185 100644 --- a/Erupe/network/packetid_string.go +++ b/Erupe/network/packetid_string.go @@ -426,8 +426,8 @@ func _() { _ = x[MSG_SYS_reserve19F-415] _ = x[MSG_MHF_UPDATE_FORCE_GUILD_RANK-416] _ = x[MSG_MHF_RESET_TITLE-417] - _ = x[MSG_SYS_reserve202-418] - _ = x[MSG_SYS_reserve203-419] + _ = x[MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD-418] + _ = x[MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD-419] _ = x[MSG_SYS_reserve204-420] _ = x[MSG_SYS_reserve205-421] _ = x[MSG_SYS_reserve206-422] @@ -442,9 +442,9 @@ func _() { _ = x[MSG_SYS_reserve20F-431] } -const _PacketID_name = "MSG_HEADMSG_SYS_reserve01MSG_SYS_reserve02MSG_SYS_reserve03MSG_SYS_reserve04MSG_SYS_reserve05MSG_SYS_reserve06MSG_SYS_reserve07MSG_SYS_ADD_OBJECTMSG_SYS_DEL_OBJECTMSG_SYS_DISP_OBJECTMSG_SYS_HIDE_OBJECTMSG_SYS_reserve0CMSG_SYS_reserve0DMSG_SYS_reserve0EMSG_SYS_EXTEND_THRESHOLDMSG_SYS_ENDMSG_SYS_NOPMSG_SYS_ACKMSG_SYS_TERMINAL_LOGMSG_SYS_LOGINMSG_SYS_LOGOUTMSG_SYS_SET_STATUSMSG_SYS_PINGMSG_SYS_CAST_BINARYMSG_SYS_HIDE_CLIENTMSG_SYS_TIMEMSG_SYS_CASTED_BINARYMSG_SYS_GET_FILEMSG_SYS_ISSUE_LOGKEYMSG_SYS_RECORD_LOGMSG_SYS_ECHOMSG_SYS_CREATE_STAGEMSG_SYS_STAGE_DESTRUCTMSG_SYS_ENTER_STAGEMSG_SYS_BACK_STAGEMSG_SYS_MOVE_STAGEMSG_SYS_LEAVE_STAGEMSG_SYS_LOCK_STAGEMSG_SYS_UNLOCK_STAGEMSG_SYS_RESERVE_STAGEMSG_SYS_UNRESERVE_STAGEMSG_SYS_SET_STAGE_PASSMSG_SYS_WAIT_STAGE_BINARYMSG_SYS_SET_STAGE_BINARYMSG_SYS_GET_STAGE_BINARYMSG_SYS_ENUMERATE_CLIENTMSG_SYS_ENUMERATE_STAGEMSG_SYS_CREATE_MUTEXMSG_SYS_CREATE_OPEN_MUTEXMSG_SYS_DELETE_MUTEXMSG_SYS_OPEN_MUTEXMSG_SYS_CLOSE_MUTEXMSG_SYS_CREATE_SEMAPHOREMSG_SYS_CREATE_ACQUIRE_SEMAPHOREMSG_SYS_DELETE_SEMAPHOREMSG_SYS_ACQUIRE_SEMAPHOREMSG_SYS_RELEASE_SEMAPHOREMSG_SYS_LOCK_GLOBAL_SEMAMSG_SYS_UNLOCK_GLOBAL_SEMAMSG_SYS_CHECK_SEMAPHOREMSG_SYS_OPERATE_REGISTERMSG_SYS_LOAD_REGISTERMSG_SYS_NOTIFY_REGISTERMSG_SYS_CREATE_OBJECTMSG_SYS_DELETE_OBJECTMSG_SYS_POSITION_OBJECTMSG_SYS_ROTATE_OBJECTMSG_SYS_DUPLICATE_OBJECTMSG_SYS_SET_OBJECT_BINARYMSG_SYS_GET_OBJECT_BINARYMSG_SYS_GET_OBJECT_OWNERMSG_SYS_UPDATE_OBJECT_BINARYMSG_SYS_CLEANUP_OBJECTMSG_SYS_reserve4AMSG_SYS_reserve4BMSG_SYS_reserve4CMSG_SYS_reserve4DMSG_SYS_reserve4EMSG_SYS_reserve4FMSG_SYS_INSERT_USERMSG_SYS_DELETE_USERMSG_SYS_SET_USER_BINARYMSG_SYS_GET_USER_BINARYMSG_SYS_NOTIFY_USER_BINARYMSG_SYS_reserve55MSG_SYS_reserve56MSG_SYS_reserve57MSG_SYS_UPDATE_RIGHTMSG_SYS_AUTH_QUERYMSG_SYS_AUTH_DATAMSG_SYS_AUTH_TERMINALMSG_SYS_reserve5CMSG_SYS_RIGHTS_RELOADMSG_SYS_reserve5EMSG_SYS_reserve5FMSG_MHF_SAVEDATAMSG_MHF_LOADDATAMSG_MHF_LIST_MEMBERMSG_MHF_OPR_MEMBERMSG_MHF_ENUMERATE_DIST_ITEMMSG_MHF_APPLY_DIST_ITEMMSG_MHF_ACQUIRE_DIST_ITEMMSG_MHF_GET_DIST_DESCRIPTIONMSG_MHF_SEND_MAILMSG_MHF_READ_MAILMSG_MHF_LIST_MAILMSG_MHF_OPRT_MAILMSG_MHF_LOAD_FAVORITE_QUESTMSG_MHF_SAVE_FAVORITE_QUESTMSG_MHF_REGISTER_EVENTMSG_MHF_RELEASE_EVENTMSG_MHF_TRANSIT_MESSAGEMSG_SYS_reserve71MSG_SYS_reserve72MSG_SYS_reserve73MSG_SYS_reserve74MSG_SYS_reserve75MSG_SYS_reserve76MSG_SYS_reserve77MSG_SYS_reserve78MSG_SYS_reserve79MSG_SYS_reserve7AMSG_SYS_reserve7BMSG_SYS_reserve7CMSG_CA_EXCHANGE_ITEMMSG_SYS_reserve7EMSG_MHF_PRESENT_BOXMSG_MHF_SERVER_COMMANDMSG_MHF_SHUT_CLIENTMSG_MHF_ANNOUNCEMSG_MHF_SET_LOGINWINDOWMSG_SYS_TRANS_BINARYMSG_SYS_COLLECT_BINARYMSG_SYS_GET_STATEMSG_SYS_SERIALIZEMSG_SYS_ENUMLOBBYMSG_SYS_ENUMUSERMSG_SYS_INFOKYSERVERMSG_MHF_GET_CA_UNIQUE_IDMSG_MHF_SET_CA_ACHIEVEMENTMSG_MHF_CARAVAN_MY_SCOREMSG_MHF_CARAVAN_RANKINGMSG_MHF_CARAVAN_MY_RANKMSG_MHF_CREATE_GUILDMSG_MHF_OPERATE_GUILDMSG_MHF_OPERATE_GUILD_MEMBERMSG_MHF_INFO_GUILDMSG_MHF_ENUMERATE_GUILDMSG_MHF_UPDATE_GUILDMSG_MHF_ARRANGE_GUILD_MEMBERMSG_MHF_ENUMERATE_GUILD_MEMBERMSG_MHF_ENUMERATE_CAMPAIGNMSG_MHF_STATE_CAMPAIGNMSG_MHF_APPLY_CAMPAIGNMSG_MHF_ENUMERATE_ITEMMSG_MHF_ACQUIRE_ITEMMSG_MHF_TRANSFER_ITEMMSG_MHF_MERCENARY_HUNTDATAMSG_MHF_ENTRY_ROOKIE_GUILDMSG_MHF_ENUMERATE_QUESTMSG_MHF_ENUMERATE_EVENTMSG_MHF_ENUMERATE_PRICEMSG_MHF_ENUMERATE_RANKINGMSG_MHF_ENUMERATE_ORDERMSG_MHF_ENUMERATE_SHOPMSG_MHF_GET_EXTRA_INFOMSG_MHF_UPDATE_INTERIORMSG_MHF_ENUMERATE_HOUSEMSG_MHF_UPDATE_HOUSEMSG_MHF_LOAD_HOUSEMSG_MHF_OPERATE_WAREHOUSEMSG_MHF_ENUMERATE_WAREHOUSEMSG_MHF_UPDATE_WAREHOUSEMSG_MHF_ACQUIRE_TITLEMSG_MHF_ENUMERATE_TITLEMSG_MHF_ENUMERATE_GUILD_ITEMMSG_MHF_UPDATE_GUILD_ITEMMSG_MHF_ENUMERATE_UNION_ITEMMSG_MHF_UPDATE_UNION_ITEMMSG_MHF_CREATE_JOINTMSG_MHF_OPERATE_JOINTMSG_MHF_INFO_JOINTMSG_MHF_UPDATE_GUILD_ICONMSG_MHF_INFO_FESTAMSG_MHF_ENTRY_FESTAMSG_MHF_CHARGE_FESTAMSG_MHF_ACQUIRE_FESTAMSG_MHF_STATE_FESTA_UMSG_MHF_STATE_FESTA_GMSG_MHF_ENUMERATE_FESTA_MEMBERMSG_MHF_VOTE_FESTAMSG_MHF_ACQUIRE_CAFE_ITEMMSG_MHF_UPDATE_CAFEPOINTMSG_MHF_CHECK_DAILY_CAFEPOINTMSG_MHF_GET_COG_INFOMSG_MHF_CHECK_MONTHLY_ITEMMSG_MHF_ACQUIRE_MONTHLY_ITEMMSG_MHF_CHECK_WEEKLY_STAMPMSG_MHF_EXCHANGE_WEEKLY_STAMPMSG_MHF_CREATE_MERCENARYMSG_MHF_SAVE_MERCENARYMSG_MHF_READ_MERCENARY_WMSG_MHF_READ_MERCENARY_MMSG_MHF_CONTRACT_MERCENARYMSG_MHF_ENUMERATE_MERCENARY_LOGMSG_MHF_ENUMERATE_GUACOTMSG_MHF_UPDATE_GUACOTMSG_MHF_INFO_TOURNAMENTMSG_MHF_ENTRY_TOURNAMENTMSG_MHF_ENTER_TOURNAMENT_QUESTMSG_MHF_ACQUIRE_TOURNAMENTMSG_MHF_GET_ACHIEVEMENTMSG_MHF_RESET_ACHIEVEMENTMSG_MHF_ADD_ACHIEVEMENTMSG_MHF_PAYMENT_ACHIEVEMENTMSG_MHF_DISPLAYED_ACHIEVEMENTMSG_MHF_INFO_SCENARIO_COUNTERMSG_MHF_SAVE_SCENARIO_DATAMSG_MHF_LOAD_SCENARIO_DATAMSG_MHF_GET_BBS_SNS_STATUSMSG_MHF_APPLY_BBS_ARTICLEMSG_MHF_GET_ETC_POINTSMSG_MHF_UPDATE_ETC_POINTMSG_MHF_GET_MYHOUSE_INFOMSG_MHF_UPDATE_MYHOUSE_INFOMSG_MHF_GET_WEEKLY_SCHEDULEMSG_MHF_ENUMERATE_INV_GUILDMSG_MHF_OPERATION_INV_GUILDMSG_MHF_STAMPCARD_STAMPMSG_MHF_STAMPCARD_PRIZEMSG_MHF_UNRESERVE_SRGMSG_MHF_LOAD_PLATE_DATAMSG_MHF_SAVE_PLATE_DATAMSG_MHF_LOAD_PLATE_BOXMSG_MHF_SAVE_PLATE_BOXMSG_MHF_READ_GUILDCARDMSG_MHF_UPDATE_GUILDCARDMSG_MHF_READ_BEAT_LEVELMSG_MHF_UPDATE_BEAT_LEVELMSG_MHF_READ_BEAT_LEVEL_ALL_RANKINGMSG_MHF_READ_BEAT_LEVEL_MY_RANKINGMSG_MHF_READ_LAST_WEEK_BEAT_RANKINGMSG_MHF_ACCEPT_READ_REWARDMSG_MHF_GET_ADDITIONAL_BEAT_REWARDMSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLEMSG_MHF_GET_BBS_USER_STATUSMSG_MHF_KICK_EXPORT_FORCEMSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARDMSG_MHF_GET_WEEKLY_SEIBATU_RANKING_REWARDMSG_MHF_GET_EARTH_STATUSMSG_MHF_LOAD_PARTNERMSG_MHF_SAVE_PARTNERMSG_MHF_GET_GUILD_MISSION_LISTMSG_MHF_GET_GUILD_MISSION_RECORDMSG_MHF_ADD_GUILD_MISSION_COUNTMSG_MHF_SET_GUILD_MISSION_TARGETMSG_MHF_CANCEL_GUILD_MISSION_TARGETMSG_MHF_LOAD_OTOMO_AIROUMSG_MHF_SAVE_OTOMO_AIROUMSG_MHF_ENUMERATE_GUILD_TRESUREMSG_MHF_ENUMERATE_AIROULISTMSG_MHF_REGIST_GUILD_TRESUREMSG_MHF_ACQUIRE_GUILD_TRESUREMSG_MHF_OPERATE_GUILD_TRESURE_REPORTMSG_MHF_GET_GUILD_TRESURE_SOUVENIRMSG_MHF_ACQUIRE_GUILD_TRESURE_SOUVENIRMSG_MHF_ENUMERATE_FESTA_INTERMEDIATE_PRIZEMSG_MHF_ACQUIRE_FESTA_INTERMEDIATE_PRIZEMSG_MHF_LOAD_DECO_MYSETMSG_MHF_SAVE_DECO_MYSETMSG_MHF_reserve010FMSG_MHF_LOAD_GUILD_COOKINGMSG_MHF_REGIST_GUILD_COOKINGMSG_MHF_LOAD_GUILD_ADVENTUREMSG_MHF_REGIST_GUILD_ADVENTUREMSG_MHF_ACQUIRE_GUILD_ADVENTUREMSG_MHF_CHARGE_GUILD_ADVENTUREMSG_MHF_LOAD_LEGEND_DISPATCHMSG_MHF_LOAD_HUNTER_NAVIMSG_MHF_SAVE_HUNTER_NAVIMSG_MHF_REGIST_SPABI_TIMEMSG_MHF_GET_GUILD_WEEKLY_BONUS_MASTERMSG_MHF_GET_GUILD_WEEKLY_BONUS_ACTIVE_COUNTMSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USERMSG_MHF_GET_TOWER_INFOMSG_MHF_POST_TOWER_INFOMSG_MHF_GET_GEM_INFOMSG_MHF_POST_GEM_INFOMSG_MHF_GET_EARTH_VALUEMSG_MHF_DEBUG_POST_VALUEMSG_MHF_GET_PAPER_DATAMSG_MHF_GET_NOTICEMSG_MHF_POST_NOTICEMSG_MHF_GET_BOOST_TIMEMSG_MHF_POST_BOOST_TIMEMSG_MHF_GET_BOOST_TIME_LIMITMSG_MHF_POST_BOOST_TIME_LIMITMSG_MHF_ENUMERATE_FESTA_PERSONAL_PRIZEMSG_MHF_ACQUIRE_FESTA_PERSONAL_PRIZEMSG_MHF_GET_RAND_FROM_TABLEMSG_MHF_GET_CAFE_DURATIONMSG_MHF_GET_CAFE_DURATION_BONUS_INFOMSG_MHF_RECEIVE_CAFE_DURATION_BONUSMSG_MHF_POST_CAFE_DURATION_BONUS_RECEIVEDMSG_MHF_GET_GACHA_POINTMSG_MHF_USE_GACHA_POINTMSG_MHF_EXCHANGE_FPOINT_2_ITEMMSG_MHF_EXCHANGE_ITEM_2_FPOINTMSG_MHF_GET_FPOINT_EXCHANGE_LISTMSG_MHF_PLAY_STEPUP_GACHAMSG_MHF_RECEIVE_GACHA_ITEMMSG_MHF_GET_STEPUP_STATUSMSG_MHF_PLAY_FREE_GACHAMSG_MHF_GET_TINY_BINMSG_MHF_POST_TINY_BINMSG_MHF_GET_SENYU_DAILY_COUNTMSG_MHF_GET_GUILD_TARGET_MEMBER_NUMMSG_MHF_GET_BOOST_RIGHTMSG_MHF_START_BOOST_TIMEMSG_MHF_POST_BOOST_TIME_QUEST_RETURNMSG_MHF_GET_BOX_GACHA_INFOMSG_MHF_PLAY_BOX_GACHAMSG_MHF_RESET_BOX_GACHA_INFOMSG_MHF_GET_SEIBATTLEMSG_MHF_POST_SEIBATTLEMSG_MHF_GET_RYOUDAMAMSG_MHF_POST_RYOUDAMAMSG_MHF_GET_TENROUIRAIMSG_MHF_POST_TENROUIRAIMSG_MHF_POST_GUILD_SCOUTMSG_MHF_CANCEL_GUILD_SCOUTMSG_MHF_ANSWER_GUILD_SCOUTMSG_MHF_GET_GUILD_SCOUT_LISTMSG_MHF_GET_GUILD_MANAGE_RIGHTMSG_MHF_SET_GUILD_MANAGE_RIGHTMSG_MHF_PLAY_NORMAL_GACHAMSG_MHF_GET_DAILY_MISSION_MASTERMSG_MHF_GET_DAILY_MISSION_PERSONALMSG_MHF_SET_DAILY_MISSION_PERSONALMSG_MHF_GET_GACHA_PLAY_HISTORYMSG_MHF_GET_REJECT_GUILD_SCOUTMSG_MHF_SET_REJECT_GUILD_SCOUTMSG_MHF_GET_CA_ACHIEVEMENT_HISTMSG_MHF_SET_CA_ACHIEVEMENT_HISTMSG_MHF_GET_KEEP_LOGIN_BOOST_STATUSMSG_MHF_USE_KEEP_LOGIN_BOOSTMSG_MHF_GET_UD_SCHEDULEMSG_MHF_GET_UD_INFOMSG_MHF_GET_KIJU_INFOMSG_MHF_SET_KIJUMSG_MHF_ADD_UD_POINTMSG_MHF_GET_UD_MY_POINTMSG_MHF_GET_UD_TOTAL_POINT_INFOMSG_MHF_GET_UD_BONUS_QUEST_INFOMSG_MHF_GET_UD_SELECTED_COLOR_INFOMSG_MHF_GET_UD_MONSTER_POINTMSG_MHF_GET_UD_DAILY_PRESENT_LISTMSG_MHF_GET_UD_NORMA_PRESENT_LISTMSG_MHF_GET_UD_RANKING_REWARD_LISTMSG_MHF_ACQUIRE_UD_ITEMMSG_MHF_GET_REWARD_SONGMSG_MHF_USE_REWARD_SONGMSG_MHF_ADD_REWARD_SONG_COUNTMSG_MHF_GET_UD_RANKINGMSG_MHF_GET_UD_MY_RANKINGMSG_MHF_ACQUIRE_MONTHLY_REWARDMSG_MHF_GET_UD_GUILD_MAP_INFOMSG_MHF_GENERATE_UD_GUILD_MAPMSG_MHF_GET_UD_TACTICS_POINTMSG_MHF_ADD_UD_TACTICS_POINTMSG_MHF_GET_UD_TACTICS_RANKINGMSG_MHF_GET_UD_TACTICS_REWARD_LISTMSG_MHF_GET_UD_TACTICS_LOGMSG_MHF_GET_EQUIP_SKIN_HISTMSG_MHF_UPDATE_EQUIP_SKIN_HISTMSG_MHF_GET_UD_TACTICS_FOLLOWERMSG_MHF_SET_UD_TACTICS_FOLLOWERMSG_MHF_GET_UD_SHOP_COINMSG_MHF_USE_UD_SHOP_COINMSG_MHF_GET_ENHANCED_MINIDATAMSG_MHF_SET_ENHANCED_MINIDATAMSG_MHF_SEX_CHANGERMSG_MHF_GET_LOBBY_CROWDMSG_SYS_reserve180MSG_MHF_GUILD_HUNTDATAMSG_MHF_ADD_KOURYOU_POINTMSG_MHF_GET_KOURYOU_POINTMSG_MHF_EXCHANGE_KOURYOU_POINTMSG_MHF_GET_UD_TACTICS_BONUS_QUESTMSG_MHF_GET_UD_TACTICS_FIRST_QUEST_BONUSMSG_MHF_GET_UD_TACTICS_REMAINING_POINTMSG_SYS_reserve188MSG_MHF_LOAD_PLATE_MYSETMSG_MHF_SAVE_PLATE_MYSETMSG_SYS_reserve18BMSG_MHF_GET_RESTRICTION_EVENTMSG_MHF_SET_RESTRICTION_EVENTMSG_SYS_reserve18EMSG_SYS_reserve18FMSG_MHF_GET_TREND_WEAPONMSG_MHF_UPDATE_USE_TREND_WEAPON_LOGMSG_SYS_reserve192MSG_SYS_reserve193MSG_SYS_reserve194MSG_MHF_SAVE_RENGOKU_DATAMSG_MHF_LOAD_RENGOKU_DATAMSG_MHF_GET_RENGOKU_BINARYMSG_MHF_ENUMERATE_RENGOKU_RANKINGMSG_MHF_GET_RENGOKU_RANKING_RANKMSG_MHF_ACQUIRE_EXCHANGE_SHOPMSG_SYS_reserve19BMSG_MHF_SAVE_MEZFES_DATAMSG_MHF_LOAD_MEZFES_DATAMSG_SYS_reserve19EMSG_SYS_reserve19FMSG_MHF_UPDATE_FORCE_GUILD_RANKMSG_MHF_RESET_TITLEMSG_SYS_reserve202MSG_SYS_reserve203MSG_SYS_reserve204MSG_SYS_reserve205MSG_SYS_reserve206MSG_SYS_reserve207MSG_SYS_reserve208MSG_SYS_reserve209MSG_SYS_reserve20AMSG_SYS_reserve20BMSG_SYS_reserve20CMSG_SYS_reserve20DMSG_SYS_reserve20EMSG_SYS_reserve20F" +const _PacketID_name = "MSG_HEADMSG_SYS_reserve01MSG_SYS_reserve02MSG_SYS_reserve03MSG_SYS_reserve04MSG_SYS_reserve05MSG_SYS_reserve06MSG_SYS_reserve07MSG_SYS_ADD_OBJECTMSG_SYS_DEL_OBJECTMSG_SYS_DISP_OBJECTMSG_SYS_HIDE_OBJECTMSG_SYS_reserve0CMSG_SYS_reserve0DMSG_SYS_reserve0EMSG_SYS_EXTEND_THRESHOLDMSG_SYS_ENDMSG_SYS_NOPMSG_SYS_ACKMSG_SYS_TERMINAL_LOGMSG_SYS_LOGINMSG_SYS_LOGOUTMSG_SYS_SET_STATUSMSG_SYS_PINGMSG_SYS_CAST_BINARYMSG_SYS_HIDE_CLIENTMSG_SYS_TIMEMSG_SYS_CASTED_BINARYMSG_SYS_GET_FILEMSG_SYS_ISSUE_LOGKEYMSG_SYS_RECORD_LOGMSG_SYS_ECHOMSG_SYS_CREATE_STAGEMSG_SYS_STAGE_DESTRUCTMSG_SYS_ENTER_STAGEMSG_SYS_BACK_STAGEMSG_SYS_MOVE_STAGEMSG_SYS_LEAVE_STAGEMSG_SYS_LOCK_STAGEMSG_SYS_UNLOCK_STAGEMSG_SYS_RESERVE_STAGEMSG_SYS_UNRESERVE_STAGEMSG_SYS_SET_STAGE_PASSMSG_SYS_WAIT_STAGE_BINARYMSG_SYS_SET_STAGE_BINARYMSG_SYS_GET_STAGE_BINARYMSG_SYS_ENUMERATE_CLIENTMSG_SYS_ENUMERATE_STAGEMSG_SYS_CREATE_MUTEXMSG_SYS_CREATE_OPEN_MUTEXMSG_SYS_DELETE_MUTEXMSG_SYS_OPEN_MUTEXMSG_SYS_CLOSE_MUTEXMSG_SYS_CREATE_SEMAPHOREMSG_SYS_CREATE_ACQUIRE_SEMAPHOREMSG_SYS_DELETE_SEMAPHOREMSG_SYS_ACQUIRE_SEMAPHOREMSG_SYS_RELEASE_SEMAPHOREMSG_SYS_LOCK_GLOBAL_SEMAMSG_SYS_UNLOCK_GLOBAL_SEMAMSG_SYS_CHECK_SEMAPHOREMSG_SYS_OPERATE_REGISTERMSG_SYS_LOAD_REGISTERMSG_SYS_NOTIFY_REGISTERMSG_SYS_CREATE_OBJECTMSG_SYS_DELETE_OBJECTMSG_SYS_POSITION_OBJECTMSG_SYS_ROTATE_OBJECTMSG_SYS_DUPLICATE_OBJECTMSG_SYS_SET_OBJECT_BINARYMSG_SYS_GET_OBJECT_BINARYMSG_SYS_GET_OBJECT_OWNERMSG_SYS_UPDATE_OBJECT_BINARYMSG_SYS_CLEANUP_OBJECTMSG_SYS_reserve4AMSG_SYS_reserve4BMSG_SYS_reserve4CMSG_SYS_reserve4DMSG_SYS_reserve4EMSG_SYS_reserve4FMSG_SYS_INSERT_USERMSG_SYS_DELETE_USERMSG_SYS_SET_USER_BINARYMSG_SYS_GET_USER_BINARYMSG_SYS_NOTIFY_USER_BINARYMSG_SYS_reserve55MSG_SYS_reserve56MSG_SYS_reserve57MSG_SYS_UPDATE_RIGHTMSG_SYS_AUTH_QUERYMSG_SYS_AUTH_DATAMSG_SYS_AUTH_TERMINALMSG_SYS_reserve5CMSG_SYS_RIGHTS_RELOADMSG_SYS_reserve5EMSG_SYS_reserve5FMSG_MHF_SAVEDATAMSG_MHF_LOADDATAMSG_MHF_LIST_MEMBERMSG_MHF_OPR_MEMBERMSG_MHF_ENUMERATE_DIST_ITEMMSG_MHF_APPLY_DIST_ITEMMSG_MHF_ACQUIRE_DIST_ITEMMSG_MHF_GET_DIST_DESCRIPTIONMSG_MHF_SEND_MAILMSG_MHF_READ_MAILMSG_MHF_LIST_MAILMSG_MHF_OPRT_MAILMSG_MHF_LOAD_FAVORITE_QUESTMSG_MHF_SAVE_FAVORITE_QUESTMSG_MHF_REGISTER_EVENTMSG_MHF_RELEASE_EVENTMSG_MHF_TRANSIT_MESSAGEMSG_SYS_reserve71MSG_SYS_reserve72MSG_SYS_reserve73MSG_SYS_reserve74MSG_SYS_reserve75MSG_SYS_reserve76MSG_SYS_reserve77MSG_SYS_reserve78MSG_SYS_reserve79MSG_SYS_reserve7AMSG_SYS_reserve7BMSG_SYS_reserve7CMSG_CA_EXCHANGE_ITEMMSG_SYS_reserve7EMSG_MHF_PRESENT_BOXMSG_MHF_SERVER_COMMANDMSG_MHF_SHUT_CLIENTMSG_MHF_ANNOUNCEMSG_MHF_SET_LOGINWINDOWMSG_SYS_TRANS_BINARYMSG_SYS_COLLECT_BINARYMSG_SYS_GET_STATEMSG_SYS_SERIALIZEMSG_SYS_ENUMLOBBYMSG_SYS_ENUMUSERMSG_SYS_INFOKYSERVERMSG_MHF_GET_CA_UNIQUE_IDMSG_MHF_SET_CA_ACHIEVEMENTMSG_MHF_CARAVAN_MY_SCOREMSG_MHF_CARAVAN_RANKINGMSG_MHF_CARAVAN_MY_RANKMSG_MHF_CREATE_GUILDMSG_MHF_OPERATE_GUILDMSG_MHF_OPERATE_GUILD_MEMBERMSG_MHF_INFO_GUILDMSG_MHF_ENUMERATE_GUILDMSG_MHF_UPDATE_GUILDMSG_MHF_ARRANGE_GUILD_MEMBERMSG_MHF_ENUMERATE_GUILD_MEMBERMSG_MHF_ENUMERATE_CAMPAIGNMSG_MHF_STATE_CAMPAIGNMSG_MHF_APPLY_CAMPAIGNMSG_MHF_ENUMERATE_ITEMMSG_MHF_ACQUIRE_ITEMMSG_MHF_TRANSFER_ITEMMSG_MHF_MERCENARY_HUNTDATAMSG_MHF_ENTRY_ROOKIE_GUILDMSG_MHF_ENUMERATE_QUESTMSG_MHF_ENUMERATE_EVENTMSG_MHF_ENUMERATE_PRICEMSG_MHF_ENUMERATE_RANKINGMSG_MHF_ENUMERATE_ORDERMSG_MHF_ENUMERATE_SHOPMSG_MHF_GET_EXTRA_INFOMSG_MHF_UPDATE_INTERIORMSG_MHF_ENUMERATE_HOUSEMSG_MHF_UPDATE_HOUSEMSG_MHF_LOAD_HOUSEMSG_MHF_OPERATE_WAREHOUSEMSG_MHF_ENUMERATE_WAREHOUSEMSG_MHF_UPDATE_WAREHOUSEMSG_MHF_ACQUIRE_TITLEMSG_MHF_ENUMERATE_TITLEMSG_MHF_ENUMERATE_GUILD_ITEMMSG_MHF_UPDATE_GUILD_ITEMMSG_MHF_ENUMERATE_UNION_ITEMMSG_MHF_UPDATE_UNION_ITEMMSG_MHF_CREATE_JOINTMSG_MHF_OPERATE_JOINTMSG_MHF_INFO_JOINTMSG_MHF_UPDATE_GUILD_ICONMSG_MHF_INFO_FESTAMSG_MHF_ENTRY_FESTAMSG_MHF_CHARGE_FESTAMSG_MHF_ACQUIRE_FESTAMSG_MHF_STATE_FESTA_UMSG_MHF_STATE_FESTA_GMSG_MHF_ENUMERATE_FESTA_MEMBERMSG_MHF_VOTE_FESTAMSG_MHF_ACQUIRE_CAFE_ITEMMSG_MHF_UPDATE_CAFEPOINTMSG_MHF_CHECK_DAILY_CAFEPOINTMSG_MHF_GET_COG_INFOMSG_MHF_CHECK_MONTHLY_ITEMMSG_MHF_ACQUIRE_MONTHLY_ITEMMSG_MHF_CHECK_WEEKLY_STAMPMSG_MHF_EXCHANGE_WEEKLY_STAMPMSG_MHF_CREATE_MERCENARYMSG_MHF_SAVE_MERCENARYMSG_MHF_READ_MERCENARY_WMSG_MHF_READ_MERCENARY_MMSG_MHF_CONTRACT_MERCENARYMSG_MHF_ENUMERATE_MERCENARY_LOGMSG_MHF_ENUMERATE_GUACOTMSG_MHF_UPDATE_GUACOTMSG_MHF_INFO_TOURNAMENTMSG_MHF_ENTRY_TOURNAMENTMSG_MHF_ENTER_TOURNAMENT_QUESTMSG_MHF_ACQUIRE_TOURNAMENTMSG_MHF_GET_ACHIEVEMENTMSG_MHF_RESET_ACHIEVEMENTMSG_MHF_ADD_ACHIEVEMENTMSG_MHF_PAYMENT_ACHIEVEMENTMSG_MHF_DISPLAYED_ACHIEVEMENTMSG_MHF_INFO_SCENARIO_COUNTERMSG_MHF_SAVE_SCENARIO_DATAMSG_MHF_LOAD_SCENARIO_DATAMSG_MHF_GET_BBS_SNS_STATUSMSG_MHF_APPLY_BBS_ARTICLEMSG_MHF_GET_ETC_POINTSMSG_MHF_UPDATE_ETC_POINTMSG_MHF_GET_MYHOUSE_INFOMSG_MHF_UPDATE_MYHOUSE_INFOMSG_MHF_GET_WEEKLY_SCHEDULEMSG_MHF_ENUMERATE_INV_GUILDMSG_MHF_OPERATION_INV_GUILDMSG_MHF_STAMPCARD_STAMPMSG_MHF_STAMPCARD_PRIZEMSG_MHF_UNRESERVE_SRGMSG_MHF_LOAD_PLATE_DATAMSG_MHF_SAVE_PLATE_DATAMSG_MHF_LOAD_PLATE_BOXMSG_MHF_SAVE_PLATE_BOXMSG_MHF_READ_GUILDCARDMSG_MHF_UPDATE_GUILDCARDMSG_MHF_READ_BEAT_LEVELMSG_MHF_UPDATE_BEAT_LEVELMSG_MHF_READ_BEAT_LEVEL_ALL_RANKINGMSG_MHF_READ_BEAT_LEVEL_MY_RANKINGMSG_MHF_READ_LAST_WEEK_BEAT_RANKINGMSG_MHF_ACCEPT_READ_REWARDMSG_MHF_GET_ADDITIONAL_BEAT_REWARDMSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLEMSG_MHF_GET_BBS_USER_STATUSMSG_MHF_KICK_EXPORT_FORCEMSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARDMSG_MHF_GET_WEEKLY_SEIBATU_RANKING_REWARDMSG_MHF_GET_EARTH_STATUSMSG_MHF_LOAD_PARTNERMSG_MHF_SAVE_PARTNERMSG_MHF_GET_GUILD_MISSION_LISTMSG_MHF_GET_GUILD_MISSION_RECORDMSG_MHF_ADD_GUILD_MISSION_COUNTMSG_MHF_SET_GUILD_MISSION_TARGETMSG_MHF_CANCEL_GUILD_MISSION_TARGETMSG_MHF_LOAD_OTOMO_AIROUMSG_MHF_SAVE_OTOMO_AIROUMSG_MHF_ENUMERATE_GUILD_TRESUREMSG_MHF_ENUMERATE_AIROULISTMSG_MHF_REGIST_GUILD_TRESUREMSG_MHF_ACQUIRE_GUILD_TRESUREMSG_MHF_OPERATE_GUILD_TRESURE_REPORTMSG_MHF_GET_GUILD_TRESURE_SOUVENIRMSG_MHF_ACQUIRE_GUILD_TRESURE_SOUVENIRMSG_MHF_ENUMERATE_FESTA_INTERMEDIATE_PRIZEMSG_MHF_ACQUIRE_FESTA_INTERMEDIATE_PRIZEMSG_MHF_LOAD_DECO_MYSETMSG_MHF_SAVE_DECO_MYSETMSG_MHF_reserve010FMSG_MHF_LOAD_GUILD_COOKINGMSG_MHF_REGIST_GUILD_COOKINGMSG_MHF_LOAD_GUILD_ADVENTUREMSG_MHF_REGIST_GUILD_ADVENTUREMSG_MHF_ACQUIRE_GUILD_ADVENTUREMSG_MHF_CHARGE_GUILD_ADVENTUREMSG_MHF_LOAD_LEGEND_DISPATCHMSG_MHF_LOAD_HUNTER_NAVIMSG_MHF_SAVE_HUNTER_NAVIMSG_MHF_REGIST_SPABI_TIMEMSG_MHF_GET_GUILD_WEEKLY_BONUS_MASTERMSG_MHF_GET_GUILD_WEEKLY_BONUS_ACTIVE_COUNTMSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USERMSG_MHF_GET_TOWER_INFOMSG_MHF_POST_TOWER_INFOMSG_MHF_GET_GEM_INFOMSG_MHF_POST_GEM_INFOMSG_MHF_GET_EARTH_VALUEMSG_MHF_DEBUG_POST_VALUEMSG_MHF_GET_PAPER_DATAMSG_MHF_GET_NOTICEMSG_MHF_POST_NOTICEMSG_MHF_GET_BOOST_TIMEMSG_MHF_POST_BOOST_TIMEMSG_MHF_GET_BOOST_TIME_LIMITMSG_MHF_POST_BOOST_TIME_LIMITMSG_MHF_ENUMERATE_FESTA_PERSONAL_PRIZEMSG_MHF_ACQUIRE_FESTA_PERSONAL_PRIZEMSG_MHF_GET_RAND_FROM_TABLEMSG_MHF_GET_CAFE_DURATIONMSG_MHF_GET_CAFE_DURATION_BONUS_INFOMSG_MHF_RECEIVE_CAFE_DURATION_BONUSMSG_MHF_POST_CAFE_DURATION_BONUS_RECEIVEDMSG_MHF_GET_GACHA_POINTMSG_MHF_USE_GACHA_POINTMSG_MHF_EXCHANGE_FPOINT_2_ITEMMSG_MHF_EXCHANGE_ITEM_2_FPOINTMSG_MHF_GET_FPOINT_EXCHANGE_LISTMSG_MHF_PLAY_STEPUP_GACHAMSG_MHF_RECEIVE_GACHA_ITEMMSG_MHF_GET_STEPUP_STATUSMSG_MHF_PLAY_FREE_GACHAMSG_MHF_GET_TINY_BINMSG_MHF_POST_TINY_BINMSG_MHF_GET_SENYU_DAILY_COUNTMSG_MHF_GET_GUILD_TARGET_MEMBER_NUMMSG_MHF_GET_BOOST_RIGHTMSG_MHF_START_BOOST_TIMEMSG_MHF_POST_BOOST_TIME_QUEST_RETURNMSG_MHF_GET_BOX_GACHA_INFOMSG_MHF_PLAY_BOX_GACHAMSG_MHF_RESET_BOX_GACHA_INFOMSG_MHF_GET_SEIBATTLEMSG_MHF_POST_SEIBATTLEMSG_MHF_GET_RYOUDAMAMSG_MHF_POST_RYOUDAMAMSG_MHF_GET_TENROUIRAIMSG_MHF_POST_TENROUIRAIMSG_MHF_POST_GUILD_SCOUTMSG_MHF_CANCEL_GUILD_SCOUTMSG_MHF_ANSWER_GUILD_SCOUTMSG_MHF_GET_GUILD_SCOUT_LISTMSG_MHF_GET_GUILD_MANAGE_RIGHTMSG_MHF_SET_GUILD_MANAGE_RIGHTMSG_MHF_PLAY_NORMAL_GACHAMSG_MHF_GET_DAILY_MISSION_MASTERMSG_MHF_GET_DAILY_MISSION_PERSONALMSG_MHF_SET_DAILY_MISSION_PERSONALMSG_MHF_GET_GACHA_PLAY_HISTORYMSG_MHF_GET_REJECT_GUILD_SCOUTMSG_MHF_SET_REJECT_GUILD_SCOUTMSG_MHF_GET_CA_ACHIEVEMENT_HISTMSG_MHF_SET_CA_ACHIEVEMENT_HISTMSG_MHF_GET_KEEP_LOGIN_BOOST_STATUSMSG_MHF_USE_KEEP_LOGIN_BOOSTMSG_MHF_GET_UD_SCHEDULEMSG_MHF_GET_UD_INFOMSG_MHF_GET_KIJU_INFOMSG_MHF_SET_KIJUMSG_MHF_ADD_UD_POINTMSG_MHF_GET_UD_MY_POINTMSG_MHF_GET_UD_TOTAL_POINT_INFOMSG_MHF_GET_UD_BONUS_QUEST_INFOMSG_MHF_GET_UD_SELECTED_COLOR_INFOMSG_MHF_GET_UD_MONSTER_POINTMSG_MHF_GET_UD_DAILY_PRESENT_LISTMSG_MHF_GET_UD_NORMA_PRESENT_LISTMSG_MHF_GET_UD_RANKING_REWARD_LISTMSG_MHF_ACQUIRE_UD_ITEMMSG_MHF_GET_REWARD_SONGMSG_MHF_USE_REWARD_SONGMSG_MHF_ADD_REWARD_SONG_COUNTMSG_MHF_GET_UD_RANKINGMSG_MHF_GET_UD_MY_RANKINGMSG_MHF_ACQUIRE_MONTHLY_REWARDMSG_MHF_GET_UD_GUILD_MAP_INFOMSG_MHF_GENERATE_UD_GUILD_MAPMSG_MHF_GET_UD_TACTICS_POINTMSG_MHF_ADD_UD_TACTICS_POINTMSG_MHF_GET_UD_TACTICS_RANKINGMSG_MHF_GET_UD_TACTICS_REWARD_LISTMSG_MHF_GET_UD_TACTICS_LOGMSG_MHF_GET_EQUIP_SKIN_HISTMSG_MHF_UPDATE_EQUIP_SKIN_HISTMSG_MHF_GET_UD_TACTICS_FOLLOWERMSG_MHF_SET_UD_TACTICS_FOLLOWERMSG_MHF_GET_UD_SHOP_COINMSG_MHF_USE_UD_SHOP_COINMSG_MHF_GET_ENHANCED_MINIDATAMSG_MHF_SET_ENHANCED_MINIDATAMSG_MHF_SEX_CHANGERMSG_MHF_GET_LOBBY_CROWDMSG_SYS_reserve180MSG_MHF_GUILD_HUNTDATAMSG_MHF_ADD_KOURYOU_POINTMSG_MHF_GET_KOURYOU_POINTMSG_MHF_EXCHANGE_KOURYOU_POINTMSG_MHF_GET_UD_TACTICS_BONUS_QUESTMSG_MHF_GET_UD_TACTICS_FIRST_QUEST_BONUSMSG_MHF_GET_UD_TACTICS_REMAINING_POINTMSG_SYS_reserve188MSG_MHF_LOAD_PLATE_MYSETMSG_MHF_SAVE_PLATE_MYSETMSG_SYS_reserve18BMSG_MHF_GET_RESTRICTION_EVENTMSG_MHF_SET_RESTRICTION_EVENTMSG_SYS_reserve18EMSG_SYS_reserve18FMSG_MHF_GET_TREND_WEAPONMSG_MHF_UPDATE_USE_TREND_WEAPON_LOGMSG_SYS_reserve192MSG_SYS_reserve193MSG_SYS_reserve194MSG_MHF_SAVE_RENGOKU_DATAMSG_MHF_LOAD_RENGOKU_DATAMSG_MHF_GET_RENGOKU_BINARYMSG_MHF_ENUMERATE_RENGOKU_RANKINGMSG_MHF_GET_RENGOKU_RANKING_RANKMSG_MHF_ACQUIRE_EXCHANGE_SHOPMSG_SYS_reserve19BMSG_MHF_SAVE_MEZFES_DATAMSG_MHF_LOAD_MEZFES_DATAMSG_SYS_reserve19EMSG_SYS_reserve19FMSG_MHF_UPDATE_FORCE_GUILD_RANKMSG_MHF_RESET_TITLEMSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARDMSG_MHF_UPDATE_GUILD_MESSAGE_BOARDMSG_SYS_reserve204MSG_SYS_reserve205MSG_SYS_reserve206MSG_SYS_reserve207MSG_SYS_reserve208MSG_SYS_reserve209MSG_SYS_reserve20AMSG_SYS_reserve20BMSG_SYS_reserve20CMSG_SYS_reserve20DMSG_SYS_reserve20EMSG_SYS_reserve20F" -var _PacketID_index = [...]uint16{0, 8, 25, 42, 59, 76, 93, 110, 127, 145, 163, 182, 201, 218, 235, 252, 276, 287, 298, 309, 329, 342, 356, 374, 386, 405, 424, 436, 457, 473, 493, 511, 523, 543, 565, 584, 602, 620, 639, 657, 677, 698, 721, 743, 768, 792, 816, 840, 863, 883, 908, 928, 946, 965, 989, 1021, 1045, 1070, 1095, 1119, 1145, 1168, 1192, 1213, 1236, 1257, 1278, 1301, 1322, 1346, 1371, 1396, 1420, 1448, 1470, 1487, 1504, 1521, 1538, 1555, 1572, 1591, 1610, 1633, 1656, 1682, 1699, 1716, 1733, 1753, 1771, 1788, 1809, 1826, 1847, 1864, 1881, 1897, 1913, 1932, 1950, 1977, 2000, 2025, 2053, 2070, 2087, 2104, 2121, 2148, 2175, 2197, 2218, 2241, 2258, 2275, 2292, 2309, 2326, 2343, 2360, 2377, 2394, 2411, 2428, 2445, 2465, 2482, 2501, 2523, 2542, 2558, 2581, 2601, 2623, 2640, 2657, 2674, 2690, 2710, 2734, 2760, 2784, 2807, 2830, 2850, 2871, 2899, 2917, 2940, 2960, 2988, 3018, 3044, 3066, 3088, 3110, 3130, 3151, 3177, 3203, 3226, 3249, 3272, 3297, 3320, 3342, 3364, 3387, 3410, 3430, 3448, 3473, 3500, 3524, 3545, 3568, 3596, 3621, 3649, 3674, 3694, 3715, 3733, 3758, 3776, 3795, 3815, 3836, 3857, 3878, 3908, 3926, 3951, 3975, 4004, 4024, 4050, 4078, 4104, 4133, 4157, 4179, 4203, 4227, 4253, 4284, 4308, 4329, 4352, 4376, 4406, 4432, 4455, 4480, 4503, 4530, 4559, 4588, 4614, 4640, 4666, 4691, 4713, 4737, 4761, 4788, 4815, 4842, 4869, 4892, 4915, 4936, 4959, 4982, 5004, 5026, 5048, 5072, 5095, 5120, 5155, 5189, 5224, 5250, 5284, 5323, 5350, 5375, 5413, 5454, 5478, 5498, 5518, 5548, 5580, 5611, 5643, 5678, 5702, 5726, 5757, 5784, 5812, 5841, 5877, 5911, 5949, 5991, 6031, 6054, 6077, 6096, 6122, 6150, 6178, 6208, 6239, 6269, 6297, 6321, 6345, 6370, 6407, 6450, 6497, 6519, 6542, 6562, 6583, 6606, 6630, 6652, 6670, 6689, 6711, 6734, 6762, 6791, 6829, 6865, 6892, 6917, 6953, 6988, 7029, 7052, 7075, 7105, 7135, 7167, 7192, 7218, 7243, 7266, 7286, 7307, 7336, 7371, 7394, 7418, 7454, 7480, 7502, 7530, 7551, 7573, 7593, 7614, 7636, 7659, 7683, 7709, 7735, 7763, 7793, 7823, 7848, 7880, 7914, 7948, 7978, 8008, 8038, 8069, 8100, 8135, 8163, 8186, 8205, 8226, 8242, 8262, 8285, 8316, 8347, 8381, 8409, 8442, 8475, 8509, 8532, 8555, 8578, 8607, 8629, 8654, 8684, 8713, 8742, 8770, 8798, 8828, 8862, 8888, 8915, 8945, 8976, 9007, 9031, 9055, 9084, 9113, 9132, 9155, 9173, 9195, 9220, 9245, 9275, 9309, 9349, 9387, 9405, 9429, 9453, 9471, 9500, 9529, 9547, 9565, 9589, 9624, 9642, 9660, 9678, 9703, 9728, 9754, 9787, 9819, 9848, 9866, 9890, 9914, 9932, 9950, 9981, 10000, 10018, 10036, 10054, 10072, 10090, 10108, 10126, 10144, 10162, 10180, 10198, 10216, 10234, 10252} +var _PacketID_index = [...]uint16{0, 8, 25, 42, 59, 76, 93, 110, 127, 145, 163, 182, 201, 218, 235, 252, 276, 287, 298, 309, 329, 342, 356, 374, 386, 405, 424, 436, 457, 473, 493, 511, 523, 543, 565, 584, 602, 620, 639, 657, 677, 698, 721, 743, 768, 792, 816, 840, 863, 883, 908, 928, 946, 965, 989, 1021, 1045, 1070, 1095, 1119, 1145, 1168, 1192, 1213, 1236, 1257, 1278, 1301, 1322, 1346, 1371, 1396, 1420, 1448, 1470, 1487, 1504, 1521, 1538, 1555, 1572, 1591, 1610, 1633, 1656, 1682, 1699, 1716, 1733, 1753, 1771, 1788, 1809, 1826, 1847, 1864, 1881, 1897, 1913, 1932, 1950, 1977, 2000, 2025, 2053, 2070, 2087, 2104, 2121, 2148, 2175, 2197, 2218, 2241, 2258, 2275, 2292, 2309, 2326, 2343, 2360, 2377, 2394, 2411, 2428, 2445, 2465, 2482, 2501, 2523, 2542, 2558, 2581, 2601, 2623, 2640, 2657, 2674, 2690, 2710, 2734, 2760, 2784, 2807, 2830, 2850, 2871, 2899, 2917, 2940, 2960, 2988, 3018, 3044, 3066, 3088, 3110, 3130, 3151, 3177, 3203, 3226, 3249, 3272, 3297, 3320, 3342, 3364, 3387, 3410, 3430, 3448, 3473, 3500, 3524, 3545, 3568, 3596, 3621, 3649, 3674, 3694, 3715, 3733, 3758, 3776, 3795, 3815, 3836, 3857, 3878, 3908, 3926, 3951, 3975, 4004, 4024, 4050, 4078, 4104, 4133, 4157, 4179, 4203, 4227, 4253, 4284, 4308, 4329, 4352, 4376, 4406, 4432, 4455, 4480, 4503, 4530, 4559, 4588, 4614, 4640, 4666, 4691, 4713, 4737, 4761, 4788, 4815, 4842, 4869, 4892, 4915, 4936, 4959, 4982, 5004, 5026, 5048, 5072, 5095, 5120, 5155, 5189, 5224, 5250, 5284, 5323, 5350, 5375, 5413, 5454, 5478, 5498, 5518, 5548, 5580, 5611, 5643, 5678, 5702, 5726, 5757, 5784, 5812, 5841, 5877, 5911, 5949, 5991, 6031, 6054, 6077, 6096, 6122, 6150, 6178, 6208, 6239, 6269, 6297, 6321, 6345, 6370, 6407, 6450, 6497, 6519, 6542, 6562, 6583, 6606, 6630, 6652, 6670, 6689, 6711, 6734, 6762, 6791, 6829, 6865, 6892, 6917, 6953, 6988, 7029, 7052, 7075, 7105, 7135, 7167, 7192, 7218, 7243, 7266, 7286, 7307, 7336, 7371, 7394, 7418, 7454, 7480, 7502, 7530, 7551, 7573, 7593, 7614, 7636, 7659, 7683, 7709, 7735, 7763, 7793, 7823, 7848, 7880, 7914, 7948, 7978, 8008, 8038, 8069, 8100, 8135, 8163, 8186, 8205, 8226, 8242, 8262, 8285, 8316, 8347, 8381, 8409, 8442, 8475, 8509, 8532, 8555, 8578, 8607, 8629, 8654, 8684, 8713, 8742, 8770, 8798, 8828, 8862, 8888, 8915, 8945, 8976, 9007, 9031, 9055, 9084, 9113, 9132, 9155, 9173, 9195, 9220, 9245, 9275, 9309, 9349, 9387, 9405, 9429, 9453, 9471, 9500, 9529, 9547, 9565, 9589, 9624, 9642, 9660, 9678, 9703, 9728, 9754, 9787, 9819, 9848, 9866, 9890, 9914, 9932, 9950, 9981, 10000, 10037, 10071, 10089, 10107, 10125, 10143, 10161, 10179, 10197, 10215, 10233, 10251, 10269, 10287} func (i PacketID) String() string { if i >= PacketID(len(_PacketID_index)-1) { diff --git a/Erupe/server/channelserver/handlers.go b/Erupe/server/channelserver/handlers.go index 4a6d97eaf..5d7629dc8 100644 --- a/Erupe/server/channelserver/handlers.go +++ b/Erupe/server/channelserver/handlers.go @@ -3,6 +3,7 @@ package channelserver import ( "bytes" "encoding/hex" + "encoding/binary" "io/ioutil" "math/bits" "math/rand" @@ -74,16 +75,7 @@ func doAckSimpleFail(s *Session, ackHandle uint32, data []byte) { func updateRights(s *Session) { update := &mhfpacket.MsgSysUpdateRight{ ClientRespAckHandle: 0, - Unk1: 0x0E, //0e with normal sub 4e when having premium it's probably a bitfield? - // 01 = Character can take quests at allows - // 02 = Hunter Life, normal quests core sub - // 03 = Extra Course, extra quests, town boxes, QOL course, core sub - // 06 = Premium Course, standard 'premium' which makes ranking etc. faster - // some connection to unk1 above for these maybe? - // 06 0A 0B = Boost Course, just actually 3 subs combined - // 08 09 1E = N Course, gives you the benefits of being in a netcafe (extra quests, N Points, daily freebies etc.) minimal and pointless - // no timestamp after 08 or 1E while active - // 0C = N Boost course, ultra luxury course that ruins the game if in use but also gives a + Unk1: s.rights, Rights: []mhfpacket.ClientRight{ { ID: 1, @@ -143,10 +135,25 @@ func handleMsgSysLogin(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysLogin) name := "" + rights := uint32(0x0E) + // 0e with normal sub 4e when having premium + // 01 = Character can take quests at allows + // 02 = Hunter Life, normal quests core sub + // 03 = Extra Course, extra quests, town boxes, QOL course, core sub + // 06 = Premium Course, standard 'premium' which makes ranking etc. faster + // 06 0A 0B = Boost Course, just actually 3 subs combined + // 08 09 1E = N Course, gives you the benefits of being in a netcafe (extra quests, N Points, daily freebies etc.) minimal and pointless + // 0C = N Boost course, ultra luxury course that ruins the game if in use + err := s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", pkt.CharID0).Scan(&rights) + if err != nil { + panic(err) + } + s.server.db.QueryRow("SELECT name FROM characters WHERE id = $1", pkt.CharID0).Scan(&name) s.Lock() s.Name = name s.charID = pkt.CharID0 + s.rights = rights s.Unlock() bf := byteframe.NewByteFrame() bf.WriteUint32(uint32(Time_Current_Adjusted().Unix())) // Unix timestamp @@ -158,11 +165,11 @@ func handleMsgSysLogin(s *Session, p mhfpacket.MHFPacket) { } } - _, err := s.server.db.Exec("UPDATE characters SET last_login=$1 WHERE id=$2", Time_Current().Unix(), s.charID) + _, err = s.server.db.Exec("UPDATE characters SET last_login=$1 WHERE id=$2", Time_Current().Unix(), s.charID) if err != nil { panic(err) } - + doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) } @@ -191,6 +198,46 @@ func logoutPlayer(s *Session) { } removeSessionFromStage(s) + + if _, exists := s.server.semaphore["hs_l0u3B51J9k3"]; exists { + if _, ok := s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots[s.charID]; ok { + removeSessionFromSemaphore(s) + } + } + + var timePlayed int + err := s.server.db.QueryRow("SELECT time_played FROM characters WHERE id = $1", s.charID).Scan(&timePlayed) + + timePlayed = (int(Time_Current_Adjusted().Unix()) - int(s.sessionStart)) + timePlayed + + var rpGained int + + if s.rights == 0x08091e4e || s.rights == 0x08091e0e { // N Course + rpGained = timePlayed / 900 + timePlayed = timePlayed % 900 + } else { + rpGained = timePlayed / 1800 + timePlayed = timePlayed % 1800 + } + + _, err = s.server.db.Exec("UPDATE characters SET time_played = $1 WHERE id = $2", timePlayed, s.charID) + if err != nil { + panic(err) + } + + saveData, err := GetCharacterSaveData(s, s.charID) + if err != nil { + panic(err) + } + saveData.RP += uint16(rpGained) + transaction, err := s.server.db.Begin() + err = saveData.Save(s, transaction) + if err != nil { + transaction.Rollback() + panic(err) + } else { + transaction.Commit() + } } func handleMsgSysSetStatus(s *Session, p mhfpacket.MHFPacket) {} @@ -208,6 +255,8 @@ func handleMsgSysTime(s *Session, p mhfpacket.MHFPacket) { Timestamp: uint32(Time_Current_Adjusted().Unix()), // JP timezone } s.QueueSendMHF(resp) + + s.notifyticker() } func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) { @@ -356,15 +405,92 @@ func handleMsgMhfAcquireTitle(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfEnumerateTitle(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfEnumerateUnionItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfEnumerateUnionItem) + var boxContents []byte + bf := byteframe.NewByteFrame() + err := s.server.db.QueryRow("SELECT item_box FROM users, characters WHERE characters.id = $1 AND users.id = characters.user_id", int(s.charID)).Scan(&boxContents) + if err != nil { + s.logger.Fatal("Failed to get shared item box contents from db", zap.Error(err)) + } else { + if len(boxContents) == 0 { + bf.WriteUint32(0x00) + } else { + amount := len(boxContents) / 4 + bf.WriteUint16(uint16(amount)) + bf.WriteUint32(0x00) + bf.WriteUint16(0x00) + for i := 0; i < amount; i++ { + bf.WriteUint32(binary.BigEndian.Uint32(boxContents[i*4 : i*4+4])) + if i+1 != amount { + bf.WriteUint64(0x00) + } + } + } + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} -func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfUpdateUnionItem) + // Get item cache from DB + var boxContents []byte + var oldItems []Item -func handleMsgMhfCreateJoint(s *Session, p mhfpacket.MHFPacket) {} + err := s.server.db.QueryRow("SELECT item_box FROM users, characters WHERE characters.id = $1 AND users.id = characters.user_id", int(s.charID)).Scan(&boxContents) + if err != nil { + s.logger.Fatal("Failed to get shared item box contents from db", zap.Error(err)) + } else { + amount := len(boxContents) / 4 + oldItems = make([]Item, amount) + for i := 0; i < amount; i++ { + oldItems[i].ItemId = binary.BigEndian.Uint16(boxContents[i*4 : i*4+2]) + oldItems[i].Amount = binary.BigEndian.Uint16(boxContents[i*4+2 : i*4+4]) + } + } -func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) {} + // Update item stacks + newItems := make([]Item, len(oldItems)) + copy(newItems, oldItems) + for i := 0; i < int(pkt.Amount); i++ { + for j := 0; j <= len(oldItems); j++ { + if j == len(oldItems) { + var newItem Item + newItem.ItemId = pkt.Items[i].ItemId + newItem.Amount = pkt.Items[i].Amount + newItems = append(newItems, newItem) + break + } + if pkt.Items[i].ItemId == oldItems[j].ItemId { + newItems[j].Amount = pkt.Items[i].Amount + break + } + } + } -func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) {} + // Delete empty item stacks + for i := len(newItems) - 1; i >= 0; i-- { + if int(newItems[i].Amount) == 0 { + copy(newItems[i:], newItems[i+1:]) + newItems[len(newItems)-1] = make([]Item, 1)[0] + newItems = newItems[:len(newItems)-1] + } + } + + // Create new item cache + bf := byteframe.NewByteFrame() + for i := 0; i < len(newItems); i++ { + bf.WriteUint16(newItems[i].ItemId) + bf.WriteUint16(newItems[i].Amount) + } + + // Upload new item cache + _, err = s.server.db.Exec("UPDATE users SET item_box = $1 FROM characters WHERE users.id = characters.user_id AND characters.id = $2", bf.Data(), int(s.charID)) + if err != nil { + s.logger.Fatal("Failed to update shared item box contents in db", zap.Error(err)) + } + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) +} func handleMsgMhfAcquireCafeItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfAcquireCafeItem) diff --git a/Erupe/server/channelserver/handlers_cast_binary.go b/Erupe/server/channelserver/handlers_cast_binary.go index 566b3696a..b4ad6e799 100644 --- a/Erupe/server/channelserver/handlers_cast_binary.go +++ b/Erupe/server/channelserver/handlers_cast_binary.go @@ -2,8 +2,8 @@ package channelserver import ( "fmt" - "math" "strings" + "math" "github.com/Andoryuuta/byteframe" "github.com/Solenataris/Erupe/network/binpacket" @@ -22,6 +22,7 @@ const ( const ( BroadcastTypeTargeted = 0x01 BroadcastTypeStage = 0x03 + BroadcastTypeRavi = 0x06 BroadcastTypeWorld = 0x0a ) @@ -51,15 +52,14 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysCastBinary) if pkt.BroadcastType == 0x03 && pkt.MessageType == 0x03 && len(pkt.RawDataPayload) == 0x10 { - tmp := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) - - if tmp.ReadUint16() == 0x0002 && tmp.ReadUint8() == 0x18 { - _ = tmp.ReadBytes(9) - tmp.SetLE() - frame := tmp.ReadUint32() - sendServerChatMessage(s, fmt.Sprintf("TIME : %d'%d.%03d (%dframe)", frame/30/60, frame/30%60, int(math.Round(float64(frame%30*100)/3)), frame)) - } + tmp := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) + if tmp.ReadUint16() == 0x0002 && tmp.ReadUint8() == 0x18 { + _ = tmp.ReadBytes(9) + tmp.SetLE() + frame := tmp.ReadUint32() + sendServerChatMessage(s, fmt.Sprintf("TIME : %d'%d.%03d (%dframe)", frame/30/60, frame/30%60, int(math.Round(float64(frame%30*100)/3)), frame)) } + } // Parse out the real casted binary payload var realPayload []byte @@ -93,6 +93,11 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { s.server.BroadcastMHF(resp, s) case BroadcastTypeStage: s.stage.BroadcastMHF(resp, s) + case BroadcastTypeRavi: + if pkt.MessageType == 1 { + session := s.server.semaphore["hs_l0u3B51J9k3"] + (*session).BroadcastMHF(resp, s) + } case BroadcastTypeTargeted: for _, targetID := range (*msgBinTargeted).TargetCharIDs { char := s.server.FindSessionByCharID(targetID) @@ -129,6 +134,114 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { s.server.discordSession.ChannelMessageSend(s.server.erupeConfig.Discord.ChannelID, 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) + } 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) + } 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 + } + 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) + } else { + sendServerChatMessage(s, fmt.Sprintf("Setting Ravi damage multiplier to %d", num)) + s.server.db.Exec("UPDATE ravistate SET damagemultiplier = $1", num) + } + } else { + sendServerChatMessage(s, fmt.Sprintf("Multiplier can only be set once, please restart Ravi to set again")) + } + } + 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 + } + sendServerChatMessage(s, fmt.Sprintf("Ravi's current damage multiplier is %d", damageMultiplier)) + } + } + } + // END OF RAVI COMMANDS + if strings.HasPrefix(chatMessage.Message, "!tele ") { var x, y int16 n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y) diff --git a/Erupe/server/channelserver/handlers_clients.go b/Erupe/server/channelserver/handlers_clients.go index c9eb206ad..313da7a6a 100644 --- a/Erupe/server/channelserver/handlers_clients.go +++ b/Erupe/server/channelserver/handlers_clients.go @@ -59,7 +59,11 @@ func handleMsgMhfListMember(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } -func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfListMember) + // TODO: add targetid(uint32) to charid(uint32)'s database under new field + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} func handleMsgMhfShutClient(s *Session, p mhfpacket.MHFPacket) {} diff --git a/Erupe/server/channelserver/handlers_data.go b/Erupe/server/channelserver/handlers_data.go index 0727809e2..7704a8940 100644 --- a/Erupe/server/channelserver/handlers_data.go +++ b/Erupe/server/channelserver/handlers_data.go @@ -2,6 +2,7 @@ package channelserver import ( "encoding/hex" + "encoding/binary" "fmt" "io/ioutil" "os" @@ -54,21 +55,46 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { } s.logger.Info("Wrote recompressed savedata back to DB.") dumpSaveData(s, pkt.RawDataPayload, "") - // Temporary server launcher response stuff - // 0x1F715 Weapon Class - // 0x1FDF6 HR (small_gr_level) - // 0x88 Character Name - _, err = s.server.db.Exec("UPDATE characters SET weapon=$1 WHERE id=$2", uint16(decompressedData[128789]), s.charID) + + _, err = s.server.db.Exec("UPDATE characters SET weapon_type=$1 WHERE id=$2", uint16(decompressedData[128789]), s.charID) if err != nil { - s.logger.Fatal("Failed to character weapon in db", zap.Error(err)) + s.logger.Fatal("Failed to character weapon type in db", zap.Error(err)) + } + + isMale := uint8(decompressedData[80]) // 0x50 + if isMale == 1 { + _, err = s.server.db.Exec("UPDATE characters SET is_female=true WHERE id=$1", s.charID) + } else { + _, err = s.server.db.Exec("UPDATE characters SET is_female=false WHERE id=$1", s.charID) } - gr := uint16(decompressedData[130550])<<8 | uint16(decompressedData[130551]) - s.logger.Info("Setting db field", zap.Uint16("gr_override_level", gr)) - // We have to use `gr_override_level` (uint16), not `small_gr_level` (uint8) to store this. - _, err = s.server.db.Exec("UPDATE characters SET gr_override_mode=true, gr_override_level=$1 WHERE id=$2", gr, s.charID) if err != nil { - s.logger.Fatal("Failed to update character gr_override_level in db", zap.Error(err)) + s.logger.Fatal("Failed to character gender in db", zap.Error(err)) } + + weaponId := binary.LittleEndian.Uint16(decompressedData[128522:128524]) // 0x1F60A + _, err = s.server.db.Exec("UPDATE characters SET weapon_id=$1 WHERE id=$2", weaponId, s.charID) + if err != nil { + s.logger.Fatal("Failed to update character weapon id in db", zap.Error(err)) + } + + hrp := binary.LittleEndian.Uint16(decompressedData[130550:130552]) // 0x1FDF6 + _, err = s.server.db.Exec("UPDATE characters SET hrp=$1 WHERE id=$2", hrp, s.charID) + if err != nil { + s.logger.Fatal("Failed to update character hrp in db", zap.Error(err)) + } + + grp := binary.LittleEndian.Uint32(decompressedData[130556:130560]) // 0x1FDFC + var gr uint16 + if grp > 0 { + gr = grpToGR(grp) + } else { + gr = 0 + } + _, err = s.server.db.Exec("UPDATE characters SET gr=$1 WHERE id=$2", gr, s.charID) + if err != nil { + s.logger.Fatal("Failed to update character gr in db", zap.Error(err)) + } + characterName := s.clientContext.StrConv.MustDecode(bfutil.UpToNull(decompressedData[88:100])) _, err = s.server.db.Exec("UPDATE characters SET name=$1 WHERE id=$2", characterName, s.charID) if err != nil { @@ -77,6 +103,53 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } +func grpToGR(n uint32) uint16 { + var gr uint16 + gr = 1 + switch grp := int(n); { + case grp < 208750: // Up to 50 + i := 0 + for { + grp -= 500 + if grp <= 500 { + if grp < 0 { + i-- + } + break + } else { + i++ + for j := 0; j < i; j++ { + grp -= 150 + } + } + } + gr = uint16(i + 2); break + case grp < 593400: // 51-99 + grp -= 208750; i := 51; for { if grp < 7850 {break}; i++; grp -= 7850 }; gr = uint16(i); break + case grp < 993400: // 100-149 + grp -= 593400; i := 100; for { if grp < 8000 {break}; i++; grp -= 8000 }; gr = uint16(i); break + case grp < 1400900: // 150-199 + grp -= 993400; i := 150; for { if grp < 8150 {break}; i++; grp -= 8150 }; gr = uint16(i); break + case grp < 2315900: // 200-299 + grp -= 1400900; i := 200; for { if grp < 9150 {break}; i++; grp -= 9150 }; gr = uint16(i); break + case grp < 3340900: // 300-399 + grp -= 2315900; i := 300; for { if grp < 10250 {break}; i++; grp -= 10250 }; gr = uint16(i); break + case grp < 4505900: // 400-499 + grp -= 3340900; i := 400; for { if grp < 11650 {break}; i++; grp -= 11650 }; gr = uint16(i); break + case grp < 5850900: // 500-599 + grp -= 4505900; i := 500; for { if grp < 13450 {break}; i++; grp -= 13450 }; gr = uint16(i); break + case grp < 7415900: // 600-699 + grp -= 5850900; i := 600; for { if grp < 15650 {break}; i++; grp -= 15650 }; gr = uint16(i); break + case grp < 9230900: // 700-799 + grp -= 7415900; i := 700; for { if grp < 18150 {break}; i++; grp -= 18150 }; gr = uint16(i); break + case grp < 11345900: // 800-899 + grp -= 9230900; i := 800; for { if grp < 21150 {break}; i++; grp -= 21150 }; gr = uint16(i); break + default: // 900+ + grp -= 11345900; i := 900; for { if grp < 23950 {break}; i++; grp -= 23950 }; gr = uint16(i); break + } + return gr +} + func dumpSaveData(s *Session, data []byte, suffix string) { if !s.server.erupeConfig.DevModeOptions.SaveDumps.Enabled { return diff --git a/Erupe/server/channelserver/handlers_diva.go b/Erupe/server/channelserver/handlers_diva.go index 09a8029ec..6dd00e2e8 100644 --- a/Erupe/server/channelserver/handlers_diva.go +++ b/Erupe/server/channelserver/handlers_diva.go @@ -196,7 +196,10 @@ func handleMsgMhfAcquireUdItem(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } -func handleMsgMhfGetUdRanking(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfGetUdRanking(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetUdRanking) + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) +} func handleMsgMhfGetUdMyRanking(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetUdMyRanking) diff --git a/Erupe/server/channelserver/handlers_guild.go b/Erupe/server/channelserver/handlers_guild.go index 41faf3924..f6a9c2929 100644 --- a/Erupe/server/channelserver/handlers_guild.go +++ b/Erupe/server/channelserver/handlers_guild.go @@ -10,6 +10,8 @@ import ( "fmt" "sort" "time" + "strings" + "strconv" "github.com/Andoryuuta/byteframe" "github.com/Solenataris/Erupe/common/bfutil" @@ -47,10 +49,11 @@ type Guild struct { SubMotto uint8 `db:"sub_motto"` CreatedAt time.Time `db:"created_at"` MemberCount uint16 `db:"member_count"` - RP uint32 `db:"rp"` + RankRP uint32 `db:"rank_rp"` + EventRP uint32 `db:"event_rp"` Comment string `db:"comment"` FestivalColour FestivalColour `db:"festival_colour"` - GuildHallType uint16 `db:"guild_hall"` + Rank uint16 `db:"rank"` Icon *GuildIcon `db:"icon"` GuildLeader @@ -64,8 +67,12 @@ type GuildLeader struct { type GuildIconPart struct { Index uint16 ID uint16 + Page uint8 Size uint8 Rotation uint8 + Red uint8 + Green uint8 + Blue uint8 PosX uint16 PosY uint16 } @@ -99,24 +106,33 @@ func (gi *GuildIcon) Value() (valuer driver.Value, err error) { } const guildInfoSelectQuery = ` -SELECT g.id, - g.name, - g.rp, - g.main_motto, - g.sub_motto, - created_at, - leader_id, - lc.name as leader_name, - comment, - festival_colour, - guild_hall, - icon, - ( - SELECT count(1) FROM guild_characters gc WHERE gc.guild_id = g.id - ) AS member_count -FROM guilds g - JOIN guild_characters lgc ON lgc.character_id = leader_id - JOIN characters lc on leader_id = lc.id +SELECT + g.id, + g.name, + g.rank_rp, + g.event_rp, + g.main_motto, + g.sub_motto, + created_at, + leader_id, + lc.name as leader_name, + comment, + festival_colour, + CASE + WHEN g.rank_rp <= 48 THEN g.rank_rp/24 + WHEN g.rank_rp <= 288 THEN g.rank_rp/48+1 + WHEN g.rank_rp <= 504 THEN g.rank_rp/72+3 + WHEN g.rank_rp <= 1080 THEN (g.rank_rp-24)/96+5 + WHEN g.rank_rp < 1200 THEN 16 + ELSE 17 + END rank, + icon, + ( + SELECT count(1) FROM guild_characters gc WHERE gc.guild_id = g.id + ) AS member_count + FROM guilds g + JOIN guild_characters lgc ON lgc.character_id = leader_id + JOIN characters lc on leader_id = lc.id ` func (guild *Guild) Save(s *Session) error { @@ -328,28 +344,6 @@ func (guild *Guild) ArrangeCharacters(s *Session, charIDs []uint32) error { return nil } -func (guild *Guild) DonateRP(s *Session, rp uint16, transaction *sql.Tx) (err error) { - updateSQL := "UPDATE guilds SET rp = rp + $1 WHERE id = $2" - - if transaction != nil { - _, err = transaction.Exec(updateSQL, rp, guild.ID) - } else { - _, err = s.server.db.Exec(updateSQL, rp, guild.ID) - } - - if err != nil { - s.logger.Error( - "failed to donate RP to guild", - zap.Error(err), - zap.Uint32("guildID", guild.ID), - ) - - return err - } - - return nil -} - func (guild *Guild) GetApplicationForCharID(s *Session, charID uint32, applicationType GuildApplicationType) (*GuildApplication, error) { row := s.server.db.QueryRowx(` SELECT * from guild_applications WHERE character_id = $1 AND guild_id = $2 AND application_type = $3 @@ -415,8 +409,8 @@ func CreateGuild(s *Session, guildName string) (int32, error) { } guildResult, err := transaction.Query( - "INSERT INTO guilds (name, leader_id, rp, guild_hall) VALUES ($1, $2, $3, $4) RETURNING id", - guildName, s.charID, 48, 17, + "INSERT INTO guilds (name, leader_id) VALUES ($1, $2) RETURNING id", + guildName, s.charID, ) if err != nil { @@ -617,106 +611,158 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrame() switch pkt.Action { - case mhfpacket.OPERATE_GUILD_ACTION_DISBAND: - if guild.LeaderCharID != s.charID { - s.logger.Warn(fmt.Sprintf("character '%d' is attempting to manage guild '%d' without permission", s.charID, guild.ID)) + case mhfpacket.OPERATE_GUILD_DISBAND: + if guild.LeaderCharID != s.charID { + s.logger.Warn(fmt.Sprintf("character '%d' is attempting to manage guild '%d' without permission", s.charID, guild.ID)) + return + } + + err = guild.Disband(s) + response := 0x01 + + if err != nil { + // All successful acks return 0x01, assuming 0x00 is failure + response = 0x00 + } + + bf.WriteUint32(uint32(response)) + case mhfpacket.OPERATE_GUILD_APPLY: + err = guild.CreateApplication(s, s.charID, GuildApplicationTypeApplied, nil) + + if err != nil { + // All successful acks return 0x01, assuming 0x00 is failure + bf.WriteUint32(0x00) + } else { + bf.WriteUint32(guild.LeaderCharID) + } + case mhfpacket.OPERATE_GUILD_LEAVE: + var err error + + if characterGuildInfo.IsApplicant { + err = guild.RejectApplication(s, s.charID) + } else { + err = guild.RemoveCharacter(s, s.charID) + } + + response := 0x01 + if err != nil { + // All successful acks return 0x01, assuming 0x00 is failure + response = 0x00 + } + + bf.WriteUint32(uint32(response)) + case mhfpacket.OPERATE_GUILD_DONATE_RANK: + handleDonateRP(s, pkt, bf, guild, false) + case mhfpacket.OPERATE_GUILD_SET_APPLICATION_DENY: + // TODO: close applications for guild + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } + case mhfpacket.OPERATE_GUILD_SET_APPLICATION_ALLOW: + // TODO: open applications for guild + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return + case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_TRUE: + handleAvoidLeadershipUpdate(s, pkt, true) + case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE: + handleAvoidLeadershipUpdate(s, pkt, false) + case mhfpacket.OPERATE_GUILD_UPDATE_COMMENT: + pbf := byteframe.NewByteFrameFromBytes(pkt.UnkData) - err = guild.Disband(s) - response := 0x01 + if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + return + } - if err != nil { - // All successful acks return 0x01, assuming 0x00 is failure - response = 0x00 - } + commentLength := pbf.ReadUint8() + _ = pbf.ReadUint32() - bf.WriteUint32(uint32(response)) - case mhfpacket.OPERATE_GUILD_ACTION_APPLY: - err = guild.CreateApplication(s, s.charID, GuildApplicationTypeApplied, nil) + guild.Comment, err = s.clientContext.StrConv.Decode(bfutil.UpToNull(pbf.ReadBytes(uint(commentLength)))) + + if err != nil { + s.logger.Warn("failed to convert guild comment to UTF8", zap.Error(err)) + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + break + } + + err = guild.Save(s) + + if err != nil { + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + return + } - if err != nil { - // All successful acks return 0x01, assuming 0x00 is failure bf.WriteUint32(0x00) - } else { - bf.WriteUint32(guild.LeaderCharID) - } - case mhfpacket.OPERATE_GUILD_ACTION_LEAVE: - var err error + case mhfpacket.OPERATE_GUILD_UPDATE_MOTTO: + if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + return + } - if characterGuildInfo.IsApplicant { - err = guild.RejectApplication(s, s.charID) - } else { - err = guild.RemoveCharacter(s, s.charID) - } + guild.SubMotto = pkt.UnkData[3] + guild.MainMotto = pkt.UnkData[4] - response := 0x01 + err := guild.Save(s) - if err != nil { - // All successful acks return 0x01, assuming 0x00 is failure - response = 0x00 - } - - bf.WriteUint32(uint32(response)) - case mhfpacket.OPERATE_GUILD_ACTION_DONATE: - err := handleOperateGuildActionDonate(s, guild, pkt, bf) - - if err != nil { + if err != nil { + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + return + } + case mhfpacket.OPERATE_GUILD_RENAME_PUGI_1: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } - case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_TRUE: - handleAvoidLeadershipUpdate(s, pkt, true) - case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE: - handleAvoidLeadershipUpdate(s, pkt, false) - case mhfpacket.OPERATE_GUILD_ACTION_UPDATE_COMMENT: - pbf := byteframe.NewByteFrameFromBytes(pkt.UnkData) - - if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { - doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + case mhfpacket.OPERATE_GUILD_RENAME_PUGI_2: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } - - commentLength := pbf.ReadUint8() - _ = pbf.ReadUint32() - - guild.Comment, err = s.clientContext.StrConv.Decode(bfutil.UpToNull(pbf.ReadBytes(uint(commentLength)))) - - if err != nil { - s.logger.Warn("failed to convert guild comment to UTF8", zap.Error(err)) - doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) - break - } - - err = guild.Save(s) - - if err != nil { - doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + case mhfpacket.OPERATE_GUILD_RENAME_PUGI_3: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } - - bf.WriteUint32(0x00) - case mhfpacket.OPERATE_GUILD_ACTION_UPDATE_MOTTO: - if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { - doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_1: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } - - guild.SubMotto = pkt.UnkData[3] - guild.MainMotto = pkt.UnkData[4] - - err := guild.Save(s) - - if err != nil { - doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_2: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return - } - default: - panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action)) + case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_3: + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + return + case mhfpacket.OPERATE_GUILD_DONATE_EVENT: + handleDonateRP(s, pkt, bf, guild, true) + default: + panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action)) } doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) } +func handleDonateRP(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, bf *byteframe.ByteFrame, guild *Guild, isEvent bool) error { + rp := binary.BigEndian.Uint16(pkt.UnkData[3:5]) + saveData, err := GetCharacterSaveData(s, s.charID) + if err != nil { + return err + } + saveData.RP -= rp + transaction, err := s.server.db.Begin() + err = saveData.Save(s, transaction) + if err != nil { + transaction.Rollback() + return err + } + updateSQL := "UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2" + if isEvent { + updateSQL = "UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2" + } + _, err = s.server.db.Exec(updateSQL, rp, guild.ID) + if err != nil { + s.logger.Error("Failed to donate rank RP to guild", zap.Error(err), zap.Uint32("guildID", guild.ID)) + transaction.Rollback() + return err + } else { + transaction.Commit() + } + bf.WriteUint32(uint32(saveData.RP)) + return nil +} + func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, avoidLeadership bool) { characterGuildData, err := GetCharacterGuildData(s, s.charID) @@ -737,93 +783,6 @@ func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } -func handleOperateGuildActionDonate(s *Session, guild *Guild, pkt *mhfpacket.MsgMhfOperateGuild, bf *byteframe.ByteFrame) error { - - var rpDB uint16 - var guildHallLvl uint16 - - rp := binary.BigEndian.Uint16(pkt.UnkData[3:5]) - - saveData, err := GetCharacterSaveData(s, s.charID) - - if err != nil { - return err - } - - if saveData.RP < rp { - s.logger.Warn( - "character attempting to donate more RP than they own", - zap.Uint32("charID", s.charID), - zap.Uint16("rp", rp), - ) - return err - } - - saveData.RP -= rp - - transaction, err := s.server.db.Begin() - - if err != nil { - s.logger.Error("failed to start db transaction", zap.Error(err)) - return err - } - - err = saveData.Save(s, transaction) - - if err != nil { - err = transaction.Rollback() - - if err != nil { - s.logger.Error("failed to rollback transaction", zap.Error(err)) - } - - return err - } - - err = guild.DonateRP(s, rp, transaction) - - if err != nil { - err = transaction.Rollback() - - if err != nil { - s.logger.Error("failed to rollback transaction", zap.Error(err)) - } - - return err - } - - err = transaction.Commit() - - if err != nil { - s.logger.Error("failed to commit transaction", zap.Error(err)) - return err - } - - bf.WriteUint32(uint32(saveData.RP)) // Points remaining - - errSelectSQL := s.server.db.QueryRow("SELECT rp FROM guilds WHERE id=$1", guild.ID).Scan(&rpDB) - - if errSelectSQL != nil { - s.logger.Fatal("Failed to get rp from db", zap.Error(errSelectSQL)) - } - - guildHallLvl = rpDB / 70 - - if guildHallLvl >= 17 { - guildHallLvl = 17 - } - fmt.Printf("\n\nrpDB = %d\n", rpDB) - fmt.Printf("guildHallLvl = %d\n", guildHallLvl) - - _, errUpdateSQL := s.server.db.Exec("UPDATE guilds SET guild_hall=$1 WHERE id=$2", guildHallLvl, guild.ID) - if errUpdateSQL == nil { - s.logger.Error("failed to donate RP to guild", zap.Error(errUpdateSQL), zap.Uint32("guildID", guild.ID)) - return err - } - - return nil -} - func handleMsgMhfOperateGuildMember(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfOperateGuildMember) @@ -924,11 +883,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(guild.ID) bf.WriteUint32(guild.LeaderCharID) - // Unk 0x09 = Guild Hall available, maybe guild hall type? - // Guild hall available on at least - // 0x09 0x08 0x02 - // Should just be outright guild level for guild hall features, 17 gives everything - bf.WriteUint16(guild.GuildHallType) + bf.WriteUint16(guild.Rank) bf.WriteUint16(guild.MemberCount) bf.WriteUint8(guild.MainMotto) @@ -939,7 +894,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { if characterGuildData == nil || characterGuildData.IsApplicant { bf.WriteUint16(0x00) - } else if characterGuildData.IsSubLeader() || guild.LeaderCharID == s.charID { + } else if guild.LeaderCharID == s.charID { bf.WriteUint16(0x01) } else { bf.WriteUint16(0x02) @@ -955,13 +910,13 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint8(uint8(len(leaderName) + 1)) bf.WriteBytes(guildName) bf.WriteBytes(guildComment) - bf.WriteUint8(FestivalColourCodes[guild.FestivalColour]) - - bf.WriteUint32(guild.RP) + bf.WriteUint32(guild.RankRP) bf.WriteNullTerminatedBytes(leaderName) - //bf.WriteBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00}) // Unk - bf.WriteBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x18, 0xBD}) // Level 17 guild's version + bf.WriteBytes([]byte{0x00, 0x00, 0x00, 0x00}) // Unk + bf.WriteBool(false) // isReturnGuild + bf.WriteBytes([]byte{0x01, 0x02, 0x02}) // Unk + bf.WriteUint32(guild.EventRP) // Pugi's names, probably expected as null until you have them with levels? Null gives them a default japanese name for i := 0; i < 3; i++ { @@ -983,30 +938,6 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(0x00) // Alliance ID - // TODO add alliance parts here - // - //if (AllianceID != 0) { - // uint16 AllianceDataUnk; - // uint16 AllianceDataUnk; - // uint16 AllianceNameLength; - // char AllianceName[AllianceNameLength]; - // - // byte NumAllianceMembers; - // - // struct AllianceMember { - // uint32 Unk; - // uint32 Unk; - // uint16 Unk; - // uint16 Unk; - // uint16 Unk; - // uint16 GuildNameLength; - // char GuildName[GuildNameLength]; - // uint16 GuildLeaderNameLength; - // char GuildLeaderName[GuildLeaderNameLength]; - // - // } member[NumAllianceMembers] ; - //} - applicants, err := GetGuildMembers(s, guild.ID, true) if err != nil { @@ -1028,15 +959,6 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteNullTerminatedBytes(applicantName) } - // This is guild icon data - // temp canned bytes to avoid crashing when a guild has more than 1-2 members and a guild hall - //bf.WriteBytes([]byte{0x00, 0x05, 0x00, 0x03, 0x00, 0x38, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x00, 0x03, - // 0x00, 0x02, 0x00, 0x38, 0x01, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x69, 0x00, 0x60, 0x00, 0x01, - // 0x00, 0x38, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x6A, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, - // 0x01, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0x35, 0x01, 0x03, - // 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x11, 0x00, 0x01, 0x00, - //}) - // Unk bool? if true +3 bytes after this bf.WriteUint8(0x00) @@ -1046,11 +968,12 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { for _, p := range guild.Icon.Parts { bf.WriteUint16(p.Index) bf.WriteUint16(p.ID) - bf.WriteUint8(0x01) + bf.WriteUint8(p.Page) bf.WriteUint8(p.Size) bf.WriteUint8(p.Rotation) - bf.WriteUint8(0xFF) - bf.WriteUint16(0xFFFF) + bf.WriteUint8(p.Red) + bf.WriteUint8(p.Green) + bf.WriteUint8(p.Blue) bf.WriteUint16(p.PosX) bf.WriteUint16(p.PosY) } @@ -1073,26 +996,125 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateGuild) var guilds []*Guild + var rows *sqlx.Rows var err error + bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload) switch pkt.Type { - case mhfpacket.ENUMERATE_GUILD_TYPE_NAME: - // I have no idea if is really little endian, but it seems too weird to have a random static - // 0x00 before the string - searchTermLength := binary.LittleEndian.Uint16(pkt.RawDataPayload[9:11]) - searchTerm := pkt.RawDataPayload[11 : 11+searchTermLength] - - var searchTermSafe string - - searchTermSafe, err = s.clientContext.StrConv.Decode(bfutil.UpToNull(searchTerm)) - - if err != nil { - panic(err) - } - - guilds, err = FindGuildsByName(s, searchTermSafe) - default: - panic(fmt.Sprintf("no handler for guild search type '%d'", pkt.Type)) + case mhfpacket.ENUMERATE_GUILD_TYPE_GUILD_NAME: + bf.ReadBytes(8) + searchTermLength := bf.ReadUint16() + bf.ReadBytes(1) + searchTerm := bf.ReadBytes(uint(searchTermLength)) + var searchTermSafe string + searchTermSafe, err = s.clientContext.StrConv.Decode(bfutil.UpToNull(searchTerm)) + if err != nil { + panic(err) + } + guilds, err = FindGuildsByName(s, searchTermSafe) + case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_NAME: + bf.ReadBytes(8) + searchTermLength := bf.ReadUint16() + bf.ReadBytes(1) + searchTerm := bf.ReadBytes(uint(searchTermLength)) + var searchTermSafe string + searchTermSafe, err = s.clientContext.StrConv.Decode(bfutil.UpToNull(searchTerm)) + if err != nil { + panic(err) + } + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE lc.name ILIKE $1`, guildInfoSelectQuery), searchTermSafe) + if err != nil { + s.logger.Error("Failed to retrieve guild by leader name", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_ID: + bf.ReadBytes(3) + ID := bf.ReadUint32() + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE leader_id = $1`, guildInfoSelectQuery), ID) + if err != nil { + s.logger.Error("Failed to retrieve guild by leader ID", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_MEMBERS: + sorting := bf.ReadUint16() + if sorting == 1 { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count DESC`, guildInfoSelectQuery)) + } else { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count ASC`, guildInfoSelectQuery)) + } + if err != nil { + s.logger.Error("Failed to retrieve guild by member count", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_REGISTRATION: + sorting := bf.ReadUint16() + if sorting == 1 { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id DESC`, guildInfoSelectQuery)) + } else { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id ASC`, guildInfoSelectQuery)) + } + if err != nil { + s.logger.Error("Failed to retrieve guild by registration date", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_RANK: + sorting := bf.ReadUint16() + if sorting == 1 { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp DESC`, guildInfoSelectQuery)) + } else { + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp ASC`, guildInfoSelectQuery)) + } + if err != nil { + s.logger.Error("Failed to retrieve guild by rank", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_MOTTO: + bf.ReadBytes(3) + mainMotto := bf.ReadUint16() + subMotto := bf.ReadUint16() + rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE main_motto = $1 AND sub_motto = $2`, guildInfoSelectQuery), mainMotto, subMotto) + if err != nil { + s.logger.Error("Failed to retrieve guild by motto", zap.Error(err)) + } else { + for rows.Next() { + guild, _ := buildGuildObjectFromDbResult(rows, err, s) + guilds = append(guilds, guild) + } + } + case mhfpacket.ENUMERATE_GUILD_TYPE_RECRUITING: + // + case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ALLIANCE_NAME: + // + case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_NAME: + // + case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_ID: + // + case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_MEMBERS: + // + case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_REGISTRATION: + // + default: + panic(fmt.Sprintf("no handler for guild search type '%d'", pkt.Type)) } if err != nil || guilds == nil { @@ -1100,7 +1122,7 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) { return } - bf := byteframe.NewByteFrame() + bf = byteframe.NewByteFrame() bf.WriteUint16(uint16(len(guilds))) for _, guild := range guilds { @@ -1113,12 +1135,12 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(guild.MemberCount) bf.WriteUint8(0x00) // Unk bf.WriteUint8(0x00) // Unk - bf.WriteUint16(0x00) // Rank + bf.WriteUint16(guild.Rank) bf.WriteUint32(uint32(guild.CreatedAt.Unix())) - bf.WriteUint8(uint8(len(guildName))) - bf.WriteBytes(guildName) - bf.WriteUint8(uint8(len(leaderName))) - bf.WriteBytes(leaderName) + bf.WriteUint8(uint8(len(guildName)+1)) + bf.WriteNullTerminatedBytes(guildName) + bf.WriteUint8(uint8(len(leaderName)+1)) + bf.WriteNullTerminatedBytes(leaderName) bf.WriteUint8(0x01) // Unk } @@ -1203,12 +1225,14 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) { name := s.clientContext.StrConv.MustEncode(member.Name) bf.WriteUint32(member.CharID) - - // Exp, HR[x] is split by 0, 1, 30, 50, 99, 299, 998, 999 - bf.WriteUint16(member.Exp) // Rank flags - bf.WriteUint16(0x00) // Grank - bf.WriteUint16(0x00) // Unk - bf.WriteUint16(0x00) // Some rank? + bf.WriteUint16(member.HRP) + bf.WriteUint16(member.GR) + bf.WriteUint16(member.WeaponID) + if member.WeaponType == 1 || member.WeaponType == 5 || member.WeaponType == 10 { // If weapon is ranged + bf.WriteUint16(0x0700) + } else { + bf.WriteUint16(0x0600) + } bf.WriteUint8(member.OrderIndex) bf.WriteUint16(uint16(len(name) + 1)) bf.WriteNullTerminatedBytes(name) @@ -1298,10 +1322,95 @@ func handleMsgMhfGetGuildTargetMemberNum(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfEnumerateGuildItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateGuildItem) + var boxContents []byte + bf := byteframe.NewByteFrame() + err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", int(pkt.GuildId)).Scan(&boxContents) + if err != nil { + s.logger.Fatal("Failed to get guild item box contents from db", zap.Error(err)) + } else { + if len(boxContents) == 0 { + bf.WriteUint32(0x00) + } else { + amount := len(boxContents) / 4 + bf.WriteUint16(uint16(amount)) + bf.WriteUint32(0x00) + bf.WriteUint16(0x00) + for i := 0; i < amount; i++ { + bf.WriteUint32(binary.BigEndian.Uint32(boxContents[i*4:i*4+4])) + if i + 1 != amount { + bf.WriteUint64(0x00) + } + } + } + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} - data, _ := hex.DecodeString("000100004cfa00010017000300000000") +type Item struct{ + ItemId uint16 + Amount uint16 +} - doAckBufSucceed(s, pkt.AckHandle, data) +func handleMsgMhfUpdateGuildItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfUpdateGuildItem) + + // Get item cache from DB + var boxContents []byte + var oldItems []Item + err := s.server.db.QueryRow("SELECT item_box FROM guilds WHERE id = $1", int(pkt.GuildId)).Scan(&boxContents) + if err != nil { + s.logger.Fatal("Failed to get guild item box contents from db", zap.Error(err)) + } else { + amount := len(boxContents) / 4 + oldItems = make([]Item, amount) + for i := 0; i < amount; i++ { + oldItems[i].ItemId = binary.BigEndian.Uint16(boxContents[i*4:i*4+2]) + oldItems[i].Amount = binary.BigEndian.Uint16(boxContents[i*4+2:i*4+4]) + } + } + + // Update item stacks + newItems := make([]Item, len(oldItems)) + copy(newItems, oldItems) + for i := 0; i < int(pkt.Amount); i++ { + for j := 0; j <= len(oldItems); j++ { + if j == len(oldItems) { + var newItem Item + newItem.ItemId = pkt.Items[i].ItemId + newItem.Amount = pkt.Items[i].Amount + newItems = append(newItems, newItem) + break + } + if pkt.Items[i].ItemId == oldItems[j].ItemId { + newItems[j].Amount = pkt.Items[i].Amount + break + } + } + } + + // Delete empty item stacks + for i := len(newItems) - 1; i >= 0; i-- { + if int(newItems[i].Amount) == 0 { + copy(newItems[i:], newItems[i + 1:]) + newItems[len(newItems) - 1] = make([]Item, 1)[0] + newItems = newItems[:len(newItems) - 1] + } + } + + // Create new item cache + bf := byteframe.NewByteFrame() + for i := 0; i < len(newItems); i++ { + bf.WriteUint16(newItems[i].ItemId) + bf.WriteUint16(newItems[i].Amount) + } + + // Upload new item cache + _, err = s.server.db.Exec("UPDATE guilds SET item_box = $1 WHERE id = $2", bf.Data(), int(pkt.GuildId)) + if err != nil { + s.logger.Fatal("Failed to update guild item box contents in db", zap.Error(err)) + } + + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } func handleMsgMhfUpdateGuildIcon(s *Session, p mhfpacket.MHFPacket) { @@ -1337,8 +1446,12 @@ func handleMsgMhfUpdateGuildIcon(s *Session, p mhfpacket.MHFPacket) { icon.Parts[i] = GuildIconPart{ Index: p.Index, ID: p.ID, + Page: p.Page, Size: p.Size, Rotation: p.Rotation, + Red: p.Red, + Green: p.Green, + Blue: p.Blue, PosX: p.PosX, PosY: p.PosY, } @@ -1434,16 +1547,182 @@ func handleMsgMhfGetGuildWeeklyBonusActiveCount(s *Session, p mhfpacket.MHFPacke func handleMsgMhfGuildHuntdata(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGuildHuntdata) - data := []byte{0x01, 0xFE} - doAckBufSucceed(s, pkt.AckHandle, data) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } -// "Enumrate_guild_msg_board" -func handleMsgSysReserve202(s *Session, p mhfpacket.MHFPacket) {} +type MessageBoardPost struct { + Type uint32 `db:"post_type"` + StampID uint32 `db:"stamp_id"` + Title string `db:"title"` + Body string `db:"body"` + AuthorID uint32 `db:"author_id"` + Timestamp uint64 `db:"created_at"` + LikedBy string `db:"liked_by"` +} -// "Is_update_guild_msg_board" -func handleMsgSysReserve203(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgSysReserve203) +func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfEnumerateGuildMessageBoard) + guild, _ := GetGuildInfoByCharacterId(s, s.charID) + + msgs, err := s.server.db.Queryx("SELECT post_type, stamp_id, title, body, author_id, (EXTRACT(epoch FROM created_at)::int) as created_at, liked_by FROM guild_posts WHERE guild_id = $1 AND post_type = $2 ORDER BY created_at DESC", guild.ID, int(pkt.BoardType)) + if err != nil { + s.logger.Fatal("Failed to get guild messages from db", zap.Error(err)) + } + + bf := byteframe.NewByteFrame() + noMsgs := true + postCount := 0 + for msgs.Next() { + noMsgs = false + postCount++ + + postData := &MessageBoardPost{} + err = msgs.StructScan(&postData) + if err != nil { + s.logger.Error("Failed to read guild message board post") + } + + bf.WriteUint32(postData.Type) + bf.WriteUint32(postData.AuthorID) + bf.WriteUint64(postData.Timestamp) + liked := false + likedBySlice := strings.Split(postData.LikedBy, ",") + for i := 0; i < len(likedBySlice); i++ { + j, _ := strconv.ParseInt(likedBySlice[i], 10, 64) + if int(j) == int(s.charID) { + liked = true; break + } + } + if likedBySlice[0] == "" { + bf.WriteUint32(0) + } else { + bf.WriteUint32(uint32(len(likedBySlice))) + } + bf.WriteBool(liked) + bf.WriteUint32(postData.StampID) + bf.WriteUint32(uint32(len(postData.Title))) + bf.WriteBytes([]byte(postData.Title)) + bf.WriteUint32(uint32(len(postData.Body))) + bf.WriteBytes([]byte(postData.Body)) + } + if noMsgs { + doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + } else { + data := byteframe.NewByteFrame() + data.WriteUint32(uint32(postCount)) + data.WriteBytes(bf.Data()) + doAckBufSucceed(s, pkt.AckHandle, data.Data()) + } +} + +func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfUpdateGuildMessageBoard) + bf := byteframe.NewByteFrameFromBytes(pkt.Request) + guild, _ := GetGuildInfoByCharacterId(s, s.charID) + if guild == nil { + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + return + } + switch pkt.MessageOp { + case 0: // Create message + postType := bf.ReadUint32() // 0 = message, 1 = news + stampId := bf.ReadUint32() + titleLength := bf.ReadUint32() + bodyLength := bf.ReadUint32() + title := bf.ReadBytes(uint(titleLength)) + body := bf.ReadBytes(uint(bodyLength)) + _, err := s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, int(stampId), int(postType), string(title), string(body)) + if err != nil { + s.logger.Fatal("Failed to add new guild message to db", zap.Error(err)) + } + // TODO: if there are too many messages, purge excess + _, err = s.server.db.Exec("") + if err != nil { + s.logger.Fatal("Failed to remove excess guild messages from db", zap.Error(err)) + } + case 1: // Delete message + postType := bf.ReadUint32() + timestamp := bf.ReadUint64() + _, err := s.server.db.Exec("DELETE FROM guild_posts WHERE post_type = $1 AND (EXTRACT(epoch FROM created_at)::int) = $2 AND guild_id = $3", int(postType), int(timestamp), guild.ID) + if err != nil { + s.logger.Fatal("Failed to delete guild message from db", zap.Error(err)) + } + case 2: // Update message + postType := bf.ReadUint32() + timestamp := bf.ReadUint64() + titleLength := bf.ReadUint32() + bodyLength := bf.ReadUint32() + title := bf.ReadBytes(uint(titleLength)) + body := bf.ReadBytes(uint(bodyLength)) + _, err := s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE post_type = $3 AND (EXTRACT(epoch FROM created_at)::int) = $4 AND guild_id = $5", string(title), string(body), int(postType), int(timestamp), guild.ID) + if err != nil { + s.logger.Fatal("Failed to update guild message in db", zap.Error(err)) + } + case 3: // Update stamp + postType := bf.ReadUint32() + timestamp := bf.ReadUint64() + stampId := bf.ReadUint32() + _, err := s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", int(stampId), int(postType), int(timestamp), guild.ID) + if err != nil { + s.logger.Fatal("Failed to update guild message stamp in db", zap.Error(err)) + } + case 4: // Like message + postType := bf.ReadUint32() + timestamp := bf.ReadUint64() + likeState := bf.ReadBool() + var likedBy string + err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE post_type = $1 AND (EXTRACT(epoch FROM created_at)::int) = $2 AND guild_id = $3", int(postType), int(timestamp), guild.ID).Scan(&likedBy) + if err != nil { + s.logger.Fatal("Failed to get guild message like data from db", zap.Error(err)) + } else { + if likeState { + if len(likedBy) == 0 { + likedBy = strconv.Itoa(int(s.charID)) + } else { + likedBy += "," + strconv.Itoa(int(s.charID)) + } + _, err := s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", likedBy, int(postType), int(timestamp), guild.ID) + if err != nil { + s.logger.Fatal("Failed to like guild message in db", zap.Error(err)) + } + } else { + likedBySlice := strings.Split(likedBy, ",") + for i, e := range likedBySlice { + if e == strconv.Itoa(int(s.charID)) { + likedBySlice[i] = likedBySlice[len(likedBySlice) - 1] + likedBySlice = likedBySlice[:len(likedBySlice) - 1] + } + } + likedBy = strings.Join(likedBySlice, ",") + _, err := s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE post_type = $2 AND (EXTRACT(epoch FROM created_at)::int) = $3 AND guild_id = $4", likedBy, int(postType), int(timestamp), guild.ID) + if err != nil { + s.logger.Fatal("Failed to unlike guild message in db", zap.Error(err)) + } + } + } + case 5: // Check for new messages + var timeChecked int + var newPosts int + err := s.server.db.QueryRow("SELECT (EXTRACT(epoch FROM guild_post_checked)::int) FROM characters WHERE id = $1", s.charID).Scan(&timeChecked) + if err != nil { + s.logger.Fatal("Failed to get last guild post check timestamp from db", zap.Error(err)) + } else { + _, err = s.server.db.Exec("UPDATE characters SET guild_post_checked = $1 WHERE id = $2", time.Now(), s.charID) + if err != nil { + s.logger.Fatal("Failed to update guild post check timestamp in db", zap.Error(err)) + } else { + err = s.server.db.QueryRow("SELECT COUNT(*) FROM guild_posts WHERE guild_id = $1 AND (EXTRACT(epoch FROM created_at)::int) > $2", guild.ID, timeChecked).Scan(&newPosts) + if err != nil { + s.logger.Fatal("Failed to check for new guild posts in db", zap.Error(err)) + } else { + if newPosts > 0 { + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01}) + return + } + } + } + } + } doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } @@ -1451,7 +1730,12 @@ func handleMsgMhfEntryRookieGuild(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfUpdateForceGuildRank(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfAddGuildWeeklyBonusExceptionalUser(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfAddGuildWeeklyBonusExceptionalUser(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfAddGuildWeeklyBonusExceptionalUser) + // TODO: record pkt.NumUsers to DB + // must use addition + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) +} func handleMsgMhfRegistGuildAdventure(s *Session, p mhfpacket.MHFPacket) {} @@ -1461,7 +1745,10 @@ func handleMsgMhfChargeGuildAdventure(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfAddGuildMissionCount(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfSetGuildMissionTarget(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfSetGuildMissionTarget(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfSetGuildMissionTarget) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} func handleMsgMhfCancelGuildMissionTarget(s *Session, p mhfpacket.MHFPacket) {} @@ -1477,4 +1764,8 @@ func handleMsgMhfOperationInvGuild(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfUpdateGuildcard(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfUpdateGuildItem(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfCreateJoint(s *Session, p mhfpacket.MHFPacket) { } + +func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) { } + +func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) {} \ No newline at end of file diff --git a/Erupe/server/channelserver/handlers_guild_member.go b/Erupe/server/channelserver/handlers_guild_member.go index fae27ec69..db9623b4a 100644 --- a/Erupe/server/channelserver/handlers_guild_member.go +++ b/Erupe/server/channelserver/handlers_guild_member.go @@ -18,7 +18,10 @@ type GuildMember struct { LastLogin uint32 `db:"last_login"` AvoidLeadership bool `db:"avoid_leadership"` IsLeader bool `db:"is_leader"` - Exp uint16 `db:"exp"` + HRP uint16 `db:"hrp"` + GR uint16 `db:"gr"` + WeaponID uint16 `db:"weapon_id"` + WeaponType uint16 `db:"weapon_type"` } func (gm *GuildMember) IsSubLeader() bool { @@ -53,7 +56,10 @@ SELECT g.id as guild_id, coalesce(gc.order_index, 0) as order_index, c.last_login, coalesce(gc.avoid_leadership, false) as avoid_leadership, - c.exp, + c.hrp, + c.gr, + c.weapon_id, + c.weapon_type, character.is_applicant, CASE WHEN g.leader_id = c.id THEN 1 ELSE 0 END as is_leader FROM ( diff --git a/Erupe/server/channelserver/handlers_mail.go b/Erupe/server/channelserver/handlers_mail.go index fb81fff22..b72801394 100644 --- a/Erupe/server/channelserver/handlers_mail.go +++ b/Erupe/server/channelserver/handlers_mail.go @@ -61,7 +61,7 @@ func (m *Mail) Send(s *Session, transaction *sql.Tx) error { func (m *Mail) MarkRead(s *Session) error { _, err := s.server.db.Exec(` - UPDATE mail SET read = true WHERE id = $1 + UPDATE mail SET read = true WHERE id = $1 `, m.ID) if err != nil { @@ -78,7 +78,7 @@ func (m *Mail) MarkRead(s *Session) error { func (m *Mail) MarkDeleted(s *Session) error { _, err := s.server.db.Exec(` - UPDATE mail SET deleted = true WHERE id = $1 + UPDATE mail SET deleted = true WHERE id = $1 `, m.ID) if err != nil { @@ -93,22 +93,40 @@ func (m *Mail) MarkDeleted(s *Session) error { return nil } +func (m *Mail) MarkAcquired(s *Session) error { + _, err := s.server.db.Exec(` + UPDATE mail SET attached_item_received = true WHERE id = $1 + `, m.ID) + + if err != nil { + s.logger.Error( + "failed to mark mail item as claimed", + 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 + SELECT m.id, m.sender_id, m.recipient_id, m.subject, m.read, + m.attached_item_received, m.attached_item, m.attached_item_amount, m.created_at, m.is_guild_invite, m.deleted, c.name as sender_name - FROM mail m - JOIN characters c ON c.id = m.sender_id + FROM mail m + JOIN characters c ON c.id = m.sender_id WHERE recipient_id = $1 AND deleted = false ORDER BY m.created_at DESC, id DESC LIMIT 32 @@ -140,21 +158,22 @@ func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) { func GetMailByID(s *Session, ID int) (*Mail, error) { row := s.server.db.QueryRowx(` - SELECT + SELECT m.id, m.sender_id, m.recipient_id, m.subject, m.read, m.body, + m.attached_item_received, m.attached_item, m.attached_item_amount, m.created_at, m.is_guild_invite, m.deleted, c.name as sender_name - FROM mail m - JOIN characters c ON c.id = m.sender_id + FROM mail m + JOIN characters c ON c.id = m.sender_id WHERE m.id = $1 LIMIT 1 `, ID) @@ -235,9 +254,11 @@ func handleMsgMhfReadMail(s *Session, p mhfpacket.MHFPacket) { _ = mail.MarkRead(s) + bf := byteframe.NewByteFrame() bodyBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(mail.Body) + bf.WriteNullTerminatedBytes(bodyBytes) - doAckBufSucceed(s, pkt.AckHandle, bodyBytes) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) { @@ -295,10 +316,10 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) { msg.WriteUint8(flags) msg.WriteBool(itemAttached) - msg.WriteUint8(uint8(len(subjectBytes))) - msg.WriteUint8(uint8(len(senderNameBytes))) - msg.WriteBytes(subjectBytes) - msg.WriteBytes(senderNameBytes) + msg.WriteUint8(uint8(len(subjectBytes)+1)) + msg.WriteUint8(uint8(len(senderNameBytes)+1)) + msg.WriteNullTerminatedBytes(subjectBytes) + msg.WriteNullTerminatedBytes(senderNameBytes) if itemAttached { msg.WriteInt16(m.AttachedItemAmount) @@ -320,9 +341,14 @@ func handleMsgMhfOprtMail(s *Session, p mhfpacket.MHFPacket) { } switch mhfpacket.OperateMailOperation(pkt.Operation) { - case mhfpacket.OperateMailOperationDelete: + case mhfpacket.OPERATE_MAIL_DELETE: err = mail.MarkDeleted(s) - + if err != nil { + doAckSimpleFail(s, pkt.AckHandle, nil) + panic(err) + } + case mhfpacket.OPERATE_MAIL_ACQUIRE_ITEM: + err = mail.MarkAcquired(s) if err != nil { doAckSimpleFail(s, pkt.AckHandle, nil) panic(err) @@ -332,4 +358,34 @@ func handleMsgMhfOprtMail(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, nil) } -func handleMsgMhfSendMail(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfSendMail(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfSendMail) + query := ` + INSERT INTO mail (sender_id, recipient_id, subject, body, attached_item, attached_item_amount, is_guild_invite) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ` + + if pkt.RecipientID == 0 { // Guild mail + g, err := GetGuildInfoByCharacterId(s, s.charID) + if err != nil { + s.logger.Fatal("Failed to get guild info for mail") + } + gm, err := GetGuildMembers(s, g.ID, false) + if err != nil { + s.logger.Fatal("Failed to get guild members for mail") + } + for i := 0; i < len(gm); i++ { + _, err := s.server.db.Exec(query, s.charID, gm[i].CharID, pkt.Subject, pkt.Body, 0, 0, false) + if err != nil { + s.logger.Fatal("Failed to send mail") + } + } + } else { + _, err := s.server.db.Exec(query, s.charID, pkt.RecipientID, pkt.Subject, pkt.Body, pkt.ItemID, pkt.Quantity, false) + if err != nil { + s.logger.Fatal("Failed to send mail") + } + } + + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} diff --git a/Erupe/server/channelserver/handlers_register.go b/Erupe/server/channelserver/handlers_register.go index c48bdec76..6b19d55cc 100644 --- a/Erupe/server/channelserver/handlers_register.go +++ b/Erupe/server/channelserver/handlers_register.go @@ -1,16 +1,1652 @@ package channelserver import ( - "encoding/hex" + "encoding/hex" + "encoding/binary" + "github.com/Andoryuuta/byteframe" "github.com/Solenataris/Erupe/network/mhfpacket" ) func handleMsgSysOperateRegister(s *Session, p mhfpacket.MHFPacket) { // RAVIENTE USE THIS // RAVI EVENT pkt := p.(*mhfpacket.MsgSysOperateRegister) + var RefID uint8 + var Phase1HP, Phase2HP, Phase3HP, Phase4HP, Phase5HP, Phase6HP, Phase7HP, Phase8HP, Phase9HP, Unknown1, Unknown2, Unknown3, Unknown4, Unknown5, Unknown6, Unknown7, Unknown8, Unknown9, Unknown10, Unknown11, Unknown12, Unknown13, Unknown14, Unknown15, Unknown16, Unknown17, Unknown18, Unknown19, Unknown20 uint32 + var DamageMultiplier uint32 - doAckSimpleSucceed(s, pkt.AckHandle, pkt.RawDataPayload) + var NextRavi, RaviStarted, RaviPostTime, RaviType, MaxPlayers, RaviKilled, CarveQuest, Register1, Register2, Register3, Register4, Register5 uint32 + + var Support1, Support2, Support3, Support4, Support5, Support6, Support7, Support8, Support9, Support10, Support11, Support12, Support13, Support14, Support15, Support16, Support17, Support18, Support19, Support20, Support21, Support22, Support23, Support24, Support25 uint32 + raviState, err := s.server.db.Query("SELECT refid, phase1hp, phase2hp, phase3hp, phase4hp, phase5hp, phase6hp, phase7hp, phase8hp, phase9hp, unknown1, unknown2, unknown3, unknown4, unknown5, unknown6, unknown7, unknown8, unknown9, unknown10, unknown11, unknown12, unknown13, unknown14, unknown15, unknown16, unknown17, unknown18, unknown19, unknown20, damagemultiplier FROM ravistate WHERE RefID=$1", 29) + if err != nil { + panic(err) + } + for raviState.Next() { + err = raviState.Scan(&RefID, &Phase1HP, &Phase2HP, &Phase3HP, &Phase4HP, &Phase5HP, &Phase6HP, &Phase7HP, &Phase8HP, &Phase9HP, &Unknown1, &Unknown2, &Unknown3, &Unknown4, &Unknown5, &Unknown6, &Unknown7, &Unknown8, &Unknown9, &Unknown10, &Unknown11, &Unknown12, &Unknown13, &Unknown14, &Unknown15, &Unknown16, &Unknown17, &Unknown18, &Unknown19, &Unknown20, &DamageMultiplier) + if err != nil { + panic("Error in ravistate") + } + } + raviRegister, err := s.server.db.Query("SELECT refid, nextravi, ravistarted, raviposttime, ravitype, maxplayers, ravikilled, carvequest, register1, register2, register3, register4, register5 FROM raviregister WHERE RefID=$1", 12) + if err != nil { + panic(err) + } + for raviRegister.Next() { + err = raviRegister.Scan(&RefID, &NextRavi, &RaviStarted, &RaviPostTime, &RaviType, &MaxPlayers, &RaviKilled, &CarveQuest, &Register1, &Register2, &Register3, &Register4, &Register5) + if err != nil { + panic("Error in raviregister") + } + } + raviSupport, err := s.server.db.Query("SELECT refid, support1, support2, support3, support4, support5, support6, support7, support8, support9, support10, support11, support12, support13, support14, support15, support16, support17, support18, support19, support20, support21, support22, support23, support24, support25 FROM ravisupport WHERE RefID=$1", 25) + if err != nil { + panic(err) + } + for raviSupport.Next() { + err = raviSupport.Scan(&RefID, &Support1, &Support2, &Support3, &Support4, &Support5, &Support6, &Support7, &Support8, &Support9, &Support10, &Support11, &Support12, &Support13, &Support14, &Support15, &Support16, &Support17, &Support18, &Support19, &Support20, &Support21, &Support22, &Support23, &Support24, &Support25) + if err != nil { + panic("Error in ravisupport") + } + } + + switch pkt.RegisterID { + + case 786461: + resp := byteframe.NewByteFrame() + size := 6 + var j int + for i := 0; i < len(pkt.RawDataPayload)-1; i += size { + j += size + if j > len(pkt.RawDataPayload) { + j = len(pkt.RawDataPayload) + } + AddData := binary.BigEndian.Uint32(pkt.RawDataPayload[i+2:j]) + resp.WriteUint8(1) + resp.WriteUint8(pkt.RawDataPayload[i+1]) + switch pkt.RawDataPayload[i+1] { + case 0: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET nextravi = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 1: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET ravistarted = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 2: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET ravikilled = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 3: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET raviposttime = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 4: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Register1) + resp.WriteUint32(Register1 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE raviregister SET register1 = $1 WHERE refid = $2", Register1 + uint32(AddData), 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register1 = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register1 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + } + case 5: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET carvequest = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 6: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Register2) + resp.WriteUint32(Register2 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE raviregister SET register2 = $1 WHERE refid = $2", Register2 + uint32(AddData), 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register2 = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register2 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + } + case 7: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Register3) + resp.WriteUint32(Register3 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE raviregister SET register3 = $1 WHERE refid = $2", Register3 + uint32(AddData), 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register3 = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register3 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + } + case 8: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Register4) + resp.WriteUint32(Register4 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE raviregister SET register4 = $1 WHERE refid = $2", Register4 + uint32(AddData), 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register4 = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register4 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + } + case 9: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET maxplayers = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 10: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET ravitype = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 11: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Register5) + resp.WriteUint32(Register5 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE raviregister SET register5 = $1 WHERE refid = $2", Register5 + uint32(AddData), 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register5 = $1 WHERE refid = $2", AddData, 12) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE raviregister SET register5 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update raviregister in db") + } + } + default: + resp.WriteUint32(0) + resp.WriteUint32(0) + } + } + resp.WriteUint8(0) + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + s.notifyplayer() + + + + case 917533: + resp := byteframe.NewByteFrame() + size := 6 + var j int + for i := 0; i < len(pkt.RawDataPayload)-1; i += size { + j += size + if j > len(pkt.RawDataPayload) { + j = len(pkt.RawDataPayload) + } + AddData := binary.BigEndian.Uint32(pkt.RawDataPayload[i+2:j]) + resp.WriteUint8(1) + resp.WriteUint8(pkt.RawDataPayload[i+1]) + switch pkt.RawDataPayload[i+1] { + case 0: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase1HP) + resp.WriteUint32(Phase1HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase1HP = $1 WHERE refid = $2", Phase1HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase1HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase1HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 1: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase2HP) + resp.WriteUint32(Phase2HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase2HP = $1 WHERE refid = $2", Phase2HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase2HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase2HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 2: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase3HP) + resp.WriteUint32(Phase3HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase3HP = $1 WHERE refid = $2", Phase3HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase3HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase3HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 3: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase4HP) + resp.WriteUint32(Phase4HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase4HP = $1 WHERE refid = $2", Phase4HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase4HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase4HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 4: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase5HP) + resp.WriteUint32(Phase5HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase5HP = $1 WHERE refid = $2", Phase5HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase5HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase5HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 5: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase6HP) + resp.WriteUint32(Phase6HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase6HP = $1 WHERE refid = $2", Phase6HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase6HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase6HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 6: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase7HP) + resp.WriteUint32(Phase7HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase7HP = $1 WHERE refid = $2", Phase7HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase7HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase7HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 7: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase8HP) + resp.WriteUint32(Phase8HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase8HP = $1 WHERE refid = $2", Phase8HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase8HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase8HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 8: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Phase9HP) + resp.WriteUint32(Phase9HP + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase9HP = $1 WHERE refid = $2", Phase9HP + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase9HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Phase9HP = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 9: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown1) + resp.WriteUint32(Unknown1 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown1 = $1 WHERE refid = $2", Unknown1 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown1 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown1 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 10: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown2) + resp.WriteUint32(Unknown2 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown2 = $1 WHERE refid = $2", Unknown2 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown2 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown2 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 11: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown3) + resp.WriteUint32(Unknown3 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown3 = $1 WHERE refid = $2", Unknown3 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown3 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown3 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 12: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown4) + resp.WriteUint32(Unknown4 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown4 = $1 WHERE refid = $2", Unknown4 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown4 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown4 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 13: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown5) + resp.WriteUint32(Unknown5 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown5 = $1 WHERE refid = $2", Unknown5 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown5 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown5 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 14: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown6) + resp.WriteUint32(Unknown6 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown6 = $1 WHERE refid = $2", Unknown6 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown6 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown6 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 15: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown7) + resp.WriteUint32(Unknown7 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown7 = $1 WHERE refid = $2", Unknown7 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown7 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown7 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 16: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown8) + resp.WriteUint32(Unknown8 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown8 = $1 WHERE refid = $2", Unknown8 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown8 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown8 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 17: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown9) + resp.WriteUint32(Unknown9 + (uint32(AddData) * DamageMultiplier)) + if DamageMultiplier == 1 { + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown9 = $1 WHERE refid = $2", Unknown9 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown9 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown9 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 18: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown10) + resp.WriteUint32(Unknown10 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown10 = $1 WHERE refid = $2", Unknown10 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown10 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown10 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 19: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown11) + resp.WriteUint32(Unknown11 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown11 = $1 WHERE refid = $2", Unknown11 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown11 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown11 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 20: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown12) + resp.WriteUint32(Unknown12 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown12 = $1 WHERE refid = $2", Unknown12 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown12 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown12 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 21: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown13) + resp.WriteUint32(Unknown13 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown13 = $1 WHERE refid = $2", Unknown13 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown13 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown13 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 22: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown14) + resp.WriteUint32(Unknown14 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown14 = $1 WHERE refid = $2", Unknown14 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown14 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown14 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 23: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown15) + resp.WriteUint32(Unknown15 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown15 = $1 WHERE refid = $2", Unknown15 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown15 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown15 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 24: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown16) + resp.WriteUint32(Unknown16 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown16 = $1 WHERE refid = $2", Unknown16 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown16 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown16 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 25: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown17) + resp.WriteUint32(Unknown17 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown17 = $1 WHERE refid = $2", Unknown17 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown17 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown17 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 26: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown18) + resp.WriteUint32(Unknown18 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown18 = $1 WHERE refid = $2", Unknown18 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown18 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown18 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 27: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown19) + resp.WriteUint32(Unknown19 + (uint32(AddData) * DamageMultiplier)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown19 = $1 WHERE refid = $2", Unknown19 + (uint32(AddData) * DamageMultiplier), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown19 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown19 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + case 28: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Unknown20) + resp.WriteUint32(Unknown20 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown20 = $1 WHERE refid = $2", Unknown20 + uint32(AddData), 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown20 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravistate SET Unknown20 = $1 WHERE refid = $2", AddData, 29) + if err != nil { + s.logger.Fatal("Failed to update ravistate in db") + } + } + + default: + resp.WriteUint32(0) + resp.WriteUint32(0) + } + } + + resp.WriteUint8(0) + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + s.notifyplayer() + + + + case 851997: + resp := byteframe.NewByteFrame() + size := 6 + var j int + for i := 0; i < len(pkt.RawDataPayload)-1; i += size { + j += size + if j > len(pkt.RawDataPayload) { + j = len(pkt.RawDataPayload) + } + AddData := binary.BigEndian.Uint32(pkt.RawDataPayload[i+2:j]) + resp.WriteUint8(1) + resp.WriteUint8(pkt.RawDataPayload[i+1]) + switch pkt.RawDataPayload[i+1] { + case 0: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support1) + resp.WriteUint32(Support1 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support1 = $1 WHERE refid = $2", Support1 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support1 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support1 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 1: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support2) + resp.WriteUint32(Support2 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support2 = $1 WHERE refid = $2", Support2 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support2 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support2 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 2: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support3) + resp.WriteUint32(Support3 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support3 = $1 WHERE refid = $2", Support3 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support3 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support3 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 3: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support4) + resp.WriteUint32(Support4 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support4 = $1 WHERE refid = $2", Support4 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support4 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support4 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 4: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support5) + resp.WriteUint32(Support5 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support5 = $1 WHERE refid = $2", Support5 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support5 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support5 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 5: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support6) + resp.WriteUint32(Support6 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support6 = $1 WHERE refid = $2", Support6 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support6 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support6 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 6: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support7) + resp.WriteUint32(Support7 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support7 = $1 WHERE refid = $2", Support7 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support7 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support7 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 7: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support8) + resp.WriteUint32(Support8 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support8 = $1 WHERE refid = $2", Support8 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support8 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support8 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 8: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support9) + resp.WriteUint32(Support9 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support9 = $1 WHERE refid = $2", Support9 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support9 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support9 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 9: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support10) + resp.WriteUint32(Support10 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support10 = $1 WHERE refid = $2", Support10 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support10 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support10 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 10: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support11) + resp.WriteUint32(Support11 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support11 = $1 WHERE refid = $2", Support11 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support11 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support11 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 11: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support12) + resp.WriteUint32(Support12 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support12 = $1 WHERE refid = $2", Support12 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support12 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support12 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 12: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support13) + resp.WriteUint32(Support13 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support13 = $1 WHERE refid = $2", Support13 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support13 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support13 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 13: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support14) + resp.WriteUint32(Support14 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support14 = $1 WHERE refid = $2", Support14 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support14 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support14 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 14: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support15) + resp.WriteUint32(Support15 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support15 = $1 WHERE refid = $2", Support15 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support15 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support15 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 15: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support16) + resp.WriteUint32(Support16 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support16 = $1 WHERE refid = $2", Support16 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support16 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support16 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 16: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support17) + resp.WriteUint32(Support17 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support17 = $1 WHERE refid = $2", Support17 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support17 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support17 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 17: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support18) + resp.WriteUint32(Support18 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support18 = $1 WHERE refid = $2", Support18 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support18 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support18 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 18: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support19) + resp.WriteUint32(Support19 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support19 = $1 WHERE refid = $2", Support19 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support19 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support19 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 19: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support20) + resp.WriteUint32(Support20 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support20 = $1 WHERE refid = $2", Support20 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support20 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support20 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 20: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support21) + resp.WriteUint32(Support21 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support21 = $1 WHERE refid = $2", Support21 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support21 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support21 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 21: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support22) + resp.WriteUint32(Support22 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support22 = $1 WHERE refid = $2", Support22 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support22 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support22 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 22: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support23) + resp.WriteUint32(Support23 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support23 = $1 WHERE refid = $2", Support23 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support23 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support23 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 23: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support24) + resp.WriteUint32(Support24 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support24 = $1 WHERE refid = $2", Support24 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support24 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support24 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + case 24: + switch pkt.RawDataPayload[i] { + case 2: + resp.WriteUint32(Support25) + resp.WriteUint32(Support25 + uint32(AddData)) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support25 = $1 WHERE refid = $2", Support25 + uint32(AddData), 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 13: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support25 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + case 14: + resp.WriteUint32(0) + resp.WriteUint32(AddData) + _, err = s.server.db.Exec("UPDATE ravisupport SET Support25 = $1 WHERE refid = $2", AddData, 25) + if err != nil { + s.logger.Fatal("Failed to update ravisupport in db") + } + } + + default: + resp.WriteUint32(0) + resp.WriteUint32(0) + + + } + } + resp.WriteUint8(0) + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + s.notifyplayer() + + + } } func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) { @@ -18,9 +1654,183 @@ func handleMsgSysLoadRegister(s *Session, p mhfpacket.MHFPacket) { // ORION TEMPORARY DISABLE (IN WORK) // ravi response - data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - //data, _ := hex.DecodeString("00000076001d0001b2c4000227d1000221040000a959000000000000000000000000000000000000000000532d1c0010ee8e001fe0010007f463000000000017e53e00072e250053937a0000194a00002d5a000000000000000000004eb300004cd700000000000008a90000be400001bb16000005dd00000014") - doAckBufSucceed(s, pkt.AckHandle, data) + r := pkt.Unk1 + switch r { + case 12: + var count int + + err := s.server.db.QueryRow("SELECT COUNT(*) FROM raviregister").Scan(&count) + switch { + case err != nil: + panic(err) + default: + if count == 0 { + s.server.db.Exec("CALL raviinit()") + } + } + if pkt.RegisterID == 983077 { + data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + doAckBufFail(s, pkt.AckHandle, data) + } else if pkt.RegisterID == 983069 { + data, _ := hex.DecodeString("000C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + doAckBufFail(s, pkt.AckHandle, data) + } + raviRegister, err := s.server.db.Query("SELECT refid, nextravi, ravistarted, raviposttime, ravitype, maxplayers, ravikilled, carvequest, register1, register2, register3, register4, register5 FROM raviregister WHERE RefID=$1", pkt.Unk1) + if err != nil { + panic(err) + } + var RefID uint8 + var NextRavi, RaviStarted, RaviPostTime, RaviType, MaxPlayers, RaviKilled, CarveQuest, Register1, Register2, Register3, Register4, Register5 uint32 + resp := byteframe.NewByteFrame() + for raviRegister.Next() { + err = raviRegister.Scan(&RefID, &NextRavi, &RaviStarted, &RaviPostTime, &RaviType, &MaxPlayers, &RaviKilled, &CarveQuest, &Register1, &Register2, &Register3, &Register4, &Register5) + if err != nil { + panic("Error in raviregister") + } + resp.WriteUint8(0) + resp.WriteUint8(RefID) + resp.WriteUint32(NextRavi) + resp.WriteUint32(RaviStarted) + resp.WriteUint32(RaviKilled) + resp.WriteUint32(RaviPostTime) + resp.WriteUint32(Register1) + resp.WriteUint32(CarveQuest) + resp.WriteUint32(Register2) + resp.WriteUint32(Register3) + resp.WriteUint32(Register4) + resp.WriteUint32(MaxPlayers) + resp.WriteUint32(RaviType) + resp.WriteUint32(Register5) + } + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + case 29: + raviState, err := s.server.db.Query("SELECT refid, phase1hp, phase2hp, phase3hp, phase4hp, phase5hp, phase6hp, phase7hp, phase8hp, phase9hp, unknown1, unknown2, unknown3, unknown4, unknown5, unknown6, unknown7, unknown8, unknown9, unknown10, unknown11, unknown12, unknown13, unknown14, unknown15, unknown16, unknown17, unknown18, unknown19, unknown20 FROM ravistate WHERE RefID=$1", pkt.Unk1) + if err != nil { + panic(err) + } + var RefID uint8 + var Phase1HP, Phase2HP, Phase3HP, Phase4HP, Phase5HP, Phase6HP, Phase7HP, Phase8HP, Phase9HP, Unknown1, Unknown2, Unknown3, Unknown4, Unknown5, Unknown6, Unknown7, Unknown8, Unknown9, Unknown10, Unknown11, Unknown12, Unknown13, Unknown14, Unknown15, Unknown16, Unknown17, Unknown18, Unknown19, Unknown20 uint32 + resp := byteframe.NewByteFrame() + for raviState.Next() { + err = raviState.Scan(&RefID, &Phase1HP, &Phase2HP, &Phase3HP, &Phase4HP, &Phase5HP, &Phase6HP, &Phase7HP, &Phase8HP, &Phase9HP, &Unknown1, &Unknown2, &Unknown3, &Unknown4, &Unknown5, &Unknown6, &Unknown7, &Unknown8, &Unknown9, &Unknown10, &Unknown11, &Unknown12, &Unknown13, &Unknown14, &Unknown15, &Unknown16, &Unknown17, &Unknown18, &Unknown19, &Unknown20) + if err != nil { + panic("Error in ravistate") + } + resp.WriteUint8(0) + resp.WriteUint8(RefID) + resp.WriteUint32(Phase1HP) + resp.WriteUint32(Phase2HP) + resp.WriteUint32(Phase3HP) + resp.WriteUint32(Phase4HP) + resp.WriteUint32(Phase5HP) + resp.WriteUint32(Phase6HP) + resp.WriteUint32(Phase7HP) + resp.WriteUint32(Phase8HP) + resp.WriteUint32(Phase9HP) + resp.WriteUint32(Unknown1) + resp.WriteUint32(Unknown2) + resp.WriteUint32(Unknown3) + resp.WriteUint32(Unknown4) + resp.WriteUint32(Unknown5) + resp.WriteUint32(Unknown6) + resp.WriteUint32(Unknown7) + resp.WriteUint32(Unknown8) + resp.WriteUint32(Unknown9) + resp.WriteUint32(Unknown10) + resp.WriteUint32(Unknown11) + resp.WriteUint32(Unknown12) + resp.WriteUint32(Unknown13) + resp.WriteUint32(Unknown14) + resp.WriteUint32(Unknown15) + resp.WriteUint32(Unknown16) + resp.WriteUint32(Unknown17) + resp.WriteUint32(Unknown18) + resp.WriteUint32(Unknown19) + resp.WriteUint32(Unknown20) + } + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + case 25: + raviSupport, err := s.server.db.Query("SELECT refid, support1, support2, support3, support4, support5, support6, support7, support8, support9, support10, support11, support12, support13, support14, support15, support16, support17, support18, support19, support20, support21, support22, support23, support24, support25 FROM ravisupport WHERE RefID=$1", pkt.Unk1) + if err != nil { + panic(err) + } + var RefID uint8 + var Support1, Support2, Support3, Support4, Support5, Support6, Support7, Support8, Support9, Support10, Support11, Support12, Support13, Support14, Support15, Support16, Support17, Support18, Support19, Support20, Support21, Support22, Support23, Support24, Support25 uint32 + resp := byteframe.NewByteFrame() + for raviSupport.Next() { + err = raviSupport.Scan(&RefID, &Support1, &Support2, &Support3, &Support4, &Support5, &Support6, &Support7, &Support8, &Support9, &Support10, &Support11, &Support12, &Support13, &Support14, &Support15, &Support16, &Support17, &Support18, &Support19, &Support20, &Support21, &Support22, &Support23, &Support24, &Support25) + if err != nil { + panic("Error in ravisupport") + } + resp.WriteUint8(0) + resp.WriteUint8(RefID) + resp.WriteUint32(Support1) + resp.WriteUint32(Support2) + resp.WriteUint32(Support3) + resp.WriteUint32(Support4) + resp.WriteUint32(Support5) + resp.WriteUint32(Support6) + resp.WriteUint32(Support7) + resp.WriteUint32(Support8) + resp.WriteUint32(Support9) + resp.WriteUint32(Support10) + resp.WriteUint32(Support11) + resp.WriteUint32(Support12) + resp.WriteUint32(Support13) + resp.WriteUint32(Support14) + resp.WriteUint32(Support15) + resp.WriteUint32(Support16) + resp.WriteUint32(Support17) + resp.WriteUint32(Support18) + resp.WriteUint32(Support19) + resp.WriteUint32(Support20) + resp.WriteUint32(Support21) + resp.WriteUint32(Support22) + resp.WriteUint32(Support23) + resp.WriteUint32(Support24) + resp.WriteUint32(Support25) + } + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + } } -func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} +func (s *Session) notifyplayer() { + + s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D}) + + s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D}) + + s.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D}) + +} + +func (s *Session) notifyall() { + + for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients { + session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0E, 0x00, 0x1D}) + } + + for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients { + session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0D, 0x00, 0x1D}) + } + + for session := range s.server.semaphore["hs_l0u3B51J9k3"].clients { + session.QueueSendNonBlocking([]byte{0x00, 0x3F, 0x00, 0x0C, 0x00, 0x1D}) + } + + +} + +func (s *Session) notifyticker() { + + 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 { + s.notifyall() + } + } +} + +func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {} \ No newline at end of file diff --git a/Erupe/server/channelserver/handlers_semaphore.go b/Erupe/server/channelserver/handlers_semaphore.go index 38c91f4c8..208491369 100644 --- a/Erupe/server/channelserver/handlers_semaphore.go +++ b/Erupe/server/channelserver/handlers_semaphore.go @@ -12,13 +12,35 @@ func handleMsgSysCreateSemaphore(s *Session, p mhfpacket.MHFPacket) { } func handleMsgSysDeleteSemaphore(s *Session, p mhfpacket.MHFPacket) { - //pkt := p.(*mhfpacket.MsgSysDeleteSemaphore) - - s.semaphore.Lock() + pkt := p.(*mhfpacket.MsgSysDeleteSemaphore) + sem := pkt.AckHandle + if s.server.semaphore != nil { + s.server.semaphoreLock.Lock() for id := range s.server.semaphore { - delete(s.server.semaphore[id].reservedClientSlots, s.charID) + switch sem { + case 917533: + if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k3" { + delete(s.server.semaphore["hs_l0u3B51J9k3"].reservedClientSlots, s.charID) + delete(s.server.semaphore["hs_l0u3B51J9k3"].clients, s) + } + case 851997: + if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k4" { + delete(s.server.semaphore["hs_l0u3B51J9k4"].reservedClientSlots, s.charID) + } + case 786461: + if s.server.semaphore[id].id_semaphore == "hs_l0u3B51J9k5" { + delete(s.server.semaphore["hs_l0u3B51J9k5"].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" { + delete(s.server.semaphore[id].reservedClientSlots, s.charID) + } + } + } + } + s.server.semaphoreLock.Unlock() } - s.semaphore.Unlock() } func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) { @@ -49,11 +71,33 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) { s.logger.Info("IS ALREADY EXIST !") doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x1D}) } else if uint16(len(newSemaphore.reservedClientSlots)) < newSemaphore.maxPlayers { - newSemaphore.reservedClientSlots[s.charID] = nil - s.Lock() - s.semaphore = newSemaphore - s.Unlock() - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x1D}) + switch SemaphoreID { + case "hs_l0u3B51J9k3": + 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": + newSemaphore.reservedClientSlots[s.charID] = nil + s.Lock() + s.semaphore = newSemaphore + s.Unlock() + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0D, 0x00, 0x1D}) + case "hs_l0u3B51J9k5": + newSemaphore.reservedClientSlots[s.charID] = nil + s.Lock() + s.semaphore = newSemaphore + s.Unlock() + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0C, 0x00, 0x1D}) + default: + newSemaphore.reservedClientSlots[s.charID] = nil + s.Lock() + s.semaphore = newSemaphore + s.Unlock() + doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x0F, 0x00, 0x25}) + } } else { doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } @@ -65,15 +109,26 @@ func handleMsgSysAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysReleaseSemaphore(s *Session, p mhfpacket.MHFPacket) { //pkt := p.(*mhfpacket.MsgSysReleaseSemaphore) - for _, session := range s.server.sessions { - session.semaphore.Lock() - for id := range session.server.semaphore { - delete(s.server.semaphore[id].reservedClientSlots, s.charID) + 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) } - session.semaphore.Unlock() } - //data, _ := hex.DecodeString("000180e703000d443b37ff006d00131809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010627426400a936a93600000100cf330600cc31cc31d431000025000000000000000000010218330600bd3cbd3cbd3c01032c280600ee3dee3da9360104f3300600d231a936a93601054a310600e23ae23ae23a00000d0000000000004d814c0000000003008501d723b7334001e7038b3fd437d516113505000000e7030001000002000203000000000000fafafafafafafafafafafafafafa000000000000ecb2000060da0000000000000000000000000000000000000000000000000000000000000000000000000000181818187e2d00003b31702d662d402e000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000") - //doAckBufSucceed(s, pkt.AckHandle, data) +} + +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() } func handleMsgSysCheckSemaphore(s *Session, p mhfpacket.MHFPacket) { diff --git a/Erupe/server/channelserver/handlers_table.go b/Erupe/server/channelserver/handlers_table.go index 0e7039552..cc7d76e18 100644 --- a/Erupe/server/channelserver/handlers_table.go +++ b/Erupe/server/channelserver/handlers_table.go @@ -429,8 +429,8 @@ func init() { handlerTable[network.MSG_SYS_reserve19F] = handleMsgSysReserve19F handlerTable[network.MSG_MHF_UPDATE_FORCE_GUILD_RANK] = handleMsgMhfUpdateForceGuildRank handlerTable[network.MSG_MHF_RESET_TITLE] = handleMsgMhfResetTitle - handlerTable[network.MSG_SYS_reserve202] = handleMsgSysReserve202 - handlerTable[network.MSG_SYS_reserve203] = handleMsgSysReserve203 + handlerTable[network.MSG_MHF_ENUMERATE_GUILD_MESSAGE_BOARD] = handleMsgMhfEnumerateGuildMessageBoard + handlerTable[network.MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD] = handleMsgMhfUpdateGuildMessageBoard handlerTable[network.MSG_SYS_reserve204] = handleMsgSysReserve204 handlerTable[network.MSG_SYS_reserve205] = handleMsgSysReserve205 handlerTable[network.MSG_SYS_reserve206] = handleMsgSysReserve206 diff --git a/Erupe/server/channelserver/handlers_tactics.go b/Erupe/server/channelserver/handlers_tactics.go index 827ac6856..43cd57ad0 100644 --- a/Erupe/server/channelserver/handlers_tactics.go +++ b/Erupe/server/channelserver/handlers_tactics.go @@ -48,7 +48,12 @@ func handleMsgMhfGetUdTacticsFirstQuestBonus(s *Session, p mhfpacket.MHFPacket) func handleMsgMhfGetUdTacticsRemainingPoint(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfGetUdTacticsRanking(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfGetUdTacticsRanking(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetUdTacticsRanking) + // Temporary canned response + data, _ := hex.DecodeString("00000515000005150000CEB4000003CE000003CE0000CEB44D49444E494748542D414E47454C0000000000000000000000") + doAckBufSucceed(s, pkt.AckHandle, data) +} func handleMsgMhfSetUdTacticsFollower(s *Session, p mhfpacket.MHFPacket) {} diff --git a/Erupe/server/channelserver/sys_semaphore.go b/Erupe/server/channelserver/sys_semaphore.go index 1e653cdbc..f5854496b 100644 --- a/Erupe/server/channelserver/sys_semaphore.go +++ b/Erupe/server/channelserver/sys_semaphore.go @@ -1,6 +1,9 @@ package channelserver import ( + "github.com/Andoryuuta/byteframe" + "github.com/Solenataris/Erupe/network/mhfpacket" + "sync" ) @@ -11,6 +14,10 @@ type Semaphore struct { // Stage ID string id_semaphore string + // Map of session -> charID. + // These are clients that are CURRENTLY in the stage + clients map[*Session]uint32 + // Map of charID -> interface{}, only the key is used, value is always nil. reservedClientSlots map[uint32]interface{} @@ -22,8 +29,46 @@ type Semaphore struct { func NewSemaphore(ID string, MaxPlayers uint16) *Semaphore { s := &Semaphore{ id_semaphore: ID, + clients: make(map[*Session]uint32), reservedClientSlots: make(map[uint32]interface{}), maxPlayers: MaxPlayers, } return s } + +func (s *Semaphore) BroadcastRavi(pkt mhfpacket.MHFPacket) { + // Broadcast the data. + for session := range s.clients { + + + // Make the header + bf := byteframe.NewByteFrame() + bf.WriteUint16(uint16(pkt.Opcode())) + + // Build the packet onto the byteframe. + pkt.Build(bf, session.clientContext) + + // Enqueue in a non-blocking way that drops the packet if the connections send buffer channel is full. + session.QueueSendNonBlocking(bf.Data()) + } +} + +// BroadcastMHF queues a MHFPacket to be sent to all sessions in the stage. +func (s *Semaphore) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session) { + // Broadcast the data. + for session := range s.clients { + if session == ignoredSession { + continue + } + + // Make the header + bf := byteframe.NewByteFrame() + bf.WriteUint16(uint16(pkt.Opcode())) + + // Build the packet onto the byteframe. + pkt.Build(bf, session.clientContext) + + // Enqueue in a non-blocking way that drops the packet if the connections send buffer channel is full. + session.QueueSendNonBlocking(bf.Data()) + } +} \ No newline at end of file diff --git a/Erupe/server/channelserver/sys_session.go b/Erupe/server/channelserver/sys_session.go index ffb5d5e05..162cf8827 100644 --- a/Erupe/server/channelserver/sys_session.go +++ b/Erupe/server/channelserver/sys_session.go @@ -32,6 +32,8 @@ type Session struct { reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet. charID uint32 logKey []byte + sessionStart int64 + rights uint32 semaphore *Semaphore // Required for the stateful MsgSysUnreserveStage packet. @@ -62,6 +64,7 @@ func NewSession(server *Server, conn net.Conn) *Session { Encoding: japanese.ShiftJIS, }, }, + sessionStart: Time_Current_Adjusted().Unix(), stageMoveStack: stringstack.New(), } return s @@ -177,6 +180,7 @@ func (s *Session) handlePacketGroup(pktGroup []byte) { opcode != network.MSG_SYS_PING && opcode != network.MSG_SYS_NOP && opcode != network.MSG_SYS_TIME && + opcode != network.MSG_SYS_POSITION_OBJECT && opcode != network.MSG_SYS_EXTEND_THRESHOLD { fmt.Printf("[%s] send to Server\n", s.Name) fmt.Printf("Opcode: %s\n", opcode) diff --git a/Erupe/server/signserver/dbutils.go b/Erupe/server/signserver/dbutils.go index 161244224..05791258b 100644 --- a/Erupe/server/signserver/dbutils.go +++ b/Erupe/server/signserver/dbutils.go @@ -26,9 +26,9 @@ func (s *Server) newUserChara(username string) error { _, err = s.db.Exec(` INSERT INTO characters ( - user_id, is_female, is_new_character, small_gr_level, gr_override_mode, name, unk_desc_string, - gr_override_level, gr_override_unk0, gr_override_unk1, exp, weapon, last_login) - VALUES($1, False, True, 0, True, '', '', 0, 0, 0, 0, 0, $2)`, + user_id, is_female, is_new_character, name, unk_desc_string, + hrp, gr, weapon_type, last_login) + VALUES($1, False, True, '', '', 1, 0, 0, $2)`, id, uint32(time.Now().Unix()), ) @@ -60,9 +60,9 @@ func (s *Server) registerDBAccount(username string, password string) error { // Create a base new character. _, err = s.db.Exec(` INSERT INTO characters ( - user_id, is_female, is_new_character, small_gr_level, gr_override_mode, name, unk_desc_string, - gr_override_level, gr_override_unk0, gr_override_unk1, exp, weapon, last_login) - VALUES($1, False, True, 0, True, '', '', 0, 0, 0, 0, 0, $2)`, + user_id, is_female, is_new_character, name, unk_desc_string, + hrp, gr, weapon_type, last_login) + VALUES($1, False, True, '', '', 1, 0, 0, $2)`, id, uint32(time.Now().Unix()), ) @@ -77,21 +77,17 @@ type character struct { ID uint32 `db:"id"` IsFemale bool `db:"is_female"` IsNewCharacter bool `db:"is_new_character"` - SmallGRLevel uint8 `db:"small_gr_level"` - GROverrideMode bool `db:"gr_override_mode"` Name string `db:"name"` UnkDescString string `db:"unk_desc_string"` - GROverrideLevel uint16 `db:"gr_override_level"` - GROverrideUnk0 uint8 `db:"gr_override_unk0"` - GROverrideUnk1 uint8 `db:"gr_override_unk1"` - Exp uint16 `db:"exp"` - Weapon uint16 `db:"weapon"` + HRP uint16 `db:"hrp"` + GR uint16 `db:"gr"` + WeaponType uint16 `db:"weapon_type"` LastLogin uint32 `db:"last_login"` } func (s *Server) getCharactersForUser(uid int) ([]character, error) { characters := []character{} - err := s.db.Select(&characters, "SELECT id, is_female, is_new_character, small_gr_level, gr_override_mode, name, unk_desc_string, gr_override_level, gr_override_unk0, gr_override_unk1, exp, weapon, last_login FROM characters WHERE user_id = $1", uid) + err := s.db.Select(&characters, "SELECT id, is_female, is_new_character, name, unk_desc_string, hrp, gr, weapon_type, last_login FROM characters WHERE user_id = $1", uid) if err != nil { return nil, err } diff --git a/Erupe/server/signserver/dsgn_resp.go b/Erupe/server/signserver/dsgn_resp.go index 3980656a6..18c370271 100644 --- a/Erupe/server/signserver/dsgn_resp.go +++ b/Erupe/server/signserver/dsgn_resp.go @@ -2,6 +2,8 @@ package signserver import ( "fmt" + "math/rand" + "time" "github.com/Andoryuuta/byteframe" "go.uber.org/zap" @@ -32,6 +34,15 @@ func makeSignInFailureResp(respID RespID) []byte { return bf.Data() } +func randSeq(n int) string { + var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} + func (s *Session) makeSignInResp(uid int) []byte { // Get the characters from the DB. chars, err := s.server.getCharactersForUser(uid) @@ -39,14 +50,18 @@ func (s *Session) makeSignInResp(uid int) []byte { s.logger.Warn("Error getting characters from DB", zap.Error(err)) } + rand.Seed(time.Now().UnixNano()) + token := randSeq(16) + // TODO: register token to db, users table + bf := byteframe.NewByteFrame() - bf.WriteUint8(1) // resp_code - bf.WriteUint8(0) // file/patch server count - bf.WriteUint8(4) // entrance server count - bf.WriteUint8(uint8(len(chars))) // character count - bf.WriteUint32(0xFFFFFFFF) // login_token_number - bf.WriteBytes(paddedString("logintokenstrng", 16)) // login_token (16 byte padded string) + bf.WriteUint8(1) // resp_code + bf.WriteUint8(0) // file/patch server count + bf.WriteUint8(4) // entrance server count + bf.WriteUint8(uint8(len(chars))) // character count + bf.WriteUint32(0xFFFFFFFF) // login_token_number + bf.WriteBytes(paddedString(token, 16)) // login_token (16 byte padded string) bf.WriteUint32(1576761190) uint8PascalString(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.HostIP, s.server.erupeConfig.Entrance.Port)) uint8PascalString(bf, "") @@ -60,24 +75,18 @@ func (s *Session) makeSignInResp(uid int) []byte { if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.MaxLauncherHR { bf.WriteUint16(999) } else { - bf.WriteUint16(char.Exp) + bf.WriteUint16(char.HRP) } - - bf.WriteUint16(char.Weapon) // Weapon, 0-13. + bf.WriteUint16(char.WeaponType) // Weapon, 0-13. bf.WriteUint32(char.LastLogin) // Last login date, unix timestamp in seconds. bf.WriteBool(char.IsFemale) // Sex, 0=male, 1=female. bf.WriteBool(char.IsNewCharacter) // Is new character, 1 replaces character name with ?????. - bf.WriteUint8(char.SmallGRLevel) // GR level if grMode == 0 - bf.WriteBool(char.GROverrideMode) // GR mode. + bf.WriteUint8(0) // Old GR + bf.WriteBool(true) // Use uint16 GR, no reason not to bf.WriteBytes(paddedString(char.Name, 16)) // Character name bf.WriteBytes(paddedString(char.UnkDescString, 32)) // unk str - if char.GROverrideMode { - bf.SetLE() - bf.WriteUint16(char.GROverrideLevel) // GR level override. - bf.SetBE() - bf.WriteUint8(char.GROverrideUnk0) // unk - bf.WriteUint8(char.GROverrideUnk1) // unk - } + bf.WriteUint16(char.GR) + bf.WriteUint16(0) // Unk } bf.WriteUint8(0) // friends_list_count diff --git a/Erupe/www/erupe/index.html b/Erupe/www/erupe/index.html index 0a5dee251..09047c5e1 100644 --- a/Erupe/www/erupe/index.html +++ b/Erupe/www/erupe/index.html @@ -71,12 +71,21 @@

Important Updates