mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
The protbot sent "DSGN:\x00" as the sign request type, but the server strips the last 3 characters as a version suffix. Send "DSGN:041" (ZZ client mode 41) to match the real client format. The entrance channel entry parser read 14 bytes for remaining fields but the server writes 18 bytes (9 uint16, not 7), causing a panic when parsing the server list. The channel server panicked on disconnect when a session had no decompressed save data (e.g. protbot or early client disconnect). Guard Save() against nil decompSave. Also fix docker-compose volume mount for Postgres 18 which changed its data directory layout.
93 lines
2.6 KiB
Go
93 lines
2.6 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"errors"
|
|
|
|
_config "erupe-ce/config"
|
|
"erupe-ce/network/mhfpacket"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// GetCharacterSaveData loads a character's save data from the database.
|
|
func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) {
|
|
result, err := s.server.db.Query("SELECT id, savedata, is_new_character, name FROM characters WHERE id = $1", charID)
|
|
if err != nil {
|
|
s.logger.Error("Failed to get savedata", zap.Error(err), zap.Uint32("charID", charID))
|
|
return nil, err
|
|
}
|
|
defer func() { _ = result.Close() }()
|
|
if !result.Next() {
|
|
err = errors.New("no savedata found")
|
|
s.logger.Error("No savedata found", zap.Uint32("charID", charID))
|
|
return nil, err
|
|
}
|
|
|
|
saveData := &CharacterSaveData{
|
|
Pointers: getPointers(),
|
|
}
|
|
err = result.Scan(&saveData.CharID, &saveData.compSave, &saveData.IsNewCharacter, &saveData.Name)
|
|
if err != nil {
|
|
s.logger.Error("Failed to scan savedata", zap.Error(err), zap.Uint32("charID", charID))
|
|
return nil, err
|
|
}
|
|
|
|
if saveData.compSave == nil {
|
|
return saveData, nil
|
|
}
|
|
|
|
err = saveData.Decompress()
|
|
if err != nil {
|
|
s.logger.Error("Failed to decompress savedata", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
saveData.updateStructWithSaveData()
|
|
|
|
return saveData, nil
|
|
}
|
|
|
|
func (save *CharacterSaveData) Save(s *Session) {
|
|
if save.decompSave == nil {
|
|
s.logger.Warn("No decompressed save data, skipping save",
|
|
zap.Uint32("charID", save.CharID),
|
|
)
|
|
return
|
|
}
|
|
|
|
if !s.kqfOverride {
|
|
s.kqf = save.KQF
|
|
} else {
|
|
save.KQF = s.kqf
|
|
}
|
|
|
|
save.updateSaveDataWithStruct()
|
|
|
|
if _config.ErupeConfig.RealClientMode >= _config.G1 {
|
|
err := save.Compress()
|
|
if err != nil {
|
|
s.logger.Error("Failed to compress savedata", zap.Error(err))
|
|
return
|
|
}
|
|
} else {
|
|
// Saves were not compressed
|
|
save.compSave = save.decompSave
|
|
}
|
|
|
|
_, err := s.server.db.Exec(`UPDATE characters SET savedata=$1, is_new_character=false, hr=$2, gr=$3, is_female=$4, weapon_type=$5, weapon_id=$6 WHERE id=$7
|
|
`, save.compSave, save.HR, save.GR, save.Gender, save.WeaponType, save.WeaponID, save.CharID)
|
|
if err != nil {
|
|
s.logger.Error("Failed to update savedata", zap.Error(err), zap.Uint32("charID", save.CharID))
|
|
}
|
|
|
|
if _, err := s.server.db.Exec(`UPDATE user_binary SET house_tier=$1, house_data=$2, bookshelf=$3, gallery=$4, tore=$5, garden=$6 WHERE id=$7
|
|
`, save.HouseTier, save.HouseData, save.BookshelfData, save.GalleryData, save.ToreData, save.GardenData, s.charID); err != nil {
|
|
s.logger.Error("Failed to update user binary house data", zap.Error(err))
|
|
}
|
|
}
|
|
|
|
func handleMsgMhfSexChanger(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfSexChanger)
|
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
}
|