mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-04 09:15:08 +01:00
Road Shop Rotation
Added Road Shop inventory's weekly dynamic rotation. Thank you everyone who helped with this!
This commit is contained in:
39
Erupe/road-shop-rotation.sql
Normal file
39
Erupe/road-shop-rotation.sql
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
BEGIN;
|
||||||
|
CREATE TABLE IF NOT EXISTS public.normal_shop_items
|
||||||
|
(
|
||||||
|
shoptype integer,
|
||||||
|
shopid integer,
|
||||||
|
itemhash integer not null,
|
||||||
|
itemid integer,
|
||||||
|
points integer,
|
||||||
|
tradequantity integer,
|
||||||
|
rankreqlow integer,
|
||||||
|
rankreqhigh integer,
|
||||||
|
rankreqg integer,
|
||||||
|
storelevelreq integer,
|
||||||
|
maximumquantity integer,
|
||||||
|
boughtquantity integer,
|
||||||
|
roadfloorsrequired integer,
|
||||||
|
weeklyfataliskills integer,
|
||||||
|
enable_weeks character varying(8)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||||
|
(
|
||||||
|
ADD COLUMN enable_weeks character varying(8)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.shop_item_state
|
||||||
|
(
|
||||||
|
char_id bigint REFERENCES characters (id),
|
||||||
|
itemhash int UNIQUE NOT NULL,
|
||||||
|
usedquantity int,
|
||||||
|
week int
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.shop_item_state
|
||||||
|
(
|
||||||
|
ADD COLUMN week int
|
||||||
|
);
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -2,16 +2,28 @@ package channelserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
//"github.com/Solenataris/Erupe/common/stringsupport"
|
//"github.com/Solenataris/Erupe/common/stringsupport"
|
||||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
|
||||||
"github.com/Andoryuuta/byteframe"
|
"github.com/Andoryuuta/byteframe"
|
||||||
|
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
"github.com/sachaos/lottery"
|
"github.com/sachaos/lottery"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func contains(s []string, str string) bool {
|
||||||
|
for _, v := range s {
|
||||||
|
if v == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateShop)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateShop)
|
||||||
// SHOP TYPES:
|
// SHOP TYPES:
|
||||||
@@ -149,20 +161,28 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
} else {
|
} else {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shopEntries, err := s.server.db.Query("SELECT itemhash,itemID,Points,TradeQuantity,rankReqLow,rankReqHigh,rankReqG,storeLevelReq,maximumQuantity,boughtQuantity,roadFloorsRequired,weeklyFatalisKills FROM normal_shop_items WHERE shoptype=$1 AND shopid=$2", pkt.ShopType, pkt.ShopID)
|
_, week := time.Now().ISOWeek()
|
||||||
|
season := fmt.Sprintf("%d", week%4)
|
||||||
|
shopEntries, err := s.server.db.Query("SELECT itemhash,itemID,Points,TradeQuantity,rankReqLow,rankReqHigh,rankReqG,storeLevelReq,maximumQuantity,boughtQuantity,roadFloorsRequired,weeklyFatalisKills, COALESCE(enable_weeks, '') FROM normal_shop_items WHERE shoptype=$1 AND shopid=$2", pkt.ShopType, pkt.ShopID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
var ItemHash, entryCount int
|
var ItemHash, entryCount int
|
||||||
var itemID, Points, TradeQuantity, rankReqLow, rankReqHigh, rankReqG, storeLevelReq, maximumQuantity, boughtQuantity, roadFloorsRequired, weeklyFatalisKills, charQuantity uint16
|
var itemID, Points, TradeQuantity, rankReqLow, rankReqHigh, rankReqG, storeLevelReq, maximumQuantity, boughtQuantity, roadFloorsRequired, weeklyFatalisKills, charQuantity uint16
|
||||||
|
var itemWeeks string
|
||||||
resp := byteframe.NewByteFrame()
|
resp := byteframe.NewByteFrame()
|
||||||
resp.WriteUint32(0) // total defs
|
resp.WriteUint32(0) // total defs
|
||||||
for shopEntries.Next() {
|
for shopEntries.Next() {
|
||||||
err = shopEntries.Scan(&ItemHash, &itemID, &Points, &TradeQuantity, &rankReqLow, &rankReqHigh, &rankReqG, &storeLevelReq, &maximumQuantity, &boughtQuantity, &roadFloorsRequired, &weeklyFatalisKills)
|
err = shopEntries.Scan(&ItemHash, &itemID, &Points, &TradeQuantity, &rankReqLow, &rankReqHigh, &rankReqG, &storeLevelReq, &maximumQuantity, &boughtQuantity, &roadFloorsRequired, &weeklyFatalisKills, &itemWeeks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(itemWeeks) > 0 && !contains(strings.Split(itemWeeks, ","), season) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
resp.WriteUint32(uint32(ItemHash))
|
resp.WriteUint32(uint32(ItemHash))
|
||||||
resp.WriteUint16(0) // unk, always 0 in existing packets
|
resp.WriteUint16(0) // unk, always 0 in existing packets
|
||||||
resp.WriteUint16(itemID)
|
resp.WriteUint16(itemID)
|
||||||
@@ -175,9 +195,13 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
resp.WriteUint16(storeLevelReq)
|
resp.WriteUint16(storeLevelReq)
|
||||||
resp.WriteUint16(maximumQuantity)
|
resp.WriteUint16(maximumQuantity)
|
||||||
if maximumQuantity > 0 {
|
if maximumQuantity > 0 {
|
||||||
err = s.server.db.QueryRow("SELECT COALESCE(usedquantity,0) FROM shop_item_state WHERE itemhash=$1 AND char_id=$2", ItemHash, s.charID).Scan(&charQuantity)
|
var itemWeek int
|
||||||
|
err = s.server.db.QueryRow("SELECT COALESCE(usedquantity,0), COALESCE(week,-1) FROM shop_item_state WHERE itemhash=$1 AND char_id=$2", ItemHash, s.charID).Scan(&charQuantity, &itemWeek)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteUint16(0)
|
resp.WriteUint16(0)
|
||||||
|
} else if pkt.ShopID == 7 && itemWeek >= 0 && itemWeek != week {
|
||||||
|
clearShopItemState(s, s.charID, uint32(ItemHash))
|
||||||
|
resp.WriteUint16(0)
|
||||||
} else {
|
} else {
|
||||||
resp.WriteUint16(charQuantity)
|
resp.WriteUint16(charQuantity)
|
||||||
}
|
}
|
||||||
@@ -200,6 +224,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
_, week := time.Now().ISOWeek()
|
||||||
// writing out to an editable shop enumeration
|
// writing out to an editable shop enumeration
|
||||||
pkt := p.(*mhfpacket.MsgMhfAcquireExchangeShop)
|
pkt := p.(*mhfpacket.MsgMhfAcquireExchangeShop)
|
||||||
if pkt.DataSize == 10 {
|
if pkt.DataSize == 10 {
|
||||||
@@ -207,10 +232,10 @@ func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
_ = bf.ReadUint16() // unk, always 1 in examples
|
_ = bf.ReadUint16() // unk, always 1 in examples
|
||||||
itemHash := bf.ReadUint32()
|
itemHash := bf.ReadUint32()
|
||||||
buyCount := bf.ReadUint32()
|
buyCount := bf.ReadUint32()
|
||||||
_, err := s.server.db.Exec(`INSERT INTO shop_item_state (char_id, itemhash, usedquantity)
|
_, err := s.server.db.Exec(`INSERT INTO shop_item_state (char_id, itemhash, usedquantity, week)
|
||||||
VALUES ($1,$2,$3) ON CONFLICT (char_id, itemhash)
|
VALUES ($1,$2,$3,$4) ON CONFLICT (char_id, itemhash)
|
||||||
DO UPDATE SET usedquantity = shop_item_state.usedquantity + $3
|
DO UPDATE SET usedquantity = shop_item_state.usedquantity + $3
|
||||||
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.itemhash=$2`, s.charID, itemHash, buyCount)
|
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.itemhash=$2`, s.charID, itemHash, buyCount, week)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update shop_item_state in db", zap.Error(err))
|
s.logger.Fatal("Failed to update shop_item_state in db", zap.Error(err))
|
||||||
}
|
}
|
||||||
@@ -218,6 +243,13 @@ func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearShopItemState(s *Session, charId uint32, itemHash uint32) {
|
||||||
|
_, err := s.server.db.Exec(`DELETE FROM shop_item_state WHERE char_id=$1 AND itemhash=$2`, charId, itemHash)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Fatal("Failed to delete shop_item_state in db", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetGachaPlayHistory(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetGachaPlayHistory(s *Session, p mhfpacket.MHFPacket) {
|
||||||
// returns number of times the gacha was played, will need persistent db stuff
|
// returns number of times the gacha was played, will need persistent db stuff
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetGachaPlayHistory)
|
pkt := p.(*mhfpacket.MsgMhfGetGachaPlayHistory)
|
||||||
@@ -703,4 +735,4 @@ func handleMsgMhfResetBoxGachaInfo(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user