From cd6561dd61b35fca3327b657a363eb1b0c8943a9 Mon Sep 17 00:00:00 2001 From: wish Date: Sat, 3 Sep 2022 19:49:39 +1000 Subject: [PATCH] rework guild operations --- network/mhfpacket/msg_mhf_operate_guild.go | 60 +++++++------- server/channelserver/handlers_guild.go | 93 ++++++++++------------ 2 files changed, 73 insertions(+), 80 deletions(-) diff --git a/network/mhfpacket/msg_mhf_operate_guild.go b/network/mhfpacket/msg_mhf_operate_guild.go index ea986cda2..f141796cb 100644 --- a/network/mhfpacket/msg_mhf_operate_guild.go +++ b/network/mhfpacket/msg_mhf_operate_guild.go @@ -1,39 +1,39 @@ package mhfpacket import ( - "errors" + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) type OperateGuildAction uint8 const ( - 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 + 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 + OPERATE_GUILD_EVENT_EXCHANGE = 0x16 + 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 @@ -41,7 +41,8 @@ type MsgMhfOperateGuild struct { AckHandle uint32 GuildID uint32 Action OperateGuildAction - UnkData []byte + Data1 *byteframe.ByteFrame + Data2 *byteframe.ByteFrame } // Opcode returns the ID associated with this packet type. @@ -54,8 +55,9 @@ func (m *MsgMhfOperateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien m.AckHandle = bf.ReadUint32() m.GuildID = bf.ReadUint32() m.Action = OperateGuildAction(bf.ReadUint8()) - m.UnkData = bf.DataFromCurrent() - bf.Seek(int64(len(bf.Data()) - 2), 0) + dataLen := uint(bf.ReadUint8()) + m.Data1 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(4)) + m.Data2 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(dataLen)) return nil } diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index 6bbee7eba..327f35781 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -634,11 +634,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { } bf.WriteUint32(uint32(response)) - doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) - return case mhfpacket.OPERATE_GUILD_RESIGN: guildMembers, err := GetGuildMembers(s, guild.ID, false) - success := false if err == nil { sort.Slice(guildMembers[:], func(i, j int) bool { return guildMembers[i].OrderIndex < guildMembers[j].OrderIndex @@ -651,29 +648,17 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { guildMembers[0].Save(s) guildMembers[i].Save(s) bf.WriteUint32(guildMembers[i].CharID) - success = true break } } guild.Save(s) - doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) } - if !success { - bf.WriteUint32(0) - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) - } - return 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 { + if err == nil { bf.WriteUint32(guild.LeaderCharID) } - doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) - return case mhfpacket.OPERATE_GUILD_LEAVE: var err error @@ -698,10 +683,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { } bf.WriteUint32(uint32(response)) - doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) - return case mhfpacket.OPERATE_GUILD_DONATE_RANK: - handleDonateRP(s, pkt, bf, guild, false) + bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, false)) case mhfpacket.OPERATE_GUILD_SET_APPLICATION_DENY: s.server.db.Exec("UPDATE guilds SET recruiting=false WHERE id=$1", guild.ID) case mhfpacket.OPERATE_GUILD_SET_APPLICATION_ALLOW: @@ -711,46 +694,55 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) { case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE: handleAvoidLeadershipUpdate(s, pkt, false) case mhfpacket.OPERATE_GUILD_UPDATE_COMMENT: - pbf := byteframe.NewByteFrameFromBytes(pkt.UnkData) if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) return } - _ = pbf.ReadUint8() // len - _ = pbf.ReadUint32() - guild.Comment = stringsupport.SJISToUTF8(pbf.ReadNullTerminatedBytes()) + guild.Comment = stringsupport.SJISToUTF8(pkt.Data2.ReadNullTerminatedBytes()) guild.Save(s) case mhfpacket.OPERATE_GUILD_UPDATE_MOTTO: if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() { doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) return } - guild.SubMotto = pkt.UnkData[3] - guild.MainMotto = pkt.UnkData[4] + _ = pkt.Data1.ReadUint16() + guild.SubMotto = pkt.Data1.ReadUint8() + guild.MainMotto = pkt.Data1.ReadUint8() guild.Save(s) case mhfpacket.OPERATE_GUILD_RENAME_PUGI_1: - handleRenamePugi(s, pkt.UnkData, guild, 1) + handleRenamePugi(s, pkt.Data2, guild, 1) case mhfpacket.OPERATE_GUILD_RENAME_PUGI_2: - handleRenamePugi(s, pkt.UnkData, guild, 2) + handleRenamePugi(s, pkt.Data2, guild, 2) case mhfpacket.OPERATE_GUILD_RENAME_PUGI_3: - handleRenamePugi(s, pkt.UnkData, guild, 3) + handleRenamePugi(s, pkt.Data2, guild, 3) case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_1: // TODO: decode guild poogie outfits case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_2: case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_3: case mhfpacket.OPERATE_GUILD_DONATE_EVENT: - handleDonateRP(s, pkt, bf, guild, true) + bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, true)) + case mhfpacket.OPERATE_GUILD_EVENT_EXCHANGE: + rp := uint16(pkt.Data1.ReadUint32()) + saveData, _ := GetCharacterSaveData(s, s.charID) + saveData.RP -= rp + transaction, err := s.server.db.Begin() + err = saveData.Save(s, transaction) + if err != nil { + transaction.Rollback() + } + bf.WriteUint32(uint32(saveData.RP)) default: panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action)) } - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + if len(bf.Data()) > 0 { + doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) + } else { + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + } } -func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) { - bf := byteframe.NewByteFrameFromBytes(data) - _ = bf.ReadUint8() // len - _ = bf.ReadUint32() // unk +func handleRenamePugi(s *Session, bf *byteframe.ByteFrame, guild *Guild, num int) { name := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) switch num { case 1: @@ -763,33 +755,30 @@ func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) { guild.Save(s) } -func handleDonateRP(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, bf *byteframe.ByteFrame, guild *Guild, isEvent bool) error { - rp := binary.BigEndian.Uint16(pkt.UnkData[3:5]) +func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byte { + bf := byteframe.NewByteFrame() + bf.WriteUint32(0) saveData, err := GetCharacterSaveData(s, s.charID) if err != nil { - return err + return bf.Data() } - saveData.RP -= rp + saveData.RP -= amount transaction, err := s.server.db.Begin() err = saveData.Save(s, transaction) if err != nil { transaction.Rollback() - return err + return bf.Data() + } else { + transaction.Commit() } 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() - } + s.server.db.Exec(updateSQL, amount, guild.ID) + bf.Seek(0, 0) bf.WriteUint32(uint32(saveData.RP)) - return nil + return bf.Data() } func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, avoidLeadership bool) { @@ -1712,9 +1701,11 @@ func handleMsgMhfGetGuildWeeklyBonusMaster(s *Session, p mhfpacket.MHFPacket) { } func handleMsgMhfGetGuildWeeklyBonusActiveCount(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetGuildWeeklyBonusActiveCount) - - // Values taken from brand new guild capture - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 0x03)) + bf := byteframe.NewByteFrame() + bf.WriteUint8(0x3C) // Active count + bf.WriteUint8(0x3C) // Current active count + bf.WriteUint8(0x00) // New active count + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } func handleMsgMhfGuildHuntdata(s *Session, p mhfpacket.MHFPacket) {