mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
Move ~39 inline SQL queries from six handler files into repo_guild.go, consolidating all guild-related DB access (posts, alliances, adventures, treasure hunts, meals, kill logs, scouts) behind GuildRepository methods. Handler files now contain only packet serialization, business logic, and ACK responses with no direct database calls.
284 lines
7.5 KiB
Go
284 lines
7.5 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"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)
|
|
|
|
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 {
|
|
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x04})
|
|
return
|
|
}
|
|
|
|
transaction, err := s.server.db.Begin()
|
|
|
|
if err != nil {
|
|
s.logger.Error("Failed to begin transaction for guild scout", zap.Error(err))
|
|
doAckBufFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
err = s.server.guildRepo.CreateApplication(guildInfo.ID, pkt.CharID, s.charID, GuildApplicationTypeInvited, transaction)
|
|
|
|
if err != nil {
|
|
_ = transaction.Rollback()
|
|
s.logger.Error("Failed to create guild scout application", zap.Error(err))
|
|
doAckBufFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
mail := &Mail{
|
|
SenderID: s.charID,
|
|
RecipientID: pkt.CharID,
|
|
Subject: s.server.i18n.guild.invite.title,
|
|
Body: fmt.Sprintf(
|
|
s.server.i18n.guild.invite.body,
|
|
guildInfo.Name,
|
|
),
|
|
IsGuildInvite: true,
|
|
}
|
|
|
|
err = mail.Send(s, transaction)
|
|
|
|
if err != nil {
|
|
_ = transaction.Rollback()
|
|
doAckBufFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
err = transaction.Commit()
|
|
|
|
if err != nil {
|
|
s.logger.Error("Failed to commit guild scout transaction", zap.Error(err))
|
|
doAckBufFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
|
}
|
|
|
|
func handleMsgMhfCancelGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfCancelGuildScout)
|
|
|
|
guildCharData, err := s.server.guildRepo.GetCharacterMembership(s.charID)
|
|
|
|
if err != nil {
|
|
s.logger.Error("Failed to get character guild data for cancel scout", zap.Error(err))
|
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
|
|
if guildCharData == nil || !guildCharData.CanRecruit() {
|
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
|
|
guild, err := s.server.guildRepo.GetByID(guildCharData.GuildID)
|
|
|
|
if err != nil {
|
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
|
|
err = s.server.guildRepo.CancelInvitation(guild.ID, pkt.InvitationID)
|
|
|
|
if err != nil {
|
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
|
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
}
|
|
|
|
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))
|
|
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
|
|
}
|
|
|
|
var mail []Mail
|
|
if pkt.Answer {
|
|
err = s.server.guildRepo.AcceptApplication(guild.ID, s.charID)
|
|
mail = append(mail, Mail{
|
|
RecipientID: s.charID,
|
|
Subject: s.server.i18n.guild.invite.success.title,
|
|
Body: fmt.Sprintf(s.server.i18n.guild.invite.success.body, guild.Name),
|
|
IsSystemMessage: true,
|
|
})
|
|
mail = append(mail, Mail{
|
|
SenderID: s.charID,
|
|
RecipientID: pkt.LeaderID,
|
|
Subject: s.server.i18n.guild.invite.accepted.title,
|
|
Body: fmt.Sprintf(s.server.i18n.guild.invite.accepted.body, guild.Name),
|
|
IsSystemMessage: true,
|
|
})
|
|
} else {
|
|
err = s.server.guildRepo.RejectApplication(guild.ID, s.charID)
|
|
mail = append(mail, Mail{
|
|
RecipientID: s.charID,
|
|
Subject: s.server.i18n.guild.invite.rejected.title,
|
|
Body: fmt.Sprintf(s.server.i18n.guild.invite.rejected.body, guild.Name),
|
|
IsSystemMessage: true,
|
|
})
|
|
mail = append(mail, Mail{
|
|
SenderID: s.charID,
|
|
RecipientID: pkt.LeaderID,
|
|
Subject: s.server.i18n.guild.invite.declined.title,
|
|
Body: fmt.Sprintf(s.server.i18n.guild.invite.declined.body, guild.Name),
|
|
IsSystemMessage: true,
|
|
})
|
|
}
|
|
if err != nil {
|
|
bf.WriteUint32(7)
|
|
bf.WriteUint32(guild.ID)
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
} else {
|
|
bf.WriteUint32(0)
|
|
bf.WriteUint32(guild.ID)
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
for _, m := range mail {
|
|
_ = m.Send(s, nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleMsgMhfGetGuildScoutList(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfGetGuildScoutList)
|
|
|
|
guildInfo, _ := s.server.guildRepo.GetByCharID(s.charID)
|
|
|
|
if guildInfo == nil && s.prevGuildID == 0 {
|
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
} else {
|
|
guildInfo, err := s.server.guildRepo.GetByID(s.prevGuildID)
|
|
if guildInfo == nil || err != nil {
|
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
}
|
|
|
|
chars, err := s.server.guildRepo.ListInvitedCharacters(guildInfo.ID)
|
|
if err != nil {
|
|
s.logger.Error("failed to retrieve scouted characters", zap.Error(err))
|
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
return
|
|
}
|
|
|
|
bf := byteframe.NewByteFrame()
|
|
bf.SetBE()
|
|
bf.WriteUint32(uint32(len(chars)))
|
|
|
|
for _, sc := range chars {
|
|
// This seems to be used as a unique ID for the invitation sent
|
|
// we can just use the charID and then filter on guild_id+charID when performing operations
|
|
// this might be a problem later with mails sent referencing IDs but we'll see.
|
|
bf.WriteUint32(sc.CharID)
|
|
bf.WriteUint32(sc.ActorID)
|
|
bf.WriteUint32(sc.CharID)
|
|
bf.WriteUint32(uint32(TimeAdjusted().Unix()))
|
|
bf.WriteUint16(sc.HR)
|
|
bf.WriteUint16(sc.GR)
|
|
bf.WriteBytes(stringsupport.PaddedString(sc.Name, 32, true))
|
|
}
|
|
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
}
|
|
|
|
func handleMsgMhfGetRejectGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfGetRejectGuildScout)
|
|
|
|
currentStatus, err := s.server.charRepo.ReadBool(s.charID, "restrict_guild_scout")
|
|
|
|
if err != nil {
|
|
s.logger.Error(
|
|
"failed to retrieve character guild scout status",
|
|
zap.Error(err),
|
|
zap.Uint32("charID", s.charID),
|
|
)
|
|
doAckSimpleFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
response := uint8(0x00)
|
|
|
|
if currentStatus {
|
|
response = 0x01
|
|
}
|
|
|
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, response})
|
|
}
|
|
|
|
func handleMsgMhfSetRejectGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfSetRejectGuildScout)
|
|
|
|
err := s.server.charRepo.SaveBool(s.charID, "restrict_guild_scout", pkt.Reject)
|
|
|
|
if err != nil {
|
|
s.logger.Error(
|
|
"failed to update character guild scout status",
|
|
zap.Error(err),
|
|
zap.Uint32("charID", s.charID),
|
|
)
|
|
doAckSimpleFail(s, pkt.AckHandle, nil)
|
|
return
|
|
}
|
|
|
|
doAckSimpleSucceed(s, pkt.AckHandle, nil)
|
|
}
|