fix(channelserver): add fail ACKs to silent error paths to prevent client softlocks

Handlers that log errors and return without sending a MsgSysAck leave
the client waiting indefinitely. Add doAckSimpleFail/doAckBufFail to
14 error paths across 4 files, matching the pattern already used in
~70 other error paths across the codebase.

Affected handlers:
- handleMsgMhfGetCafeDuration (1 path)
- handleMsgMhfSavedata (1 path)
- handleMsgMhfArrangeGuildMember (3 paths)
- handleMsgMhfEnumerateGuildMember (5 paths)
- handleMsgSysLogin (4 paths)
- handleMsgSysIssueLogkey (1 path)
This commit is contained in:
Houmgaor
2026-02-20 19:35:25 +01:00
parent 91fbc22f28
commit 24ccc167fe
4 changed files with 15 additions and 0 deletions

View File

@@ -97,6 +97,7 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
err = s.server.db.QueryRow("SELECT cafe_time FROM characters WHERE id = $1", s.charID).Scan(&cafeTime)
if err != nil {
s.logger.Error("Failed to get cafe time", zap.Error(err))
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
if mhfcourse.CourseExists(30, s.courses) {

View File

@@ -22,6 +22,7 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
characterSaveData, err := GetCharacterSaveData(s, s.charID)
if err != nil {
s.logger.Error("failed to retrieve character save data from db", zap.Error(err), zap.Uint32("charID", s.charID))
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
// Var to hold the decompressed savedata for updating the launcher response fields.

View File

@@ -44,6 +44,7 @@ func handleMsgMhfArrangeGuildMember(s *Session, p mhfpacket.MHFPacket) {
"failed to respond to ArrangeGuildMember message",
zap.Uint32("charID", s.charID),
)
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
@@ -52,6 +53,7 @@ func handleMsgMhfArrangeGuildMember(s *Session, p mhfpacket.MHFPacket) {
zap.Uint32("charID", s.charID),
zap.Uint32("guildID", guild.ID),
)
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
@@ -63,6 +65,7 @@ func handleMsgMhfArrangeGuildMember(s *Session, p mhfpacket.MHFPacket) {
zap.Uint32("charID", s.charID),
zap.Uint32("guildID", guild.ID),
)
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
@@ -106,12 +109,14 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) {
if err != nil {
s.logger.Error("failed to retrieve guild")
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
alliance, err := GetAllianceData(s, guild.AllianceID)
if err != nil {
s.logger.Error("Failed to get alliance data")
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
@@ -155,6 +160,7 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) {
mems, err := GetGuildMembers(s, alliance.ParentGuildID, false)
if err != nil {
s.logger.Error("Failed to get parent guild members for alliance", zap.Error(err))
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
for _, m := range mems {
@@ -165,6 +171,7 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) {
mems, err := GetGuildMembers(s, alliance.SubGuild1ID, false)
if err != nil {
s.logger.Error("Failed to get sub guild 1 members for alliance", zap.Error(err))
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
for _, m := range mems {
@@ -175,6 +182,7 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) {
mems, err := GetGuildMembers(s, alliance.SubGuild2ID, false)
if err != nil {
s.logger.Error("Failed to get sub guild 2 members for alliance", zap.Error(err))
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}
for _, m := range mems {

View File

@@ -77,24 +77,28 @@ func handleMsgSysLogin(s *Session, p mhfpacket.MHFPacket) {
_, err := s.server.db.Exec("UPDATE servers SET current_players=$1 WHERE server_id=$2", len(s.server.sessions), s.server.ID)
if err != nil {
s.logger.Error("Failed to update current players", zap.Error(err))
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
_, err = s.server.db.Exec("UPDATE sign_sessions SET server_id=$1, char_id=$2 WHERE token=$3", s.server.ID, s.charID, s.token)
if err != nil {
s.logger.Error("Failed to update sign session", zap.Error(err))
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
_, err = s.server.db.Exec("UPDATE characters SET last_login=$1 WHERE id=$2", TimeAdjusted().Unix(), s.charID)
if err != nil {
s.logger.Error("Failed to update last login", zap.Error(err))
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
_, err = s.server.db.Exec("UPDATE users u SET last_character=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)", s.charID)
if err != nil {
s.logger.Error("Failed to update last character", zap.Error(err))
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
return
}
@@ -366,6 +370,7 @@ func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) {
_, err := rand.Read(logKey)
if err != nil {
s.logger.Error("Failed to generate log key", zap.Error(err))
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
return
}