From be6f55b5a82a24d6e6a2d158bf4ac45aa1b8839d Mon Sep 17 00:00:00 2001 From: wish Date: Sun, 5 Nov 2023 00:31:16 +1100 Subject: [PATCH 1/5] initial distributions rework --- .../mhfpacket/msg_mhf_enumerate_dist_item.go | 4 +- patch-schema/10-rework-distributions.sql | 15 ++ server/channelserver/handlers_distitem.go | 130 ++++++++---------- 3 files changed, 78 insertions(+), 71 deletions(-) create mode 100644 patch-schema/10-rework-distributions.sql diff --git a/network/mhfpacket/msg_mhf_enumerate_dist_item.go b/network/mhfpacket/msg_mhf_enumerate_dist_item.go index 6d0082ec8..4e89c6dfc 100644 --- a/network/mhfpacket/msg_mhf_enumerate_dist_item.go +++ b/network/mhfpacket/msg_mhf_enumerate_dist_item.go @@ -10,7 +10,7 @@ import ( // MsgMhfEnumerateDistItem represents the MSG_MHF_ENUMERATE_DIST_ITEM type MsgMhfEnumerateDistItem struct { AckHandle uint32 - Unk0 uint8 + DistType uint8 Unk1 uint8 Unk2 uint16 Unk3 []byte @@ -24,7 +24,7 @@ func (m *MsgMhfEnumerateDistItem) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint8() + m.DistType = bf.ReadUint8() m.Unk1 = bf.ReadUint8() m.Unk2 = bf.ReadUint16() m.Unk3 = bf.ReadBytes(uint(bf.ReadUint8())) diff --git a/patch-schema/10-rework-distributions.sql b/patch-schema/10-rework-distributions.sql new file mode 100644 index 000000000..c56a9ff67 --- /dev/null +++ b/patch-schema/10-rework-distributions.sql @@ -0,0 +1,15 @@ +BEGIN; + +-- This will delete all of your old distribution data! +--ALTER TABLE IF EXISTS public.distribution DROP COLUMN IF EXISTS data; + +CREATE TABLE public.distribution_items +( + id serial PRIMARY KEY, + distribution_id integer, + item_type integer, + item_id integer, + quantity integer +); + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 2bde7c60a..97d9e882e 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -4,24 +4,25 @@ import ( "erupe-ce/common/byteframe" ps "erupe-ce/common/pascalstring" "erupe-ce/network/mhfpacket" + "time" "go.uber.org/zap" ) type ItemDist struct { - ID uint32 `db:"id"` - Deadline uint32 `db:"deadline"` - TimesAcceptable uint16 `db:"times_acceptable"` - TimesAccepted uint16 `db:"times_accepted"` - MinHR uint16 `db:"min_hr"` - MaxHR uint16 `db:"max_hr"` - MinSR uint16 `db:"min_sr"` - MaxSR uint16 `db:"max_sr"` - MinGR uint16 `db:"min_gr"` - MaxGR uint16 `db:"max_gr"` - EventName string `db:"event_name"` - Description string `db:"description"` - Data []byte `db:"data"` + ID uint32 `db:"id"` + Deadline time.Time `db:"deadline"` + TimesAcceptable uint16 `db:"times_acceptable"` + TimesAccepted uint16 `db:"times_accepted"` + MinHR uint16 `db:"min_hr"` + MaxHR uint16 `db:"max_hr"` + MinSR uint16 `db:"min_sr"` + MaxSR uint16 `db:"max_sr"` + MinGR uint16 `db:"min_gr"` + MaxGR uint16 `db:"max_gr"` + EventName string `db:"event_name"` + Description string `db:"description"` + Data []byte `db:"data"` } func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { @@ -37,13 +38,10 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { WHERE d.id = da.distribution_id AND da.character_id = $1 ) AS times_accepted, - CASE - WHEN (EXTRACT(epoch FROM deadline)::int) IS NULL THEN 0 - ELSE (EXTRACT(epoch FROM deadline)::int) - END deadline + COALESCE(deadline, TO_TIMESTAMP(0)) AS deadline FROM distribution d WHERE character_id = $1 AND type = $2 OR character_id IS NULL AND type = $2 ORDER BY id DESC; - `, s.charID, pkt.Unk0) + `, s.charID, pkt.DistType) if err != nil { s.logger.Error("Error getting distribution data from db", zap.Error(err)) doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) @@ -56,7 +54,7 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { s.logger.Error("Error parsing item distribution data", zap.Error(err)) } bf.WriteUint32(distData.ID) - bf.WriteUint32(distData.Deadline) + bf.WriteUint32(uint32(distData.Deadline.Unix())) bf.WriteUint32(0) // Unk bf.WriteUint16(distData.TimesAcceptable) bf.WriteUint16(distData.TimesAccepted) @@ -93,67 +91,61 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { resp := byteframe.NewByteFrame() resp.WriteUint16(uint16(distCount)) resp.WriteBytes(bf.Data()) - resp.WriteUint8(0) doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } } +type DistributionItem struct { + ItemType uint8 `db:"item_type"` + ID uint32 `db:"id"` + ItemID uint32 `db:"item_id"` + Quantity uint32 `db:"quantity"` +} + func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfApplyDistItem) - if pkt.DistributionID == 0 { - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 6)) - } else { - row := s.server.db.QueryRowx("SELECT data FROM distribution WHERE id = $1", pkt.DistributionID) - dist := &ItemDist{} - err := row.StructScan(dist) - if err != nil { - s.logger.Error("Error parsing item distribution data", zap.Error(err)) - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 6)) - return + bf := byteframe.NewByteFrame() + bf.WriteUint32(pkt.DistributionID) + var distItems []DistributionItem + rows, err := s.server.db.Queryx(`SELECT id, item_id, item_type, quantity FROM distribution_items WHERE distribution_id=$1`, pkt.DistributionID) + if err == nil { + var distItem DistributionItem + for rows.Next() { + err = rows.StructScan(&distItem) + if err != nil { + continue + } + distItems = append(distItems, distItem) } - - if len(dist.Data) >= 2 { - distData := byteframe.NewByteFrameFromBytes(dist.Data) - distItems := int(distData.ReadUint16()) - for i := 0; i < distItems; i++ { - if len(dist.Data) >= 2+(i*13) { - itemType := distData.ReadUint8() - _ = distData.ReadBytes(6) - quantity := int(distData.ReadUint16()) - _ = distData.ReadBytes(4) - switch itemType { - case 17: - _ = addPointNetcafe(s, quantity) - case 19: - s.server.db.Exec("UPDATE users u SET gacha_premium=gacha_premium+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) - case 20: - s.server.db.Exec("UPDATE users u SET gacha_trial=gacha_trial+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) - case 21: - s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", quantity, s.charID) - case 23: - saveData, err := GetCharacterSaveData(s, s.charID) - if err == nil { - saveData.RP += uint16(quantity) - saveData.Save(s) - } - } - } + } + bf.WriteUint16(uint16(len(distItems))) + for _, item := range distItems { + bf.WriteUint8(item.ItemType) + bf.WriteUint32(item.ItemID) + bf.WriteUint32(item.Quantity) + bf.WriteUint32(item.ID) + switch item.ItemType { + case 17: + _ = addPointNetcafe(s, int(item.Quantity)) + case 19: + s.server.db.Exec("UPDATE users u SET gacha_premium=gacha_premium+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 20: + s.server.db.Exec("UPDATE users u SET gacha_trial=gacha_trial+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 21: + s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 23: + saveData, err := GetCharacterSaveData(s, s.charID) + if err == nil { + saveData.RP += uint16(item.Quantity) + saveData.Save(s) } } + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) - bf := byteframe.NewByteFrame() - bf.WriteUint32(pkt.DistributionID) - bf.WriteBytes(dist.Data) - doAckBufSucceed(s, pkt.AckHandle, bf.Data()) - - _, err = s.server.db.Exec(` - INSERT INTO public.distributions_accepted - VALUES ($1, $2) - `, pkt.DistributionID, s.charID) - if err != nil { - s.logger.Error("Error updating accepted dist count", zap.Error(err)) - } + if pkt.DistributionID > 0 { + _, err = s.server.db.Exec(`INSERT INTO public.distributions_accepted VALUES ($1, $2)`, pkt.DistributionID, s.charID) } } From 29904d5b9297898b4dfd78d8122908749f41c1f0 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 7 Nov 2023 20:23:02 +1100 Subject: [PATCH 2/5] fix signing of min/max Rank Distributions --- patch-schema/10-rework-distributions.sql | 23 ++++++++++++++++++- server/channelserver/handlers_distitem.go | 28 ++++++++++++----------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/patch-schema/10-rework-distributions.sql b/patch-schema/10-rework-distributions.sql index c56a9ff67..4dc794ad3 100644 --- a/patch-schema/10-rework-distributions.sql +++ b/patch-schema/10-rework-distributions.sql @@ -6,10 +6,31 @@ BEGIN; CREATE TABLE public.distribution_items ( id serial PRIMARY KEY, - distribution_id integer, + distribution_id integer NOT NULL, item_type integer, item_id integer, quantity integer ); +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_hr DROP DEFAULT; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_hr DROP DEFAULT; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_sr DROP DEFAULT; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_sr DROP DEFAULT; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_gr DROP DEFAULT; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_gr DROP DEFAULT; + +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_hr DROP NOT NULL; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_hr DROP NOT NULL; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_sr DROP NOT NULL; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_sr DROP NOT NULL; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_gr DROP NOT NULL; +ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_gr DROP NOT NULL; + +UPDATE distribution SET min_hr=NULL WHERE min_hr=65535; +UPDATE distribution SET max_hr=NULL WHERE max_hr=65535; +UPDATE distribution SET min_sr=NULL WHERE min_sr=65535; +UPDATE distribution SET max_sr=NULL WHERE max_sr=65535; +UPDATE distribution SET min_gr=NULL WHERE min_gr=65535; +UPDATE distribution SET max_gr=NULL WHERE max_gr=65535; + END; \ No newline at end of file diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 97d9e882e..7ccf1c74d 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -14,12 +14,12 @@ type ItemDist struct { Deadline time.Time `db:"deadline"` TimesAcceptable uint16 `db:"times_acceptable"` TimesAccepted uint16 `db:"times_accepted"` - MinHR uint16 `db:"min_hr"` - MaxHR uint16 `db:"max_hr"` - MinSR uint16 `db:"min_sr"` - MaxSR uint16 `db:"max_sr"` - MinGR uint16 `db:"min_gr"` - MaxGR uint16 `db:"max_gr"` + MinHR int16 `db:"min_hr"` + MaxHR int16 `db:"max_hr"` + MinSR int16 `db:"min_sr"` + MaxSR int16 `db:"max_sr"` + MinGR int16 `db:"min_gr"` + MaxGR int16 `db:"max_gr"` EventName string `db:"event_name"` Description string `db:"description"` Data []byte `db:"data"` @@ -31,7 +31,9 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { distCount := 0 dists, err := s.server.db.Queryx(` SELECT d.id, event_name, description, times_acceptable, - min_hr, max_hr, min_sr, max_sr, min_gr, max_gr, + COALESCE(min_hr, -1) AS min_hr, COALESCE(max_hr, -1) AS max_hr, + COALESCE(min_sr, -1) AS min_sr, COALESCE(max_sr, -1) AS max_sr, + COALESCE(min_gr, -1) AS min_gr, COALESCE(max_gr, -1) AS max_gr, ( SELECT count(*) FROM distributions_accepted da @@ -59,12 +61,12 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(distData.TimesAcceptable) bf.WriteUint16(distData.TimesAccepted) bf.WriteUint16(0) // Unk - bf.WriteUint16(distData.MinHR) - bf.WriteUint16(distData.MaxHR) - bf.WriteUint16(distData.MinSR) - bf.WriteUint16(distData.MaxSR) - bf.WriteUint16(distData.MinGR) - bf.WriteUint16(distData.MaxGR) + bf.WriteInt16(distData.MinHR) + bf.WriteInt16(distData.MaxHR) + bf.WriteInt16(distData.MinSR) + bf.WriteInt16(distData.MaxSR) + bf.WriteInt16(distData.MinGR) + bf.WriteInt16(distData.MaxGR) bf.WriteUint8(0) bf.WriteUint16(0) bf.WriteUint8(0) From 14e61fd661127d009293e12b0c967363d4cbbcf9 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 7 Nov 2023 21:07:49 +1100 Subject: [PATCH 3/5] fix Distribution typing, accepting & add demo --- bundled-schema/DistributionDemo.sql | 11 +++++ patch-schema/10-rework-distributions.sql | 2 +- server/channelserver/handlers_distitem.go | 60 +++++++++++++---------- 3 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 bundled-schema/DistributionDemo.sql diff --git a/bundled-schema/DistributionDemo.sql b/bundled-schema/DistributionDemo.sql new file mode 100644 index 000000000..f8b1dc018 --- /dev/null +++ b/bundled-schema/DistributionDemo.sql @@ -0,0 +1,11 @@ +BEGIN; + +-- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 30 (Item Box extra page) +INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Item Storage', '~C05Adds one new page to your Item Box.', 20); +INSERT INTO distribution_items (distribution_id, item_type, item_id, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 30, 0, 1); + +-- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 31 (Equipment Box extra page) +INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Equipment Storage', '~C05Adds one new page to your Equipment Box.', 20); +INSERT INTO distribution_items (distribution_id, item_type, item_id, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 31, 0, 1); + +END; \ No newline at end of file diff --git a/patch-schema/10-rework-distributions.sql b/patch-schema/10-rework-distributions.sql index 4dc794ad3..7945de343 100644 --- a/patch-schema/10-rework-distributions.sql +++ b/patch-schema/10-rework-distributions.sql @@ -7,7 +7,7 @@ CREATE TABLE public.distribution_items ( id serial PRIMARY KEY, distribution_id integer NOT NULL, - item_type integer, + item_type integer NOT NULL, item_id integer, quantity integer ); diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 7ccf1c74d..97dbfcf15 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -104,13 +104,9 @@ type DistributionItem struct { Quantity uint32 `db:"quantity"` } -func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfApplyDistItem) - - bf := byteframe.NewByteFrame() - bf.WriteUint32(pkt.DistributionID) +func getDistributionItems(s *Session, i uint32) []DistributionItem { var distItems []DistributionItem - rows, err := s.server.db.Queryx(`SELECT id, item_id, item_type, quantity FROM distribution_items WHERE distribution_id=$1`, pkt.DistributionID) + rows, err := s.server.db.Queryx(`SELECT id, item_type, COALESCE(item_id, 0) AS item_id, COALESCE(quantity, 0) AS quantity FROM distribution_items WHERE distribution_id=$1`, i) if err == nil { var distItem DistributionItem for rows.Next() { @@ -121,38 +117,50 @@ func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { distItems = append(distItems, distItem) } } + return distItems +} + +func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfApplyDistItem) + bf := byteframe.NewByteFrame() + bf.WriteUint32(pkt.DistributionID) + distItems := getDistributionItems(s, pkt.DistributionID) bf.WriteUint16(uint16(len(distItems))) for _, item := range distItems { bf.WriteUint8(item.ItemType) bf.WriteUint32(item.ItemID) bf.WriteUint32(item.Quantity) bf.WriteUint32(item.ID) - switch item.ItemType { - case 17: - _ = addPointNetcafe(s, int(item.Quantity)) - case 19: - s.server.db.Exec("UPDATE users u SET gacha_premium=gacha_premium+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) - case 20: - s.server.db.Exec("UPDATE users u SET gacha_trial=gacha_trial+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) - case 21: - s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) - case 23: - saveData, err := GetCharacterSaveData(s, s.charID) - if err == nil { - saveData.RP += uint16(item.Quantity) - saveData.Save(s) - } - } } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) - - if pkt.DistributionID > 0 { - _, err = s.server.db.Exec(`INSERT INTO public.distributions_accepted VALUES ($1, $2)`, pkt.DistributionID, s.charID) - } } func handleMsgMhfAcquireDistItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfAcquireDistItem) + if pkt.DistributionID > 0 { + _, err := s.server.db.Exec(`INSERT INTO public.distributions_accepted VALUES ($1, $2)`, pkt.DistributionID, s.charID) + if err == nil { + distItems := getDistributionItems(s, pkt.DistributionID) + for _, item := range distItems { + switch item.ItemType { + case 17: + _ = addPointNetcafe(s, int(item.Quantity)) + case 19: + s.server.db.Exec("UPDATE users u SET gacha_premium=gacha_premium+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 20: + s.server.db.Exec("UPDATE users u SET gacha_trial=gacha_trial+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 21: + s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", item.Quantity, s.charID) + case 23: + saveData, err := GetCharacterSaveData(s, s.charID) + if err == nil { + saveData.RP += uint16(item.Quantity) + saveData.Save(s) + } + } + } + } + } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From 317daef04bbe6c30210dd1cb52082c0aeca09fe3 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 7 Nov 2023 21:26:45 +1100 Subject: [PATCH 4/5] rewrite EnumerateDistItem handler --- .../mhfpacket/msg_mhf_enumerate_dist_item.go | 2 +- server/channelserver/handlers_distitem.go | 106 +++++++++--------- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/network/mhfpacket/msg_mhf_enumerate_dist_item.go b/network/mhfpacket/msg_mhf_enumerate_dist_item.go index 4e89c6dfc..bf5796702 100644 --- a/network/mhfpacket/msg_mhf_enumerate_dist_item.go +++ b/network/mhfpacket/msg_mhf_enumerate_dist_item.go @@ -26,7 +26,7 @@ func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx. m.AckHandle = bf.ReadUint32() m.DistType = bf.ReadUint8() m.Unk1 = bf.ReadUint8() - m.Unk2 = bf.ReadUint16() + m.Unk2 = bf.ReadUint16() // Maximum? Hardcoded to 256 m.Unk3 = bf.ReadBytes(uint(bf.ReadUint8())) return nil } diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 97dbfcf15..b18961202 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" ) -type ItemDist struct { +type Distribution struct { ID uint32 `db:"id"` Deadline time.Time `db:"deadline"` TimesAcceptable uint16 `db:"times_acceptable"` @@ -27,74 +27,72 @@ type ItemDist struct { func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfEnumerateDistItem) + + var itemDists []Distribution bf := byteframe.NewByteFrame() - distCount := 0 - dists, err := s.server.db.Queryx(` + rows, err := s.server.db.Queryx(` SELECT d.id, event_name, description, times_acceptable, COALESCE(min_hr, -1) AS min_hr, COALESCE(max_hr, -1) AS max_hr, COALESCE(min_sr, -1) AS min_sr, COALESCE(max_sr, -1) AS max_sr, COALESCE(min_gr, -1) AS min_gr, COALESCE(max_gr, -1) AS max_gr, ( - SELECT count(*) - FROM distributions_accepted da - WHERE d.id = da.distribution_id - AND da.character_id = $1 + SELECT count(*) FROM distributions_accepted da + WHERE d.id = da.distribution_id AND da.character_id = $1 ) AS times_accepted, COALESCE(deadline, TO_TIMESTAMP(0)) AS deadline FROM distribution d - WHERE character_id = $1 AND type = $2 OR character_id IS NULL AND type = $2 ORDER BY id DESC; + WHERE character_id = $1 AND type = $2 OR character_id IS NULL AND type = $2 ORDER BY id DESC `, s.charID, pkt.DistType) - if err != nil { - s.logger.Error("Error getting distribution data from db", zap.Error(err)) - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) - } else { - for dists.Next() { - distCount++ - distData := &ItemDist{} - err = dists.StructScan(&distData) + + if err == nil { + var itemDist Distribution + for rows.Next() { + err = rows.StructScan(&itemDist) if err != nil { - s.logger.Error("Error parsing item distribution data", zap.Error(err)) + continue } - bf.WriteUint32(distData.ID) - bf.WriteUint32(uint32(distData.Deadline.Unix())) - bf.WriteUint32(0) // Unk - bf.WriteUint16(distData.TimesAcceptable) - bf.WriteUint16(distData.TimesAccepted) - bf.WriteUint16(0) // Unk - bf.WriteInt16(distData.MinHR) - bf.WriteInt16(distData.MaxHR) - bf.WriteInt16(distData.MinSR) - bf.WriteInt16(distData.MaxSR) - bf.WriteInt16(distData.MinGR) - bf.WriteInt16(distData.MaxGR) - bf.WriteUint8(0) - bf.WriteUint16(0) - bf.WriteUint8(0) - bf.WriteUint16(0) - bf.WriteUint16(0) - bf.WriteUint8(0) - ps.Uint8(bf, distData.EventName, true) - for i := 0; i < 6; i++ { - for j := 0; j < 13; j++ { - bf.WriteUint8(0) - bf.WriteUint32(0) - } - } - i := uint8(0) - bf.WriteUint8(i) - if i <= 10 { - for j := uint8(0); j < i; j++ { - bf.WriteUint32(0) - bf.WriteUint32(0) - bf.WriteUint32(0) - } + itemDists = append(itemDists, itemDist) + } + } + + bf.WriteUint16(uint16(len(itemDists))) + for _, dist := range itemDists { + bf.WriteUint32(dist.ID) + bf.WriteUint32(uint32(dist.Deadline.Unix())) + bf.WriteUint32(0) // Unk + bf.WriteUint16(dist.TimesAcceptable) + bf.WriteUint16(dist.TimesAccepted) + bf.WriteUint16(0) // Unk + bf.WriteInt16(dist.MinHR) + bf.WriteInt16(dist.MaxHR) + bf.WriteInt16(dist.MinSR) + bf.WriteInt16(dist.MaxSR) + bf.WriteInt16(dist.MinGR) + bf.WriteInt16(dist.MaxGR) + bf.WriteUint8(0) + bf.WriteUint16(0) + bf.WriteUint8(0) + bf.WriteUint16(0) + bf.WriteUint16(0) + bf.WriteUint8(0) + ps.Uint8(bf, dist.EventName, true) + for i := 0; i < 6; i++ { + for j := 0; j < 13; j++ { + bf.WriteUint8(0) + bf.WriteUint32(0) + } + } + i := uint8(0) + bf.WriteUint8(i) + if i <= 10 { + for j := uint8(0); j < i; j++ { + bf.WriteUint32(0) + bf.WriteUint32(0) + bf.WriteUint32(0) } } - resp := byteframe.NewByteFrame() - resp.WriteUint16(uint16(distCount)) - resp.WriteBytes(bf.Data()) - doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } type DistributionItem struct { From 7eaf37c1ffa193a27b36c2ae3e4445b579d38fee Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 7 Nov 2023 22:00:07 +1100 Subject: [PATCH 5/5] simplify DistributionDemo script --- bundled-schema/DistributionDemo.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundled-schema/DistributionDemo.sql b/bundled-schema/DistributionDemo.sql index f8b1dc018..d5da8688e 100644 --- a/bundled-schema/DistributionDemo.sql +++ b/bundled-schema/DistributionDemo.sql @@ -2,10 +2,10 @@ BEGIN; -- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 30 (Item Box extra page) INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Item Storage', '~C05Adds one new page to your Item Box.', 20); -INSERT INTO distribution_items (distribution_id, item_type, item_id, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 30, 0, 1); +INSERT INTO distribution_items (distribution_id, item_type, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 30, 1); -- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 31 (Equipment Box extra page) INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Equipment Storage', '~C05Adds one new page to your Equipment Box.', 20); -INSERT INTO distribution_items (distribution_id, item_type, item_id, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 31, 0, 1); +INSERT INTO distribution_items (distribution_id, item_type, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 31, 1); END; \ No newline at end of file