implement Festa Bonus Categories & Guild Character optimisations

This commit is contained in:
wish
2024-02-20 04:18:16 +11:00
parent d22a7c782f
commit 5bcfe25ede
4 changed files with 103 additions and 63 deletions

View File

@@ -95,8 +95,9 @@ func handleMsgMhfEnumerateRanking(s *Session, p mhfpacket.MHFPacket) {
func cleanupFesta(s *Session) {
s.server.db.Exec("DELETE FROM events WHERE event_type='festa'")
s.server.db.Exec("DELETE FROM festa_registrations")
s.server.db.Exec("DELETE FROM festa_submissions")
s.server.db.Exec("DELETE FROM festa_prizes_accepted")
s.server.db.Exec("UPDATE guild_characters SET souls=0, trial_vote=NULL")
s.server.db.Exec("UPDATE guild_characters SET trial_vote=NULL")
}
func generateFestaTimestamps(s *Session, start uint32, debug bool) []uint32 {
@@ -293,22 +294,45 @@ func handleMsgMhfInfoFesta(s *Session, p mhfpacket.MHFPacket) {
}
bf.WriteUint16(500)
categoryWinners := uint16(4) // NYI
bf.WriteUint16(categoryWinners)
for i := uint16(0); i < categoryWinners; i++ {
bf.WriteUint32(0) // Guild ID
bf.WriteUint16(i + 1) // Category ID
bf.WriteInt16(int16(FestivalColourCodes[FestivalColourNone])) // Festa Team
ps.Uint8(bf, "", true) // Guild Name
var temp uint32
bf.WriteUint16(4)
for i := uint16(0); i < 4; i++ {
var guildID uint32
var guildName string
var guildTeam = FestivalColorNone
s.server.db.QueryRow(`
SELECT fs.guild_id, g.name, fr.team, SUM(fs.souls) as _
FROM festa_submissions fs
LEFT JOIN festa_registrations fr ON fs.guild_id = fr.guild_id
LEFT JOIN guilds g ON fs.guild_id = g.id
WHERE fs.trial_type = $1
GROUP BY fs.guild_id, g.name, fr.team
ORDER BY _ DESC LIMIT 1
`, i+1).Scan(&guildID, &guildName, &guildTeam, &temp)
bf.WriteUint32(guildID)
bf.WriteUint16(i + 1)
bf.WriteInt16(FestivalColorCodes[guildTeam])
ps.Uint8(bf, guildName, true)
}
dailyWinners := uint16(7) // NYI
bf.WriteUint16(dailyWinners)
for i := uint16(0); i < dailyWinners; i++ {
bf.WriteUint32(0) // Guild ID
bf.WriteUint16(i + 1) // Category ID
bf.WriteInt16(int16(FestivalColourCodes[FestivalColourNone])) // Festa Team
ps.Uint8(bf, "", true) // Guild Name
bf.WriteUint16(7)
for i := uint16(0); i < 7; i++ {
var guildID uint32
var guildName string
var guildTeam = FestivalColorNone
offset := 86400 * uint32(i)
s.server.db.QueryRow(`
SELECT fs.guild_id, g.name, fr.team, SUM(fs.souls) as _
FROM festa_submissions fs
LEFT JOIN festa_registrations fr ON fs.guild_id = fr.guild_id
LEFT JOIN guilds g ON fs.guild_id = g.id
WHERE EXTRACT(EPOCH FROM fs.timestamp)::int > $1 AND EXTRACT(EPOCH FROM fs.timestamp)::int < $2
GROUP BY fs.guild_id, g.name, fr.team
ORDER BY _ DESC LIMIT 1
`, timestamps[1]+offset, timestamps[1]+offset+86400).Scan(&guildID, &guildName, &guildTeam, &temp)
bf.WriteUint32(guildID)
bf.WriteUint16(i + 1)
bf.WriteInt16(FestivalColorCodes[guildTeam])
ps.Uint8(bf, guildName, true)
}
bf.WriteUint32(0) // Clan goal
@@ -445,7 +469,14 @@ func handleMsgMhfEntryFesta(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfChargeFesta(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfChargeFesta)
s.server.db.Exec("UPDATE guild_characters SET souls=souls+$1 WHERE character_id=$2", pkt.Souls, s.charID)
tx, _ := s.server.db.Begin()
for i := range pkt.Souls {
if pkt.Souls[i] == 0 {
continue
}
_, _ = tx.Exec(`INSERT INTO festa_submissions VALUES ($1, $2, $3, $4, now())`, s.charID, pkt.GuildID, i, pkt.Souls[i])
}
_ = tx.Commit()
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}

View File

@@ -61,41 +61,35 @@ func (gm *GuildMember) Save(s *Session) error {
}
const guildMembersSelectSQL = `
SELECT
g.id as guild_id,
joined_at,
coalesce(souls, 0) as souls,
COALESCE(rp_today, 0) AS rp_today,
COALESCE(rp_yesterday, 0) AS rp_yesterday,
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
SELECT * FROM (
SELECT
g.id AS guild_id,
joined_at,
COALESCE((SELECT SUM(souls) FROM festa_submissions fs WHERE fs.character_id=c.id), 0) AS souls,
COALESCE(rp_today, 0) AS rp_today,
COALESCE(rp_yesterday, 0) AS rp_yesterday,
c.name,
c.id AS character_id,
COALESCE(order_index, 0) AS order_index,
c.last_login,
COALESCE(recruiter, false) AS recruiter,
COALESCE(avoid_leadership, false) AS avoid_leadership,
c.hrp,
c.gr,
c.weapon_id,
c.weapon_type,
EXISTS(SELECT 1 FROM guild_applications ga WHERE ga.character_id=c.id AND application_type='applied') AS is_applicant,
CASE WHEN g.leader_id = c.id THEN true ELSE false END AS is_leader
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
LEFT JOIN characters c ON c.id = gc.character_id
LEFT JOIN guilds g ON g.id = gc.guild_id
) AS subquery
`
func GetGuildMembers(s *Session, guildID uint32, applicants bool) ([]*GuildMember, error) {
rows, err := s.server.db.Queryx(fmt.Sprintf(`
%s
WHERE character.guild_id = $1 AND is_applicant = $2
WHERE guild_id = $1 AND is_applicant = $2
`, guildMembersSelectSQL), guildID, applicants)
if err != nil {
@@ -121,7 +115,7 @@ func GetGuildMembers(s *Session, guildID uint32, applicants bool) ([]*GuildMembe
}
func GetCharacterGuildData(s *Session, charID uint32) (*GuildMember, error) {
rows, err := s.server.db.Queryx(fmt.Sprintf("%s WHERE character.character_id=$1", guildMembersSelectSQL), charID)
rows, err := s.server.db.Queryx(fmt.Sprintf("%s WHERE character_id=$1", guildMembersSelectSQL), charID)
if err != nil {
s.logger.Error(fmt.Sprintf("failed to retrieve membership data for character '%d'", charID))