mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-28 10:32:55 +01:00
refactor(guild): extract disband, resign, leave, and scout logic into GuildService
Move business logic for guild disband, resign leadership, leave, post scout, and answer scout from handlers into GuildService methods. Handlers now delegate to the service layer and handle only protocol concerns (packet parsing, ACK responses, cross-channel notifications). Adds 22 new table-driven service tests and sentinel errors for typed error handling (ErrNoEligibleLeader, ErrAlreadyInvited, etc.). DonateRP left in handler due to Session coupling.
This commit is contained in:
@@ -1,59 +1,29 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/common/stringsupport"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func handleMsgMhfPostGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfPostGuildScout)
|
||||
|
||||
actorCharGuildData, err := s.server.guildRepo.GetCharacterMembership(s.charID)
|
||||
err := s.server.guildService.PostScout(s.charID, pkt.CharID, ScoutInviteStrings{
|
||||
Title: s.server.i18n.guild.invite.title,
|
||||
Body: s.server.i18n.guild.invite.body,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get character guild data for scout", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
if actorCharGuildData == nil || !actorCharGuildData.CanRecruit() {
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
guildInfo, err := s.server.guildRepo.GetByID(actorCharGuildData.GuildID)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get guild info for scout", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
hasApplication, err := s.server.guildRepo.HasApplication(guildInfo.ID, pkt.CharID)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to check application for scout", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
if hasApplication {
|
||||
if errors.Is(err, ErrAlreadyInvited) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x04})
|
||||
return
|
||||
}
|
||||
|
||||
err = s.server.guildRepo.CreateApplicationWithMail(
|
||||
guildInfo.ID, pkt.CharID, s.charID, GuildApplicationTypeInvited,
|
||||
s.charID, pkt.CharID,
|
||||
s.server.i18n.guild.invite.title,
|
||||
fmt.Sprintf(s.server.i18n.guild.invite.body, guildInfo.Name))
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to create guild scout application with mail", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, nil)
|
||||
s.logger.Error("Failed to post guild scout", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,64 +65,37 @@ func handleMsgMhfCancelGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfAnswerGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfAnswerGuildScout)
|
||||
bf := byteframe.NewByteFrame()
|
||||
guild, err := s.server.guildRepo.GetByCharID(pkt.LeaderID)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get guild info for answer scout", zap.Error(err))
|
||||
i := s.server.i18n.guild.invite
|
||||
result, err := s.server.guildService.AnswerScout(s.charID, pkt.LeaderID, pkt.Answer, AnswerScoutStrings{
|
||||
SuccessTitle: i.success.title,
|
||||
SuccessBody: i.success.body,
|
||||
AcceptedTitle: i.accepted.title,
|
||||
AcceptedBody: i.accepted.body,
|
||||
RejectedTitle: i.rejected.title,
|
||||
RejectedBody: i.rejected.body,
|
||||
DeclinedTitle: i.declined.title,
|
||||
DeclinedBody: i.declined.body,
|
||||
})
|
||||
|
||||
if err != nil && !errors.Is(err, ErrApplicationMissing) {
|
||||
s.logger.Error("Failed to answer guild scout", zap.Error(err))
|
||||
doAckBufFail(s, pkt.AckHandle, nil)
|
||||
return
|
||||
}
|
||||
|
||||
app, err := s.server.guildRepo.GetApplication(guild.ID, s.charID, GuildApplicationTypeInvited)
|
||||
|
||||
if app == nil || err != nil {
|
||||
s.logger.Warn(
|
||||
"Guild invite missing, deleted?",
|
||||
zap.Error(err),
|
||||
zap.Uint32("guildID", guild.ID),
|
||||
zap.Uint32("charID", s.charID),
|
||||
)
|
||||
bf.WriteUint32(7)
|
||||
bf.WriteUint32(guild.ID)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
return
|
||||
}
|
||||
|
||||
type mailMsg struct {
|
||||
senderID uint32
|
||||
recipientID uint32
|
||||
subject string
|
||||
body string
|
||||
}
|
||||
var msgs []mailMsg
|
||||
if pkt.Answer {
|
||||
err = s.server.guildRepo.AcceptApplication(guild.ID, s.charID)
|
||||
msgs = append(msgs,
|
||||
mailMsg{0, s.charID, s.server.i18n.guild.invite.success.title, fmt.Sprintf(s.server.i18n.guild.invite.success.body, guild.Name)},
|
||||
mailMsg{s.charID, pkt.LeaderID, s.server.i18n.guild.invite.accepted.title, fmt.Sprintf(s.server.i18n.guild.invite.accepted.body, guild.Name)},
|
||||
)
|
||||
} else {
|
||||
err = s.server.guildRepo.RejectApplication(guild.ID, s.charID)
|
||||
msgs = append(msgs,
|
||||
mailMsg{0, s.charID, s.server.i18n.guild.invite.rejected.title, fmt.Sprintf(s.server.i18n.guild.invite.rejected.body, guild.Name)},
|
||||
mailMsg{s.charID, pkt.LeaderID, s.server.i18n.guild.invite.declined.title, fmt.Sprintf(s.server.i18n.guild.invite.declined.body, guild.Name)},
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
bf.WriteUint32(7)
|
||||
bf.WriteUint32(guild.ID)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
} else {
|
||||
bf := byteframe.NewByteFrame()
|
||||
if result != nil && result.Success {
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteUint32(guild.ID)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
for _, m := range msgs {
|
||||
if err := s.server.mailRepo.SendMail(m.senderID, m.recipientID, m.subject, m.body, 0, 0, false, true); err != nil {
|
||||
s.logger.Warn("Failed to send guild scout response mail", zap.Error(err))
|
||||
}
|
||||
} else {
|
||||
if errors.Is(err, ErrApplicationMissing) {
|
||||
s.logger.Warn("Guild invite missing, deleted?",
|
||||
zap.Uint32("charID", s.charID))
|
||||
}
|
||||
bf.WriteUint32(7)
|
||||
}
|
||||
bf.WriteUint32(result.GuildID)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGetGuildScoutList(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
Reference in New Issue
Block a user