diff --git a/network/mhfpacket/msg_mhf_set_guild_manage_right.go b/network/mhfpacket/msg_mhf_set_guild_manage_right.go index 5f9b98a2e..3feed2654 100644 --- a/network/mhfpacket/msg_mhf_set_guild_manage_right.go +++ b/network/mhfpacket/msg_mhf_set_guild_manage_right.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfSetGuildManageRight represents the MSG_MHF_SET_GUILD_MANAGE_RIGHT -type MsgMhfSetGuildManageRight struct{} +type MsgMhfSetGuildManageRight struct { + AckHandle uint32 + CharID uint32 + Allowed bool + Unk []byte +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfSetGuildManageRight) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfSetGuildManageRight) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfSetGuildManageRight) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.CharID = bf.ReadUint32() + m.Allowed = bf.ReadBool() + m.Unk = bf.ReadBytes(3) + return nil } // Build builds a binary packet from the current data. diff --git a/patch-schema/guild-enumeration.sql b/patch-schema/guild-enumeration.sql index 5ccfb3306..1e7e522a3 100644 --- a/patch-schema/guild-enumeration.sql +++ b/patch-schema/guild-enumeration.sql @@ -3,4 +3,7 @@ BEGIN; ALTER TABLE IF EXISTS public.guilds ADD COLUMN IF NOT EXISTS recruiting bool NOT NULL DEFAULT true; +ALTER TABLE IF EXISTS public.guild_characters + ADD COLUMN IF NOT EXISTS recruiter bool NOT NULL DEFAULT false; + END; \ No newline at end of file diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index 4265e4a19..fcaddbaf9 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -889,7 +889,9 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint8(guild.SubMotto) // Unk appears to be static - bf.WriteBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + bf.WriteBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + + bf.WriteBool(!guild.Recruiting) if characterGuildData == nil || characterGuildData.IsApplicant { bf.WriteUint16(0x00) @@ -1385,7 +1387,8 @@ func handleMsgMhfGetGuildManageRight(s *Session, p mhfpacket.MHFPacket) { for _, member := range members { bf.WriteUint32(member.CharID) - bf.WriteUint32(0x0) + bf.WriteBool(member.Recruiter) + bf.WriteBytes(make([]byte, 3)) } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) @@ -1877,7 +1880,12 @@ func handleMsgMhfGenerateUdGuildMap(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfUpdateGuild(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfSetGuildManageRight(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfSetGuildManageRight(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfSetGuildManageRight) + s.server.db.Exec("UPDATE guild_characters SET recruiter=$1 WHERE character_id=$2", pkt.Allowed, pkt.CharID) + // TODO: What is this supposed to return? This works for now + doAckBufSucceed(s, pkt.AckHandle, []byte{0x01}) +} func handleMsgMhfEnumerateInvGuild(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateInvGuild) diff --git a/server/channelserver/handlers_guild_member.go b/server/channelserver/handlers_guild_member.go index db9623b4a..5fa83fb6b 100644 --- a/server/channelserver/handlers_guild_member.go +++ b/server/channelserver/handlers_guild_member.go @@ -16,6 +16,7 @@ type GuildMember struct { IsApplicant bool `db:"is_applicant"` OrderIndex uint8 `db:"order_index"` LastLogin uint32 `db:"last_login"` + Recruiter bool `db:"recruiter"` AvoidLeadership bool `db:"avoid_leadership"` IsLeader bool `db:"is_leader"` HRP uint16 `db:"hrp"` @@ -43,36 +44,33 @@ func (gm *GuildMember) Save(s *Session) error { return nil } -//TODO add the recruiter permission to this check when it exists -func (gm *GuildMember) IsRecruiter() bool { - return gm.IsLeader || gm.IsSubLeader() -} - const guildMembersSelectSQL = ` -SELECT g.id as guild_id, - joined_at, - c.name, - character.character_id, - coalesce(gc.order_index, 0) as order_index, - c.last_login, - coalesce(gc.avoid_leadership, false) as avoid_leadership, - 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 ( - SELECT character_id, true as is_applicant, guild_id - FROM guild_applications ga - WHERE ga.application_type = 'applied' - UNION - SELECT character_id, false as is_applicant, guild_id - FROM guild_characters gc - ) character - JOIN characters c on character.character_id = c.id - LEFT JOIN guild_characters gc ON gc.character_id = character.character_id - JOIN guilds g ON g.id = character.guild_id +SELECT + g.id as guild_id, + joined_at, + c.name, + character.character_id, + coalesce(gc.order_index, 0) as order_index, + c.last_login, + coalesce(gc.recruiter, false) as recruiter, + coalesce(gc.avoid_leadership, false) as avoid_leadership, + 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 ( + SELECT character_id, true as is_applicant, guild_id + FROM guild_applications ga + WHERE ga.application_type = 'applied' + UNION + SELECT character_id, false as is_applicant, guild_id + FROM guild_characters gc + ) character + JOIN characters c on character.character_id = c.id + LEFT JOIN guild_characters gc ON gc.character_id = character.character_id + JOIN guilds g ON g.id = character.guild_id ` func GetGuildMembers(s *Session, guildID uint32, applicants bool) ([]*GuildMember, error) { diff --git a/server/channelserver/handlers_guild_scout.go b/server/channelserver/handlers_guild_scout.go index ec04835ef..4bcbb6b91 100644 --- a/server/channelserver/handlers_guild_scout.go +++ b/server/channelserver/handlers_guild_scout.go @@ -21,7 +21,7 @@ func handleMsgMhfPostGuildScout(s *Session, p mhfpacket.MHFPacket) { panic(err) } - if actorCharGuildData == nil || !actorCharGuildData.IsRecruiter() { + if actorCharGuildData == nil || !actorCharGuildData.Recruiter { doAckBufFail(s, pkt.AckHandle, make([]byte, 4)) return } @@ -104,7 +104,7 @@ func handleMsgMhfCancelGuildScout(s *Session, p mhfpacket.MHFPacket) { panic(err) } - if guildCharData == nil || !guildCharData.IsRecruiter() { + if guildCharData == nil || !guildCharData.Recruiter { doAckBufFail(s, pkt.AckHandle, make([]byte, 4)) return }