Config / DB now its own package

This commit is contained in:
stratic-dev
2024-10-12 22:37:42 +01:00
parent 44692e986e
commit 5f975c97b5
76 changed files with 3249 additions and 2359 deletions

View File

@@ -1,11 +1,13 @@
package channelserver
import (
_config "erupe-ce/config"
"erupe-ce/config"
"erupe-ce/network/mhfpacket"
"erupe-ce/utils/byteframe"
"erupe-ce/utils/db"
"erupe-ce/utils/gametime"
ps "erupe-ce/utils/pascalstring"
"fmt"
"math/rand"
)
@@ -62,7 +64,7 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) {
bf.WriteUint16(uint16(len(items)))
bf.WriteUint16(uint16(len(items)))
for _, item := range items {
if _config.ErupeConfig.ClientID >= _config.Z2 {
if config.GetConfig().ClientID >= config.Z2 {
bf.WriteUint32(item.ID)
}
bf.WriteUint32(item.ItemID)
@@ -70,19 +72,19 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) {
bf.WriteUint16(item.Quantity)
bf.WriteUint16(item.MinHR)
bf.WriteUint16(item.MinSR)
if _config.ErupeConfig.ClientID >= _config.Z2 {
if config.GetConfig().ClientID >= config.Z2 {
bf.WriteUint16(item.MinGR)
}
bf.WriteUint8(0) // Unk
bf.WriteUint8(item.StoreLevel)
if _config.ErupeConfig.ClientID >= _config.Z2 {
if config.GetConfig().ClientID >= config.Z2 {
bf.WriteUint16(item.MaxQuantity)
bf.WriteUint16(item.UsedQuantity)
}
if _config.ErupeConfig.ClientID == _config.Z1 {
if config.GetConfig().ClientID == config.Z1 {
bf.WriteUint8(uint8(item.RoadFloors))
bf.WriteUint8(uint8(item.RoadFatalis))
} else if _config.ErupeConfig.ClientID >= _config.Z2 {
} else if config.GetConfig().ClientID >= config.Z2 {
bf.WriteUint16(item.RoadFloors)
bf.WriteUint16(item.RoadFatalis)
}
@@ -92,10 +94,14 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) {
func getShopItems(s *Session, shopType uint8, shopID uint32) []ShopItem {
var items []ShopItem
var temp ShopItem
rows, err := s.server.db.Queryx(`SELECT id, item_id, cost, quantity, min_hr, min_sr, min_gr, store_level, max_quantity,
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
rows, err := database.Queryx(`SELECT id, item_id, cost, quantity, min_hr, min_sr, min_gr, store_level, max_quantity,
COALESCE((SELECT bought FROM shop_items_bought WHERE shop_item_id=si.id AND character_id=$3), 0) as used_quantity,
road_floors, road_fatalis FROM shop_items si WHERE shop_type=$1 AND shop_id=$2
`, shopType, shopID, s.charID)
`, shopType, shopID, s.CharID)
if err == nil {
for rows.Next() {
err = rows.StructScan(&temp)
@@ -110,6 +116,10 @@ func getShopItems(s *Session, shopType uint8, shopID uint32) []ShopItem {
func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfEnumerateShop)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
// Generic Shop IDs
// 0: basic item
// 1: gatherables
@@ -123,14 +133,14 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
switch pkt.ShopType {
case 1: // Running gachas
// Fundamentally, gacha works completely differently, just hide it for now.
if _config.ErupeConfig.ClientID <= _config.G7 {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
if config.GetConfig().ClientID <= config.G7 {
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
return
}
rows, err := s.server.db.Queryx("SELECT id, min_gr, min_hr, name, url_banner, url_feature, url_thumbnail, wide, recommended, gacha_type, hidden FROM gacha_shop")
rows, err := database.Queryx("SELECT id, min_gr, min_hr, name, url_banner, url_feature, url_thumbnail, wide, recommended, gacha_type, hidden FROM gacha_shop")
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
return
}
bf := byteframe.NewByteFrame()
@@ -156,7 +166,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
ps.Uint8(bf, g.Name, true)
ps.Uint8(bf, g.URLBanner, false)
ps.Uint8(bf, g.URLFeature, false)
if _config.ErupeConfig.ClientID >= _config.G10 {
if config.GetConfig().ClientID >= config.G10 {
bf.WriteBool(g.Wide)
ps.Uint8(bf, g.URLThumbnail, false)
}
@@ -166,23 +176,23 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint16(0)
}
bf.WriteUint8(g.GachaType)
if _config.ErupeConfig.ClientID >= _config.G10 {
if config.GetConfig().ClientID >= config.G10 {
bf.WriteBool(g.Hidden)
}
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
case 2: // Actual gacha
bf := byteframe.NewByteFrame()
bf.WriteUint32(pkt.ShopID)
var gachaType int
s.server.db.QueryRow(`SELECT gacha_type FROM gacha_shop WHERE id = $1`, pkt.ShopID).Scan(&gachaType)
rows, err := s.server.db.Queryx(`SELECT entry_type, id, item_type, item_number, item_quantity, weight, rarity, rolls, daily_limit, frontier_points, COALESCE(name, '') AS name FROM gacha_entries WHERE gacha_id = $1 ORDER BY weight DESC`, pkt.ShopID)
database.QueryRow(`SELECT gacha_type FROM gacha_shop WHERE id = $1`, pkt.ShopID).Scan(&gachaType)
rows, err := database.Queryx(`SELECT entry_type, id, item_type, item_number, item_quantity, weight, rarity, rolls, daily_limit, frontier_points, COALESCE(name, '') AS name FROM gacha_entries WHERE gacha_id = $1 ORDER BY weight DESC`, pkt.ShopID)
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
return
}
var divisor float64
s.server.db.QueryRow(`SELECT COALESCE(SUM(weight) / 100000.0, 0) AS chance FROM gacha_entries WHERE gacha_id = $1`, pkt.ShopID).Scan(&divisor)
database.QueryRow(`SELECT COALESCE(SUM(weight) / 100000.0, 0) AS chance FROM gacha_entries WHERE gacha_id = $1`, pkt.ShopID).Scan(&divisor)
var entry GachaEntry
var entries []GachaEntry
@@ -209,7 +219,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint8(ge.Rarity)
bf.WriteUint8(ge.Rolls)
rows, err = s.server.db.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id=$1`, ge.ID)
rows, err = database.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id=$1`, ge.ID)
if err != nil {
bf.WriteUint8(0)
} else {
@@ -235,7 +245,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint16(gi.Quantity)
}
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
case 3: // Hunting Festival Exchange
fallthrough
case 4: // N Points, 0-6
@@ -257,7 +267,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
items = items[:pkt.Limit]
}
writeShopItems(bf, items)
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
}
}
@@ -265,57 +275,73 @@ func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfAcquireExchangeShop)
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
exchanges := int(bf.ReadUint16())
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
for i := 0; i < exchanges; i++ {
itemHash := bf.ReadUint32()
if itemHash == 0 {
continue
}
buyCount := bf.ReadUint32()
s.server.db.Exec(`INSERT INTO shop_items_bought (character_id, shop_item_id, bought)
database.Exec(`INSERT INTO shop_items_bought (character_id, shop_item_id, bought)
VALUES ($1,$2,$3) ON CONFLICT (character_id, shop_item_id)
DO UPDATE SET bought = bought + $3
WHERE EXCLUDED.character_id=$1 AND EXCLUDED.shop_item_id=$2
`, s.charID, itemHash, buyCount)
`, s.CharID, itemHash, buyCount)
}
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
DoAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
}
func handleMsgMhfGetGachaPlayHistory(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetGachaPlayHistory)
bf := byteframe.NewByteFrame()
bf.WriteUint8(1)
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
}
func handleMsgMhfGetGachaPoint(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetGachaPoint)
var fp, gp, gt uint32
s.server.db.QueryRow("SELECT COALESCE(frontier_points, 0), COALESCE(gacha_premium, 0), COALESCE(gacha_trial, 0) FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)", s.charID).Scan(&fp, &gp, &gt)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow("SELECT COALESCE(frontier_points, 0), COALESCE(gacha_premium, 0), COALESCE(gacha_trial, 0) FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)", s.CharID).Scan(&fp, &gp, &gt)
resp := byteframe.NewByteFrame()
resp.WriteUint32(gp)
resp.WriteUint32(gt)
resp.WriteUint32(fp)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
DoAckBufSucceed(s, pkt.AckHandle, resp.Data())
}
func handleMsgMhfUseGachaPoint(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfUseGachaPoint)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
if pkt.TrialCoins > 0 {
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)`, pkt.TrialCoins, s.charID)
database.Exec(`UPDATE users u SET gacha_trial=gacha_trial-$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, pkt.TrialCoins, s.CharID)
}
if pkt.PremiumCoins > 0 {
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)`, pkt.PremiumCoins, s.charID)
database.Exec(`UPDATE users u SET gacha_premium=gacha_premium-$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, pkt.PremiumCoins, s.CharID)
}
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
DoAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}
func spendGachaCoin(s *Session, quantity uint16) {
var gt uint16
s.server.db.QueryRow(`SELECT COALESCE(gacha_trial, 0) FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&gt)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow(`SELECT COALESCE(gacha_trial, 0) FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.CharID).Scan(&gt)
if quantity <= gt {
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)
database.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)
} else {
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)
database.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)
}
}
@@ -323,7 +349,11 @@ func transactGacha(s *Session, gachaID uint32, rollID uint8) (error, int) {
var itemType uint8
var itemNumber uint16
var rolls int
err := s.server.db.QueryRowx(`SELECT item_type, item_number, rolls FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2`, gachaID, rollID).Scan(&itemType, &itemNumber, &rolls)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
err = database.QueryRowx(`SELECT item_type, item_number, rolls FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2`, gachaID, rollID).Scan(&itemType, &itemNumber, &rolls)
if err != nil {
return err, 0
}
@@ -344,7 +374,7 @@ func transactGacha(s *Session, gachaID uint32, rollID uint8) (error, int) {
case 20:
spendGachaCoin(s, itemNumber)
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)", itemNumber, s.charID)
database.Exec("UPDATE users u SET frontier_points=frontier_points-$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", itemNumber, s.CharID)
}
return nil, rolls
}
@@ -352,7 +382,11 @@ func transactGacha(s *Session, gachaID uint32, rollID uint8) (error, int) {
func getGuaranteedItems(s *Session, gachaID uint32, rollID uint8) []GachaItem {
var rewards []GachaItem
var reward GachaItem
items, err := s.server.db.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = (SELECT id FROM gacha_entries WHERE entry_type = $1 AND gacha_id = $2)`, rollID, gachaID)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
items, err := database.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = (SELECT id FROM gacha_entries WHERE entry_type = $1 AND gacha_id = $2)`, rollID, gachaID)
if err == nil {
for items.Next() {
items.StructScan(&reward)
@@ -364,7 +398,11 @@ func getGuaranteedItems(s *Session, gachaID uint32, rollID uint8) []GachaItem {
func addGachaItem(s *Session, items []GachaItem) {
var data []byte
s.server.db.QueryRow(`SELECT gacha_items FROM characters WHERE id = $1`, s.charID).Scan(&data)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow(`SELECT gacha_items FROM characters WHERE id = $1`, s.CharID).Scan(&data)
if len(data) > 0 {
numItems := int(data[0])
data = data[1:]
@@ -384,7 +422,7 @@ func addGachaItem(s *Session, items []GachaItem) {
newItem.WriteUint16(items[i].ItemID)
newItem.WriteUint16(items[i].Quantity)
}
s.server.db.Exec(`UPDATE characters SET gacha_items = $1 WHERE id = $2`, newItem.Data(), s.charID)
database.Exec(`UPDATE characters SET gacha_items = $1 WHERE id = $2`, newItem.Data(), s.CharID)
}
func getRandomEntries(entries []GachaEntry, rolls int, isBox bool) ([]GachaEntry, error) {
@@ -419,7 +457,11 @@ func getRandomEntries(entries []GachaEntry, rolls int, isBox bool) ([]GachaEntry
func handleMsgMhfReceiveGachaItem(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfReceiveGachaItem)
var data []byte
err := s.server.db.QueryRow("SELECT COALESCE(gacha_items, $2) FROM characters WHERE id = $1", s.charID, []byte{0x00}).Scan(&data)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
err = database.QueryRow("SELECT COALESCE(gacha_items, $2) FROM characters WHERE id = $1", s.CharID, []byte{0x00}).Scan(&data)
if err != nil {
data = []byte{0x00}
}
@@ -429,9 +471,9 @@ func handleMsgMhfReceiveGachaItem(s *Session, p mhfpacket.MHFPacket) {
resp := byteframe.NewByteFrame()
resp.WriteUint8(36)
resp.WriteBytes(data[1:181])
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
DoAckBufSucceed(s, pkt.AckHandle, resp.Data())
} else {
doAckBufSucceed(s, pkt.AckHandle, data)
DoAckBufSucceed(s, pkt.AckHandle, data)
}
if !pkt.Freeze {
@@ -439,9 +481,9 @@ func handleMsgMhfReceiveGachaItem(s *Session, p mhfpacket.MHFPacket) {
update := byteframe.NewByteFrame()
update.WriteUint8(uint8(len(data[181:]) / 5))
update.WriteBytes(data[181:])
s.server.db.Exec("UPDATE characters SET gacha_items = $1 WHERE id = $2", update.Data(), s.charID)
database.Exec("UPDATE characters SET gacha_items = $1 WHERE id = $2", update.Data(), s.CharID)
} else {
s.server.db.Exec("UPDATE characters SET gacha_items = null WHERE id = $1", s.charID)
database.Exec("UPDATE characters SET gacha_items = null WHERE id = $1", s.CharID)
}
}
}
@@ -453,15 +495,19 @@ func handleMsgMhfPlayNormalGacha(s *Session, p mhfpacket.MHFPacket) {
var entry GachaEntry
var rewards []GachaItem
var reward GachaItem
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
err, rolls := transactGacha(s, pkt.GachaID, pkt.RollType)
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
rows, err := s.server.db.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
rows, err := database.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
for rows.Next() {
@@ -475,7 +521,7 @@ func handleMsgMhfPlayNormalGacha(s *Session, p mhfpacket.MHFPacket) {
rewardEntries, err := getRandomEntries(entries, rolls, false)
temp := byteframe.NewByteFrame()
for i := range rewardEntries {
rows, err = s.server.db.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
rows, err = database.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
if err != nil {
continue
}
@@ -494,7 +540,7 @@ func handleMsgMhfPlayNormalGacha(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint8(uint8(len(rewards)))
bf.WriteBytes(temp.Data())
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
addGachaItem(s, rewards)
}
@@ -507,16 +553,20 @@ func handleMsgMhfPlayStepupGacha(s *Session, p mhfpacket.MHFPacket) {
var reward GachaItem
err, rolls := transactGacha(s, pkt.GachaID, pkt.RollType)
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
s.server.db.Exec("UPDATE users u SET frontier_points=frontier_points+(SELECT frontier_points FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2) WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$3)", pkt.GachaID, pkt.RollType, s.charID)
s.server.db.Exec(`DELETE FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.charID)
s.server.db.Exec(`INSERT INTO gacha_stepup (gacha_id, step, character_id) VALUES ($1, $2, $3)`, pkt.GachaID, pkt.RollType+1, s.charID)
rows, err := s.server.db.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
database, err := db.GetDB()
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.Exec("UPDATE users u SET frontier_points=frontier_points+(SELECT frontier_points FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2) WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$3)", pkt.GachaID, pkt.RollType, s.CharID)
database.Exec(`DELETE FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.CharID)
database.Exec(`INSERT INTO gacha_stepup (gacha_id, step, character_id) VALUES ($1, $2, $3)`, pkt.GachaID, pkt.RollType+1, s.CharID)
rows, err := database.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
if err != nil {
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
for rows.Next() {
@@ -531,7 +581,7 @@ func handleMsgMhfPlayStepupGacha(s *Session, p mhfpacket.MHFPacket) {
rewardEntries, err := getRandomEntries(entries, rolls, false)
temp := byteframe.NewByteFrame()
for i := range rewardEntries {
rows, err = s.server.db.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
rows, err = database.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
if err != nil {
continue
}
@@ -557,7 +607,7 @@ func handleMsgMhfPlayStepupGacha(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint8(0)
}
bf.WriteBytes(temp.Data())
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
addGachaItem(s, rewards)
addGachaItem(s, guaranteedItems)
}
@@ -566,24 +616,32 @@ func handleMsgMhfGetStepupStatus(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetStepupStatus)
// TODO: Reset daily (noon)
var step uint8
s.server.db.QueryRow(`SELECT step FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.charID).Scan(&step)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow(`SELECT step FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.CharID).Scan(&step)
var stepCheck int
s.server.db.QueryRow(`SELECT COUNT(1) FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2`, pkt.GachaID, step).Scan(&stepCheck)
database.QueryRow(`SELECT COUNT(1) FROM gacha_entries WHERE gacha_id = $1 AND entry_type = $2`, pkt.GachaID, step).Scan(&stepCheck)
if stepCheck == 0 {
s.server.db.Exec(`DELETE FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.charID)
database.Exec(`DELETE FROM gacha_stepup WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.CharID)
step = 0
}
bf := byteframe.NewByteFrame()
bf.WriteUint8(step)
bf.WriteUint32(uint32(gametime.TimeAdjusted().Unix()))
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
}
func handleMsgMhfGetBoxGachaInfo(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetBoxGachaInfo)
entries, err := s.server.db.Queryx(`SELECT entry_id FROM gacha_box WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.charID)
database, err := db.GetDB()
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
entries, err := database.Queryx(`SELECT entry_id FROM gacha_box WHERE gacha_id = $1 AND character_id = $2`, pkt.GachaID, s.CharID)
if err != nil {
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
var entryIDs []uint32
@@ -598,7 +656,7 @@ func handleMsgMhfGetBoxGachaInfo(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint32(entryIDs[i])
bf.WriteBool(true)
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
}
func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
@@ -610,12 +668,16 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
var reward GachaItem
err, rolls := transactGacha(s, pkt.GachaID, pkt.RollType)
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
rows, err := s.server.db.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
database, err := db.GetDB()
if err != nil {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
rows, err := database.Queryx(`SELECT id, weight, rarity FROM gacha_entries WHERE gacha_id = $1 AND entry_type = 100 ORDER BY weight DESC`, pkt.GachaID)
if err != nil {
DoAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
return
}
for rows.Next() {
@@ -626,11 +688,11 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
}
rewardEntries, err := getRandomEntries(entries, rolls, true)
for i := range rewardEntries {
items, err := s.server.db.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
items, err := database.Queryx(`SELECT item_type, item_id, quantity FROM gacha_items WHERE entry_id = $1`, rewardEntries[i].ID)
if err != nil {
continue
}
s.server.db.Exec(`INSERT INTO gacha_box (gacha_id, entry_id, character_id) VALUES ($1, $2, $3)`, pkt.GachaID, rewardEntries[i].ID, s.charID)
database.Exec(`INSERT INTO gacha_box (gacha_id, entry_id, character_id) VALUES ($1, $2, $3)`, pkt.GachaID, rewardEntries[i].ID, s.CharID)
for items.Next() {
err = items.StructScan(&reward)
if err == nil {
@@ -645,38 +707,50 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint16(r.Quantity)
bf.WriteUint8(0)
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
addGachaItem(s, rewards)
}
func handleMsgMhfResetBoxGachaInfo(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfResetBoxGachaInfo)
s.server.db.Exec("DELETE FROM gacha_box WHERE gacha_id = $1 AND character_id = $2", pkt.GachaID, s.charID)
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.Exec("DELETE FROM gacha_box WHERE gacha_id = $1 AND character_id = $2", pkt.GachaID, s.CharID)
DoAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}
func handleMsgMhfExchangeFpoint2Item(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfExchangeFpoint2Item)
var balance uint32
var itemValue, quantity int
s.server.db.QueryRow("SELECT quantity, fpoints FROM fpoint_items WHERE id=$1", pkt.TradeID).Scan(&quantity, &itemValue)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow("SELECT quantity, fpoints FROM fpoint_items WHERE id=$1", pkt.TradeID).Scan(&quantity, &itemValue)
cost := (int(pkt.Quantity) * quantity) * itemValue
s.server.db.QueryRow("UPDATE users u SET frontier_points=frontier_points::int - $1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2) RETURNING frontier_points", cost, s.charID).Scan(&balance)
database.QueryRow("UPDATE users u SET frontier_points=frontier_points::int - $1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2) RETURNING frontier_points", cost, s.CharID).Scan(&balance)
bf := byteframe.NewByteFrame()
bf.WriteUint32(balance)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
DoAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
}
func handleMsgMhfExchangeItem2Fpoint(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfExchangeItem2Fpoint)
var balance uint32
var itemValue, quantity int
s.server.db.QueryRow("SELECT quantity, fpoints FROM fpoint_items WHERE id=$1", pkt.TradeID).Scan(&quantity, &itemValue)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
database.QueryRow("SELECT quantity, fpoints FROM fpoint_items WHERE id=$1", pkt.TradeID).Scan(&quantity, &itemValue)
cost := (int(pkt.Quantity) / quantity) * itemValue
s.server.db.QueryRow("UPDATE users u SET frontier_points=COALESCE(frontier_points::int + $1, $1) WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2) RETURNING frontier_points", cost, s.charID).Scan(&balance)
database.QueryRow("UPDATE users u SET frontier_points=COALESCE(frontier_points::int + $1, $1) WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2) RETURNING frontier_points", cost, s.CharID).Scan(&balance)
bf := byteframe.NewByteFrame()
bf.WriteUint32(balance)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
DoAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
}
type FPointExchange struct {
@@ -695,7 +769,11 @@ func handleMsgMhfGetFpointExchangeList(s *Session, p mhfpacket.MHFPacket) {
var exchange FPointExchange
var exchanges []FPointExchange
var buyables uint16
rows, err := s.server.db.Queryx(`SELECT id, item_type, item_id, quantity, fpoints, buyable FROM fpoint_items ORDER BY buyable DESC`)
database, err := db.GetDB()
if err != nil {
s.Logger.Fatal(fmt.Sprintf("Failed to get database instance: %s", err))
}
rows, err := database.Queryx(`SELECT id, item_type, item_id, quantity, fpoints, buyable FROM fpoint_items ORDER BY buyable DESC`)
if err == nil {
for rows.Next() {
err = rows.StructScan(&exchange)
@@ -708,7 +786,7 @@ func handleMsgMhfGetFpointExchangeList(s *Session, p mhfpacket.MHFPacket) {
exchanges = append(exchanges, exchange)
}
}
if _config.ErupeConfig.ClientID <= _config.Z2 {
if config.GetConfig().ClientID <= config.Z2 {
bf.WriteUint8(uint8(len(exchanges)))
bf.WriteUint8(uint8(buyables))
} else {
@@ -726,12 +804,12 @@ func handleMsgMhfGetFpointExchangeList(s *Session, p mhfpacket.MHFPacket) {
bf.WriteUint16(e.FPoints)
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
DoAckBufSucceed(s, pkt.AckHandle, bf.Data())
}
func handleMsgMhfPlayFreeGacha(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfPlayFreeGacha)
bf := byteframe.NewByteFrame()
bf.WriteUint32(1)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
DoAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
}