mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 07:25:03 +01:00
387
bundled-schema/FPointItems.sql
Normal file
387
bundled-schema/FPointItems.sql
Normal file
@@ -0,0 +1,387 @@
|
||||
INSERT INTO fpoint_items (item_type, item_id, quantity, fpoints, trade_type) VALUES
|
||||
(7,8895,1,500,0),
|
||||
(7,8891,1,300,0),
|
||||
(7,8892,1,300,0),
|
||||
(7,8893,1,300,0),
|
||||
(7,8894,1,300,0),
|
||||
(7,8890,1,10,0),
|
||||
(7,10354,1,500,0),
|
||||
(7,11983,1,300,0),
|
||||
(7,11984,1,300,0),
|
||||
(7,11985,1,300,0),
|
||||
(7,11986,1,300,0),
|
||||
(7,12524,1,500,0),
|
||||
(7,12470,1,300,0),
|
||||
(7,12471,1,300,0),
|
||||
(7,12472,1,300,0),
|
||||
(7,12473,1,300,0),
|
||||
(7,2158,2,1,0),
|
||||
(7,14548,1,500,0),
|
||||
(7,9509,1,1,0),
|
||||
(7,9510,1,1,0),
|
||||
(7,9511,1,1,0),
|
||||
(7,9512,1,1,0),
|
||||
(7,9513,1,1,0),
|
||||
(7,9514,1,1,0),
|
||||
(7,9515,1,1,0),
|
||||
(7,10753,1,1,0),
|
||||
(7,10754,1,1,0),
|
||||
(7,10755,1,1,0),
|
||||
(7,10756,1,1,0),
|
||||
(7,10757,1,1,0),
|
||||
(7,10758,1,1,0),
|
||||
(7,10759,1,1,0),
|
||||
(7,11296,1,1,0),
|
||||
(7,11297,1,1,0),
|
||||
(7,11298,1,1,0),
|
||||
(7,11299,1,1,0),
|
||||
(7,11300,1,1,0),
|
||||
(7,12386,1,1,0),
|
||||
(7,12387,1,1,0),
|
||||
(7,12388,1,1,0),
|
||||
(7,12389,1,1,0),
|
||||
(7,12390,1,1,0),
|
||||
(7,13034,1,1,0),
|
||||
(7,13035,1,1,0),
|
||||
(7,13036,1,1,0),
|
||||
(7,13037,1,1,0),
|
||||
(7,13038,1,1,0),
|
||||
(7,14179,1,1,0),
|
||||
(7,14180,1,1,0),
|
||||
(7,14181,1,1,0),
|
||||
(7,14182,1,1,0),
|
||||
(7,14183,1,1,0),
|
||||
(7,13422,1,1,0),
|
||||
(7,13423,1,1,0),
|
||||
(7,13424,1,1,0),
|
||||
(7,13425,1,1,0),
|
||||
(7,13426,1,1,0),
|
||||
(7,13427,1,1,0),
|
||||
(7,9796,1,3,0),
|
||||
(7,9700,1,3,0),
|
||||
(7,10380,1,3,0),
|
||||
(7,10810,1,3,0),
|
||||
(7,10811,1,3,0),
|
||||
(7,11436,1,3,0),
|
||||
(7,9509,1,1,0),
|
||||
(7,9510,1,1,0),
|
||||
(7,9511,1,1,0),
|
||||
(7,9512,1,1,0),
|
||||
(7,9513,1,1,0),
|
||||
(7,9514,1,1,0),
|
||||
(7,9515,1,1,0),
|
||||
(7,10753,1,1,0),
|
||||
(7,10754,1,1,0),
|
||||
(7,10755,1,1,0),
|
||||
(7,10756,1,1,0),
|
||||
(7,10757,1,1,0),
|
||||
(7,10758,1,1,0),
|
||||
(7,10759,1,1,0),
|
||||
(7,11296,1,1,0),
|
||||
(7,11297,1,1,0),
|
||||
(7,11298,1,1,0),
|
||||
(7,11299,1,1,0),
|
||||
(7,11300,1,1,0),
|
||||
(7,12509,1,3,0),
|
||||
(7,12386,1,1,0),
|
||||
(7,12387,1,1,0),
|
||||
(7,12388,1,1,0),
|
||||
(7,12389,1,1,0),
|
||||
(7,12390,1,1,0),
|
||||
(7,12872,1,3,0),
|
||||
(7,12873,1,3,0),
|
||||
(7,12840,1,1,0),
|
||||
(7,12841,1,1,0),
|
||||
(7,12874,1,1,0),
|
||||
(7,12875,1,1,0),
|
||||
(7,13191,1,3,0),
|
||||
(7,13177,1,3,0),
|
||||
(7,13326,1,3,0),
|
||||
(7,13034,1,1,0),
|
||||
(7,13035,1,1,0),
|
||||
(7,13036,1,1,0),
|
||||
(7,13037,1,1,0),
|
||||
(7,13038,1,1,0),
|
||||
(7,13178,1,3,0),
|
||||
(7,13453,1,3,0),
|
||||
(7,13449,1,3,0),
|
||||
(7,13450,1,3,0),
|
||||
(7,13404,1,3,0),
|
||||
(7,13422,1,1,0),
|
||||
(7,13423,1,1,0),
|
||||
(7,13424,1,1,0),
|
||||
(7,13425,1,1,0),
|
||||
(7,13426,1,1,0),
|
||||
(7,13427,1,1,0),
|
||||
(7,13791,1,3,0),
|
||||
(7,14006,1,3,0),
|
||||
(7,14031,1,3,0),
|
||||
(7,14032,1,3,0),
|
||||
(7,13960,1,3,0),
|
||||
(7,14029,1,3,0),
|
||||
(7,13956,1,1,0),
|
||||
(7,13958,1,1,0),
|
||||
(7,13957,1,1,0),
|
||||
(7,13959,1,1,0),
|
||||
(7,13790,1,3,0),
|
||||
(7,14005,1,3,0),
|
||||
(7,14010,1,3,0),
|
||||
(7,14009,1,3,0),
|
||||
(7,14008,1,3,0),
|
||||
(7,13965,1,3,0),
|
||||
(7,14028,1,3,0),
|
||||
(7,13963,1,3,0),
|
||||
(7,14026,1,3,0),
|
||||
(7,13964,1,3,0),
|
||||
(7,14027,1,3,0),
|
||||
(7,14069,1,3,0),
|
||||
(7,14124,1,3,0),
|
||||
(7,14065,1,1,0),
|
||||
(7,14066,1,1,0),
|
||||
(7,14067,1,1,0),
|
||||
(7,14068,1,1,0),
|
||||
(7,13962,1,3,0),
|
||||
(7,14125,1,3,0),
|
||||
(7,14089,1,3,0),
|
||||
(7,14090,1,3,0),
|
||||
(7,14091,1,3,0),
|
||||
(7,14092,1,3,0),
|
||||
(7,14194,1,3,0),
|
||||
(7,14191,1,3,0),
|
||||
(7,14198,1,3,0),
|
||||
(7,14197,1,3,0),
|
||||
(7,14179,1,1,0),
|
||||
(7,14180,1,1,0),
|
||||
(7,14181,1,1,0),
|
||||
(7,14182,1,1,0),
|
||||
(7,14183,1,1,0),
|
||||
(7,14196,1,3,0),
|
||||
(7,14195,1,3,0),
|
||||
(7,14193,1,3,0),
|
||||
(7,14192,1,3,0),
|
||||
(7,14407,1,3,0),
|
||||
(7,14414,1,3,0),
|
||||
(7,14406,1,3,0),
|
||||
(7,14413,1,3,0),
|
||||
(7,14416,1,3,0),
|
||||
(7,14549,1,3,0),
|
||||
(7,14550,1,3,0),
|
||||
(7,14502,1,3,0),
|
||||
(7,14507,1,3,0),
|
||||
(7,14501,1,3,0),
|
||||
(7,14506,1,3,0),
|
||||
(7,14500,1,3,0),
|
||||
(7,14505,1,3,0),
|
||||
(7,14498,1,3,0),
|
||||
(7,14659,1,3,0),
|
||||
(7,14660,1,3,0),
|
||||
(7,14657,1,1,0),
|
||||
(7,14658,1,1,0),
|
||||
(7,11420,1,3,0),
|
||||
(7,14704,1,3,0),
|
||||
(7,11288,1,1,0),
|
||||
(7,11289,1,1,0),
|
||||
(7,11290,1,1,0),
|
||||
(7,11291,1,1,0),
|
||||
(7,10750,1,3,0),
|
||||
(7,14705,1,3,0),
|
||||
(7,10633,1,1,0),
|
||||
(7,10634,1,1,0),
|
||||
(7,10635,1,1,0),
|
||||
(7,10636,1,1,0),
|
||||
(7,14662,1,3,0),
|
||||
(7,14663,1,3,0),
|
||||
(7,14665,1,3,0),
|
||||
(7,14666,1,3,0),
|
||||
(7,14667,1,3,0),
|
||||
(7,14668,1,3,0),
|
||||
(7,14669,1,3,0),
|
||||
(7,14670,1,3,0),
|
||||
(7,14671,1,3,0),
|
||||
(7,14672,1,3,0),
|
||||
(7,14673,1,3,0),
|
||||
(7,14674,1,3,0),
|
||||
(7,14675,1,3,0),
|
||||
(7,14676,1,3,0),
|
||||
(7,14677,1,3,0),
|
||||
(7,14678,1,3,0),
|
||||
(7,14679,1,3,0),
|
||||
(7,14680,1,3,0),
|
||||
(7,14681,1,3,0),
|
||||
(7,14682,1,3,0),
|
||||
(7,14683,1,3,0),
|
||||
(7,14684,1,3,0),
|
||||
(7,14685,1,3,0),
|
||||
(7,14686,1,3,0),
|
||||
(7,14687,1,3,0),
|
||||
(7,14688,1,3,0),
|
||||
(7,14689,1,3,0),
|
||||
(7,14690,1,3,0),
|
||||
(7,14691,1,3,0),
|
||||
(7,14692,1,3,0),
|
||||
(7,14693,1,3,0),
|
||||
(7,14694,1,3,0),
|
||||
(7,14695,1,3,0),
|
||||
(7,14696,1,3,0),
|
||||
(7,14697,1,3,0),
|
||||
(7,14698,1,3,0),
|
||||
(7,14699,1,3,0),
|
||||
(7,14700,1,3,0),
|
||||
(7,14314,1,3,0),
|
||||
(7,14503,1,3,0),
|
||||
(7,14510,1,3,0),
|
||||
(7,14904,1,3,0),
|
||||
(7,14906,1,3,0),
|
||||
(7,14910,1,1,0),
|
||||
(7,14912,1,1,0),
|
||||
(7,14905,1,3,0),
|
||||
(7,14907,1,3,0),
|
||||
(7,14911,1,1,0),
|
||||
(7,14909,1,1,0),
|
||||
(7,14855,1,3,0),
|
||||
(7,14894,1,3,0),
|
||||
(7,14913,1,3,0),
|
||||
(7,14914,1,3,0),
|
||||
(7,14891,1,3,0),
|
||||
(7,14895,1,3,0),
|
||||
(7,15027,1,3,0),
|
||||
(7,15028,1,3,0),
|
||||
(7,15026,1,1,0),
|
||||
(7,15025,1,1,0),
|
||||
(7,15024,1,1,0),
|
||||
(7,15023,1,1,0),
|
||||
(7,15064,1,3,0),
|
||||
(7,15065,1,3,0),
|
||||
(7,15030,1,3,0),
|
||||
(7,15031,1,3,0),
|
||||
(7,15062,1,3,0),
|
||||
(7,15063,1,3,0),
|
||||
(7,15066,1,3,0),
|
||||
(7,15067,1,3,0),
|
||||
(7,15061,1,3,0),
|
||||
(7,15060,1,3,0),
|
||||
(7,1227,1,2,0),
|
||||
(7,13176,1,2,0),
|
||||
(7,4360,1,2,0),
|
||||
(7,4358,1,1,0),
|
||||
(7,15118,1,3,0),
|
||||
(7,15119,1,3,0),
|
||||
(7,15113,1,3,0),
|
||||
(7,15114,1,3,0),
|
||||
(7,15115,1,3,0),
|
||||
(7,15116,1,3,0),
|
||||
(7,15220,1,3,0),
|
||||
(7,15221,1,3,0),
|
||||
(7,14126,1,3,0),
|
||||
(7,15222,1,3,0),
|
||||
(7,15223,1,3,0),
|
||||
(7,15224,1,3,0),
|
||||
(7,15225,1,3,0),
|
||||
(7,15524,1,3,0),
|
||||
(7,15525,1,3,0),
|
||||
(7,15507,1,3,0),
|
||||
(7,15508,1,3,0),
|
||||
(7,15285,1,3,0),
|
||||
(7,15286,1,3,0),
|
||||
(7,15281,1,1,0),
|
||||
(7,15282,1,1,0),
|
||||
(7,15283,1,1,0),
|
||||
(7,15284,1,1,0),
|
||||
(7,15776,1,3,0),
|
||||
(7,15777,1,3,0),
|
||||
(7,15774,1,3,0),
|
||||
(7,15775,1,3,0),
|
||||
(7,15823,1,3,0),
|
||||
(7,15824,1,3,0),
|
||||
(7,15343,1,3,0),
|
||||
(7,15342,1,3,0),
|
||||
(7,15341,1,3,0),
|
||||
(7,15340,1,3,0),
|
||||
(7,15339,1,3,0),
|
||||
(7,15338,1,3,0),
|
||||
(7,15337,1,3,0),
|
||||
(7,15336,1,3,0),
|
||||
(7,15335,1,3,0),
|
||||
(7,15334,1,3,0),
|
||||
(7,15333,1,3,0),
|
||||
(7,15332,1,3,0),
|
||||
(7,15331,1,3,0),
|
||||
(7,15330,1,3,0),
|
||||
(7,15329,1,3,0),
|
||||
(7,15328,1,3,0),
|
||||
(7,15327,1,3,0),
|
||||
(7,15326,1,3,0),
|
||||
(7,15325,1,3,0),
|
||||
(7,15324,1,3,0),
|
||||
(7,15323,1,3,0),
|
||||
(7,15322,1,3,0),
|
||||
(7,15321,1,3,0),
|
||||
(7,15314,1,3,0),
|
||||
(7,15312,1,3,0),
|
||||
(7,15311,1,3,0),
|
||||
(7,15306,1,3,0),
|
||||
(7,15307,1,3,0),
|
||||
(7,15308,1,3,0),
|
||||
(7,15309,1,3,0),
|
||||
(7,15310,1,3,0),
|
||||
(7,15305,1,3,0),
|
||||
(7,15304,1,3,0),
|
||||
(7,15303,1,3,0),
|
||||
(7,15302,1,3,0),
|
||||
(7,15301,1,3,0),
|
||||
(7,15300,1,3,0),
|
||||
(7,15299,1,3,0),
|
||||
(7,15298,1,3,0),
|
||||
(7,15297,1,3,0),
|
||||
(7,15296,1,3,0),
|
||||
(7,15295,1,3,0),
|
||||
(7,15293,1,3,0),
|
||||
(7,15294,1,3,0),
|
||||
(7,15292,1,3,0),
|
||||
(7,15291,1,3,0),
|
||||
(7,15290,1,3,0),
|
||||
(7,15289,1,3,0),
|
||||
(7,15315,1,3,0),
|
||||
(7,15316,1,3,0),
|
||||
(7,15317,1,3,0),
|
||||
(7,15318,1,3,0),
|
||||
(7,15319,1,3,0),
|
||||
(7,15320,1,3,0),
|
||||
(7,15819,1,3,0),
|
||||
(7,15820,1,3,0),
|
||||
(7,15821,1,3,0),
|
||||
(7,15822,1,3,0),
|
||||
(7,16450,1,3,0),
|
||||
(7,16451,1,3,0),
|
||||
(7,16459,1,1,0),
|
||||
(7,16460,1,1,0),
|
||||
(7,16461,1,1,0),
|
||||
(7,16462,1,1,0),
|
||||
(7,16463,1,1,0),
|
||||
(7,16464,1,1,0),
|
||||
(7,16465,1,1,0),
|
||||
(7,16466,1,1,0),
|
||||
(7,16467,1,1,0),
|
||||
(7,16468,1,1,0),
|
||||
(7,16469,1,1,0),
|
||||
(7,16470,1,1,0),
|
||||
(7,16471,1,1,0),
|
||||
(7,16472,1,1,0),
|
||||
(7,16454,1,3,0),
|
||||
(7,16455,1,3,0),
|
||||
(7,16442,1,3,0),
|
||||
(7,16443,1,3,0),
|
||||
(7,16342,1,3,0),
|
||||
(7,16343,1,3,0),
|
||||
(7,16444,1,3,0),
|
||||
(7,16445,1,3,0),
|
||||
(7,16344,1,3,0),
|
||||
(7,16345,1,3,0),
|
||||
(7,16352,1,3,0),
|
||||
(7,16353,1,3,0),
|
||||
(7,16446,1,3,0),
|
||||
(7,16447,1,3,0),
|
||||
(7,16448,1,3,0),
|
||||
(7,16449,1,3,0),
|
||||
(7,16348,1,3,0),
|
||||
(7,16349,1,3,0)
|
||||
@@ -1,20 +1,20 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"erupe-ce/network/clientctx"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/network/clientctx"
|
||||
)
|
||||
|
||||
// MsgMhfExchangeFpoint2Item represents the MSG_MHF_EXCHANGE_FPOINT_2_ITEM
|
||||
type MsgMhfExchangeFpoint2Item struct{
|
||||
type MsgMhfExchangeFpoint2Item struct {
|
||||
AckHandle uint32
|
||||
ItemHash uint32
|
||||
ItemType uint16
|
||||
ItemId uint16
|
||||
Quantity byte
|
||||
TradeID uint32
|
||||
ItemType uint16
|
||||
ItemId uint16
|
||||
Quantity byte
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
@@ -25,7 +25,7 @@ func (m *MsgMhfExchangeFpoint2Item) Opcode() network.PacketID {
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfExchangeFpoint2Item) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.ItemHash = bf.ReadUint32()
|
||||
m.TradeID = bf.ReadUint32()
|
||||
m.ItemType = bf.ReadUint16()
|
||||
m.ItemId = bf.ReadUint16()
|
||||
m.Quantity = bf.ReadUint8()
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"erupe-ce/network/clientctx"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/network/clientctx"
|
||||
)
|
||||
|
||||
// MsgMhfExchangeItem2Fpoint represents the MSG_MHF_EXCHANGE_ITEM_2_FPOINT
|
||||
type MsgMhfExchangeItem2Fpoint struct{
|
||||
type MsgMhfExchangeItem2Fpoint struct {
|
||||
AckHandle uint32
|
||||
ItemHash uint32
|
||||
ItemType uint16
|
||||
ItemId uint16
|
||||
Quantity byte
|
||||
TradeID uint32
|
||||
ItemType uint16
|
||||
ItemId uint16
|
||||
Quantity byte
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
@@ -25,7 +25,7 @@ func (m *MsgMhfExchangeItem2Fpoint) Opcode() network.PacketID {
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfExchangeItem2Fpoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.ItemHash = bf.ReadUint32()
|
||||
m.TradeID = bf.ReadUint32()
|
||||
m.ItemType = bf.ReadUint16()
|
||||
m.ItemId = bf.ReadUint16()
|
||||
m.Quantity = bf.ReadUint8()
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"erupe-ce/network/clientctx"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/network/clientctx"
|
||||
)
|
||||
|
||||
// MsgMhfGetGachaPlayHistory represents the MSG_MHF_GET_GACHA_PLAY_HISTORY
|
||||
type MsgMhfGetGachaPlayHistory struct{
|
||||
type MsgMhfGetGachaPlayHistory struct {
|
||||
AckHandle uint32
|
||||
GachaHash uint32
|
||||
GachaID uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
@@ -22,7 +22,7 @@ func (m *MsgMhfGetGachaPlayHistory) Opcode() network.PacketID {
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfGetGachaPlayHistory) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.GachaHash = bf.ReadUint32()
|
||||
m.GachaID = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
29
patch-schema/gacha-db.sql
Normal file
29
patch-schema/gacha-db.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS public.gacha_shop;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.gacha_shop (
|
||||
id serial PRIMARY KEY,
|
||||
min_gr integer,
|
||||
min_hr integer,
|
||||
name text,
|
||||
link1 text,
|
||||
link2 text,
|
||||
link3 text,
|
||||
icon integer,
|
||||
type integer,
|
||||
hide boolean
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS public.fpoint_items;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.fpoint_items (
|
||||
id serial PRIMARY KEY,
|
||||
item_type integer,
|
||||
item_id integer,
|
||||
quantity integer,
|
||||
fpoints integer,
|
||||
trade_type integer
|
||||
);
|
||||
|
||||
END;
|
||||
39
patch-schema/shop-db.sql
Normal file
39
patch-schema/shop-db.sql
Normal file
@@ -0,0 +1,39 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN itemhash TO id;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
ALTER COLUMN points TYPE integer;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN points TO cost;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN tradequantity TO quantity;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN rankreqlow TO min_hr;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN rankreqhigh TO min_sr;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN rankreqg TO min_gr;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN storelevelreq TO req_store_level;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN maximumquantity TO max_quantity;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
DROP COLUMN boughtquantity;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN roadfloorsrequired TO road_floors;
|
||||
|
||||
ALTER TABLE IF EXISTS public.normal_shop_items
|
||||
RENAME COLUMN weeklyfataliskills TO road_fatalis;
|
||||
|
||||
END;
|
||||
@@ -2,6 +2,7 @@ package channelserver
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"time"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
@@ -11,43 +12,91 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ShopItem struct {
|
||||
ID uint32 `db:"id"`
|
||||
ItemID uint16 `db:"itemid"`
|
||||
Cost uint32 `db:"cost"`
|
||||
Quantity uint16 `db:"quantity"`
|
||||
MinHR uint16 `db:"min_hr"`
|
||||
MinSR uint16 `db:"min_sr"`
|
||||
MinGR uint16 `db:"min_gr"`
|
||||
ReqStoreLevel uint16 `db:"req_store_level"`
|
||||
MaxQuantity uint16 `db:"max_quantity"`
|
||||
CharQuantity uint16 `db:"char_quantity"`
|
||||
RoadFloors uint16 `db:"road_floors"`
|
||||
RoadFatalis uint16 `db:"road_fatalis"`
|
||||
}
|
||||
|
||||
type Gacha struct {
|
||||
ID uint32 `db:"id"`
|
||||
MinGR uint32 `db:"min_gr"`
|
||||
MinHR uint32 `db:"min_hr"`
|
||||
Name string `db:"name"`
|
||||
Link1 string `db:"link1"`
|
||||
Link2 string `db:"link2"`
|
||||
Link3 string `db:"link3"`
|
||||
Icon uint16 `db:"icon"`
|
||||
Type uint16 `db:"type"`
|
||||
Hide bool `db:"hide"`
|
||||
}
|
||||
|
||||
func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfEnumerateShop)
|
||||
// SHOP TYPES:
|
||||
// 01 = Running Gachas, 02 = actual gacha, 04 = N Points, 05 = GCP, 07 = Item to GCP, 08 = Diva Defense, 10 = Hunter's Road
|
||||
|
||||
// GACHA FORMAT:
|
||||
// int32: gacha id
|
||||
|
||||
// STORE FORMAT:
|
||||
// Int16: total item count
|
||||
// Int16: total item count
|
||||
|
||||
// ITEM FORMAT:
|
||||
// int32: Unique item hash for tracking purchases
|
||||
// int16: padding?
|
||||
// int16: Item ID
|
||||
// int16: padding?
|
||||
// int16: GCP returns
|
||||
// int16: Number traded at once
|
||||
// int16: HR or SR Requirement
|
||||
// int16: Whichever of the above it isn't
|
||||
// int16: GR Requirement
|
||||
// int16: Store level requirement
|
||||
// int16: Maximum quantity purchasable
|
||||
// int16: Unk
|
||||
// int16: Road floors cleared requirement
|
||||
// int16: Road White Fatalis weekly kills
|
||||
if pkt.ShopType == 2 {
|
||||
// Generic Shop IDs
|
||||
// 0: basic item
|
||||
// 1: gatherables
|
||||
// 2: hr1-4 materials
|
||||
// 3: hr5-7 materials
|
||||
// 4: decos
|
||||
// 5: other item
|
||||
// 6: g mats
|
||||
// 7: limited item
|
||||
// 8: special item
|
||||
switch pkt.ShopType {
|
||||
case 1: // Running gachas
|
||||
var count uint16
|
||||
shopEntries, err := s.server.db.Queryx("SELECT id, min_gr, min_hr, name, link1, link2, link3, icon, type, hide FROM gacha_shop")
|
||||
if err != nil {
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(0)
|
||||
var gacha Gacha
|
||||
for shopEntries.Next() {
|
||||
err = shopEntries.StructScan(&gacha)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resp.WriteUint32(gacha.ID)
|
||||
resp.WriteBytes(make([]byte, 16)) // Rank restriction
|
||||
resp.WriteUint32(gacha.MinGR)
|
||||
resp.WriteUint32(gacha.MinHR)
|
||||
resp.WriteUint32(0) // only 0 in known packet
|
||||
ps.Uint8(resp, gacha.Name, true)
|
||||
ps.Uint8(resp, gacha.Link1, false)
|
||||
ps.Uint8(resp, gacha.Link2, false)
|
||||
resp.WriteBool(gacha.Hide)
|
||||
ps.Uint8(resp, gacha.Link3, false)
|
||||
resp.WriteUint16(gacha.Icon)
|
||||
resp.WriteUint16(gacha.Type)
|
||||
count++
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint16(count)
|
||||
resp.WriteUint16(count)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
case 2: // Actual gacha
|
||||
shopEntries, err := s.server.db.Query("SELECT entryType, itemhash, currType, currNumber, currQuant, percentage, rarityIcon, rollsCount, itemCount, dailyLimit, itemType, itemId, quantity FROM gacha_shop_items WHERE shophash=$1", pkt.ShopID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
var entryType, currType, rarityIcon, rollsCount, itemCount, dailyLimit byte
|
||||
var entryType, currType, rarityIcon, rollsCount, itemCount, dailyLimit uint8
|
||||
var currQuant, currNumber, percentage uint16
|
||||
var itemhash uint32
|
||||
var itemType, itemId, quantity pq.Int64Array
|
||||
var entryCount int
|
||||
var count uint16
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(pkt.ShopID)
|
||||
resp.WriteUint16(0) // total defs
|
||||
@@ -74,164 +123,101 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) {
|
||||
resp.WriteUint16(uint16(itemId[i])) // unk, always 0 in existing packets
|
||||
resp.WriteUint16(uint16(quantity[i])) // unk, always 0 in existing packets
|
||||
}
|
||||
entryCount++
|
||||
}
|
||||
if entryCount == 0 {
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
return
|
||||
count++
|
||||
}
|
||||
resp.Seek(4, 0)
|
||||
resp.WriteUint16(uint16(entryCount))
|
||||
resp.WriteUint16(count)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
} else if pkt.ShopType == 1 {
|
||||
gachaCount := 0
|
||||
shopEntries, err := s.server.db.Query("SELECT hash, reqGR, reqHR, gachaName, gachaLink0, gachaLink1, COALESCE(gachaLink2, ''), extraIcon, gachaType, hideFlag FROM gacha_shop")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(0)
|
||||
var gachaName, gachaLink0, gachaLink1, gachaLink2 string
|
||||
var hash, reqGR, reqHR, extraIcon, gachaType int
|
||||
var hideFlag bool
|
||||
for shopEntries.Next() {
|
||||
err = shopEntries.Scan(&hash, &reqGR, &reqHR, &gachaName, &gachaLink0, &gachaLink1, &gachaLink2, &extraIcon, &gachaType, &hideFlag)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp.WriteUint32(uint32(hash))
|
||||
resp.WriteUint32(0) // only 0 in known packets
|
||||
resp.WriteUint32(0) // all of these seem to trigger the 'rank restriction'
|
||||
resp.WriteUint32(0) // message so they are presumably placeholders for a
|
||||
resp.WriteUint32(0) // Z Rank or similar that never turned up?
|
||||
resp.WriteUint32(uint32(reqGR))
|
||||
resp.WriteUint32(uint32(reqHR))
|
||||
resp.WriteUint32(0) // only 0 in known packet
|
||||
stringBytes := append([]byte(gachaName), 0x00)
|
||||
resp.WriteUint8(byte(len(stringBytes)))
|
||||
resp.WriteBytes(stringBytes)
|
||||
stringBytes = append([]byte(gachaLink0), 0x00)
|
||||
resp.WriteUint8(byte(len(stringBytes)))
|
||||
resp.WriteBytes(stringBytes)
|
||||
stringBytes = append([]byte(gachaLink1), 0x00)
|
||||
resp.WriteUint8(byte(len(stringBytes)))
|
||||
resp.WriteBytes(stringBytes)
|
||||
stringBytes = append([]byte(gachaLink2), 0x00)
|
||||
resp.WriteBool(hideFlag)
|
||||
resp.WriteUint8(uint8(len(stringBytes)))
|
||||
resp.WriteBytes(stringBytes)
|
||||
resp.WriteUint16(uint16(extraIcon))
|
||||
resp.WriteUint16(uint16(gachaType))
|
||||
gachaCount++
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint16(uint16(gachaCount))
|
||||
resp.WriteUint16(uint16(gachaCount))
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
|
||||
} else if pkt.ShopType == 7 {
|
||||
// GCP conversion store
|
||||
if pkt.ShopID == 0 {
|
||||
// Items to GCP exchange. Gou Tickets, Shiten Tickets, GP Tickets
|
||||
data, _ := hex.DecodeString("000300033a9186fb000033860000000a000100000000000000000000000000000000097fdb1c0000067e0000000a0001000000000000000000000000000000001374db29000027c300000064000100000000000000000000000000000000")
|
||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||
} else {
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
} else if pkt.ShopType == 8 {
|
||||
// Dive Defense sections
|
||||
// 00 = normal level limited exchange store, 05 = GCP skill store, 07 = limited quantity exchange
|
||||
if pkt.ShopID == 5 {
|
||||
// diva defense skill level limited store
|
||||
case 4: // N Points, 0-6
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
case 5: // GCP->Item, 0-6
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
case 6: // Gacha coin->Item
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
case 7: // Item->GCP
|
||||
data, _ := hex.DecodeString("000300033a9186fb000033860000000a000100000000000000000000000000000000097fdb1c0000067e0000000a0001000000000000000000000000000000001374db29000027c300000064000100000000000000000000000000000000")
|
||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||
case 8: // Diva
|
||||
switch pkt.ShopID {
|
||||
case 0: // Normal exchange
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
case 5: // GCP skills
|
||||
data, _ := hex.DecodeString("001f001f2c9365c1000000010000001e000a0000000000000000000a0000000000001979f1c2000000020000003c000a0000000000000000000a0000000000003e5197df000000030000003c000a0000000000000000000a000000000000219337c0000000040000001e000a0000000000000000000a00000000000009b24c9d000000140000001e000a0000000000000000000a0000000000001f1d496e000000150000001e000a0000000000000000000a0000000000003b918fcb000000160000003c000a0000000000000000000a0000000000000b7fd81c000000170000003c000a0000000000000000000a0000000000001374f239000000180000003c000a0000000000000000000a00000000000026950cba0000001c0000003c000a0000000000000000000a0000000000003797eae70000001d0000003c000a012b000000000000000a00000000000015758ad8000000050000003c00000000000000000000000a0000000000003c7035050000000600000050000a0000000000000001000a00000000000024f3b5560000000700000050000a0000000000000001000a00000000000000b600330000000800000050000a0000000000000001000a0000000000002efdce840000001900000050000a0000000000000001000a0000000000002d9365f10000001a00000050000a0000000000000001000a0000000000001979f3420000001f00000050000a012b000000000001000a0000000000003f5397cf0000002000000050000a012b000000000001000a000000000000319337c00000002100000050000a012b000000000001000a00000000000008b04cbd0000000900000064000a0000000000000002000a0000000000000b1d4b6e0000000a00000064000a0000000000000002000a0000000000003b918feb0000000b00000064000a0000000000000002000a0000000000001b7fd81c0000000c00000064000a0000000000000002000a0000000000001276f2290000000d00000064000a0000000000000002000a00000000000022950cba0000000e000000c8000a0000000000000002000a0000000000003697ead70000000f000001f4000a0000000000000003000a00000000000005758a5800000010000003e8000a0000000000000003000a0000000000003c7035250000001b000001f4000a0000000000010003000a00000000000034f3b5d60000001e00000064000a012b000000000003000a00000000000000b600030000002200000064000a0000000000010003000a000000000000")
|
||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||
} else {
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
case 7: // Note exchange
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
} 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)
|
||||
case 10: // Item shop, 0-8
|
||||
shopEntries, err := s.server.db.Queryx(`SELECT id, itemid, cost, quantity, min_hr, min_sr, min_gr, req_store_level, max_quantity,
|
||||
COALESCE((SELECT usedquantity FROM shop_item_state WHERE itemhash=nsi.id AND char_id=$3), 0) as char_quantity,
|
||||
road_floors, road_fatalis FROM normal_shop_items nsi WHERE shoptype=$1 AND shopid=$2
|
||||
`, pkt.ShopType, pkt.ShopID, s.charID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var ItemHash, entryCount int
|
||||
var itemID, Points, TradeQuantity, rankReqLow, rankReqHigh, rankReqG, storeLevelReq, maximumQuantity, boughtQuantity, roadFloorsRequired, weeklyFatalisKills, charQuantity uint16
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(0) // total defs
|
||||
for shopEntries.Next() {
|
||||
err = shopEntries.Scan(&ItemHash, &itemID, &Points, &TradeQuantity, &rankReqLow, &rankReqHigh, &rankReqG, &storeLevelReq, &maximumQuantity, &boughtQuantity, &roadFloorsRequired, &weeklyFatalisKills)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp.WriteUint32(uint32(ItemHash))
|
||||
resp.WriteUint16(0) // unk, always 0 in existing packets
|
||||
resp.WriteUint16(itemID)
|
||||
resp.WriteUint16(0) // unk, always 0 in existing packets
|
||||
resp.WriteUint16(Points) // it's either item ID or quantity for gacha coins
|
||||
resp.WriteUint16(TradeQuantity) // only for item ID
|
||||
resp.WriteUint16(rankReqLow)
|
||||
resp.WriteUint16(rankReqHigh)
|
||||
resp.WriteUint16(rankReqG)
|
||||
resp.WriteUint16(storeLevelReq)
|
||||
resp.WriteUint16(maximumQuantity)
|
||||
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)
|
||||
if err != nil {
|
||||
resp.WriteUint16(0)
|
||||
} else {
|
||||
resp.WriteUint16(charQuantity)
|
||||
}
|
||||
} else {
|
||||
resp.WriteUint16(boughtQuantity)
|
||||
}
|
||||
resp.WriteUint16(roadFloorsRequired)
|
||||
resp.WriteUint16(weeklyFatalisKills)
|
||||
entryCount++
|
||||
}
|
||||
if entryCount == 0 {
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
var count uint16
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteBytes(make([]byte, 4))
|
||||
var shopItem ShopItem
|
||||
for shopEntries.Next() {
|
||||
err = shopEntries.StructScan(&shopItem)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resp.WriteUint32(shopItem.ID)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint16(shopItem.ItemID)
|
||||
resp.WriteUint32(shopItem.Cost)
|
||||
resp.WriteUint16(shopItem.Quantity)
|
||||
resp.WriteUint16(shopItem.MinHR)
|
||||
resp.WriteUint16(shopItem.MinSR)
|
||||
resp.WriteUint16(shopItem.MinGR)
|
||||
resp.WriteUint16(shopItem.ReqStoreLevel)
|
||||
resp.WriteUint16(shopItem.MaxQuantity)
|
||||
resp.WriteUint16(shopItem.CharQuantity)
|
||||
resp.WriteUint16(shopItem.RoadFloors)
|
||||
resp.WriteUint16(shopItem.RoadFatalis)
|
||||
count++
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint16(uint16(entryCount))
|
||||
resp.WriteUint16(uint16(entryCount))
|
||||
resp.WriteUint16(count)
|
||||
resp.WriteUint16(count)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
}
|
||||
}
|
||||
|
||||
func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
||||
// writing out to an editable shop enumeration
|
||||
pkt := p.(*mhfpacket.MsgMhfAcquireExchangeShop)
|
||||
if pkt.DataSize == 10 {
|
||||
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
|
||||
_ = bf.ReadUint16() // unk, always 1 in examples
|
||||
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
|
||||
exchanges := int(bf.ReadUint16())
|
||||
for i := 0; i < exchanges; i++ {
|
||||
itemHash := bf.ReadUint32()
|
||||
buyCount := bf.ReadUint32()
|
||||
_, err := s.server.db.Exec(`INSERT INTO shop_item_state (char_id, itemhash, usedquantity)
|
||||
VALUES ($1,$2,$3) ON CONFLICT (char_id, itemhash)
|
||||
DO UPDATE SET usedquantity = shop_item_state.usedquantity + $3
|
||||
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.itemhash=$2`, s.charID, itemHash, buyCount)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update shop_item_state in db", zap.Error(err))
|
||||
}
|
||||
s.server.db.Exec(`INSERT INTO shop_item_state (char_id, itemhash, usedquantity)
|
||||
VALUES ($1,$2,$3) ON CONFLICT (char_id, itemhash)
|
||||
DO UPDATE SET usedquantity = shop_item_state.usedquantity + $3
|
||||
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.itemhash=$2
|
||||
`, s.charID, itemHash, buyCount)
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
|
||||
func handleMsgMhfGetGachaPlayHistory(s *Session, p mhfpacket.MHFPacket) {
|
||||
// returns number of times the gacha was played, will need persistent db stuff
|
||||
pkt := p.(*mhfpacket.MsgMhfGetGachaPlayHistory)
|
||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x0A})
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint8(0)
|
||||
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_prem, 0), COALESCE(gacha_trial,0) FROM characters WHERE id=$1", s.charID).Scan(&fp, &gp, >)
|
||||
s.server.db.QueryRow("SELECT COALESCE(frontier_points, 0), COALESCE(gacha_prem, 0), COALESCE(gacha_trial,0) FROM characters WHERE id=$1", s.charID).Scan(&fp, &gp, >)
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(gp) // Real Gacha Points?
|
||||
resp.WriteUint32(gt) // Trial Gacha Point?
|
||||
resp.WriteUint32(fp) // Frontier Points?
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
}
|
||||
|
||||
@@ -303,11 +289,11 @@ func handleMsgMhfPlayNormalGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
dbUpdate.Seek(0, 0)
|
||||
// response needs all item info and the rarity
|
||||
resp.WriteBytes(dbUpdate.Data())
|
||||
resp.WriteUint8(uint8(items[ind].(*gachaItem).rarityIcon))
|
||||
resp.WriteUint8(items[ind].(*gachaItem).rarityIcon)
|
||||
}
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint8(uint8(results))
|
||||
resp.WriteUint8(results)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
|
||||
// add claimables to DB
|
||||
@@ -333,83 +319,77 @@ func handleMsgMhfUseGachaPoint(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfExchangeFpoint2Item(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfExchangeFpoint2Item)
|
||||
|
||||
var itemValue, quant int
|
||||
_ = s.server.db.QueryRow("SELECT quant, itemValue FROM fpoint_items WHERE hash=$1", pkt.ItemHash).Scan(&quant, &itemValue)
|
||||
itemCost := (int(pkt.Quantity) * quant) * itemValue
|
||||
|
||||
// also update frontierpoints entry in database
|
||||
_, err := s.server.db.Exec("UPDATE characters SET frontier_points=frontier_points::int - $1 WHERE id=$2", itemCost, s.charID)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update minidata in db", zap.Error(err))
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||
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)
|
||||
cost := (int(pkt.Quantity) * quantity) * itemValue
|
||||
s.server.db.QueryRow("UPDATE characters SET frontier_points=frontier_points::int - $1 WHERE id=$2 RETURNING frontier_points", cost, s.charID).Scan(&balance)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(balance)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfExchangeItem2Fpoint(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfExchangeItem2Fpoint)
|
||||
|
||||
var itemValue, quant int
|
||||
_ = s.server.db.QueryRow("SELECT quant, itemValue FROM fpoint_items WHERE hash=$1", pkt.ItemHash).Scan(&quant, &itemValue)
|
||||
itemCost := (int(pkt.Quantity) / quant) * itemValue
|
||||
// also update frontierpoints entry in database
|
||||
_, err := s.server.db.Exec("UPDATE characters SET frontier_points=COALESCE(frontier_points::int + $1, $1) WHERE id=$2", itemCost, s.charID)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update minidata in db", zap.Error(err))
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||
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)
|
||||
cost := (int(pkt.Quantity) / quantity) * itemValue
|
||||
s.server.db.QueryRow("UPDATE characters SET frontier_points=COALESCE(frontier_points::int + $1, $1) WHERE id=$2 RETURNING frontier_points", cost, s.charID).Scan(&balance)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(balance)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGetFpointExchangeList(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetFpointExchangeList)
|
||||
//absurd, probably lists every single item to trade to FP?
|
||||
|
||||
var buyables int
|
||||
var sellables int
|
||||
|
||||
buyRows, err := s.server.db.Query("SELECT hash,itemType,itemID,quant,itemValue FROM fpoint_items WHERE tradeType=0")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp := byteframe.NewByteFrame()
|
||||
resp.WriteUint32(0)
|
||||
var hash, itemType, itemID, quant, itemValue int
|
||||
for buyRows.Next() {
|
||||
err = buyRows.Scan(&hash, &itemType, &itemID, &quant, &itemValue)
|
||||
if err != nil {
|
||||
panic("Error in fpoint_items")
|
||||
var buyables, sellables uint16
|
||||
var id uint32
|
||||
var itemType uint8
|
||||
var itemID, quantity, fPoints uint16
|
||||
|
||||
buyRows, err := s.server.db.Query("SELECT id,item_type,item_id,quantity,fpoints FROM fpoint_items WHERE trade_type=0")
|
||||
if err == nil {
|
||||
for buyRows.Next() {
|
||||
err = buyRows.Scan(&id, &itemType, &itemID, &quantity, &fPoints)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resp.WriteUint32(id)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint8(itemType)
|
||||
resp.WriteUint16(itemID)
|
||||
resp.WriteUint16(quantity)
|
||||
resp.WriteUint16(fPoints)
|
||||
buyables++
|
||||
}
|
||||
resp.WriteUint32(uint32(hash))
|
||||
resp.WriteUint32(0) // this and following only 0 in known packets
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint8(byte(itemType))
|
||||
resp.WriteUint16(uint16(itemID))
|
||||
resp.WriteUint16(uint16(quant))
|
||||
resp.WriteUint16(uint16(itemValue))
|
||||
buyables++
|
||||
}
|
||||
|
||||
sellRows, err := s.server.db.Query("SELECT hash,itemType,itemID,quant,itemValue FROM fpoint_items WHERE tradeType=1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for sellRows.Next() {
|
||||
err = sellRows.Scan(&hash, &itemType, &itemID, &quant, &itemValue)
|
||||
if err != nil {
|
||||
panic("Error in fpoint_items")
|
||||
sellRows, err := s.server.db.Query("SELECT id,item_type,item_id,quantity,fpoints FROM fpoint_items WHERE trade_type=1")
|
||||
if err == nil {
|
||||
for sellRows.Next() {
|
||||
err = sellRows.Scan(&id, &itemType, &itemID, &quantity, &fPoints)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resp.WriteUint32(id)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint8(itemType)
|
||||
resp.WriteUint16(itemID)
|
||||
resp.WriteUint16(quantity)
|
||||
resp.WriteUint16(fPoints)
|
||||
sellables++
|
||||
}
|
||||
resp.WriteUint32(uint32(hash))
|
||||
resp.WriteUint32(0) // this and following only 0 in known packets
|
||||
resp.WriteUint16(0)
|
||||
resp.WriteUint8(byte(itemType))
|
||||
resp.WriteUint16(uint16(itemID))
|
||||
resp.WriteUint16(uint16(quant))
|
||||
resp.WriteUint16(uint16(itemValue))
|
||||
sellables++
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint16(uint16(sellables))
|
||||
resp.WriteUint16(uint16(buyables))
|
||||
resp.WriteUint16(buyables)
|
||||
resp.WriteUint16(sellables)
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
}
|
||||
@@ -474,13 +454,13 @@ func handleMsgMhfPlayStepupGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
rollFrame.Seek(0, 0)
|
||||
// response needs all item info and the rarity
|
||||
resp.WriteBytes(rollFrame.Data())
|
||||
resp.WriteUint8(uint8(items[ind].(*gachaItem).rarityIcon))
|
||||
resp.WriteUint8(items[ind].(*gachaItem).rarityIcon)
|
||||
}
|
||||
}
|
||||
resp.WriteBytes(stepFrame.Data())
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint8(uint8(results + stepResults))
|
||||
resp.WriteUint8(uint8(results))
|
||||
resp.WriteUint8(results + stepResults)
|
||||
resp.WriteUint8(results)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
|
||||
// add claimables to DB
|
||||
@@ -494,10 +474,9 @@ func handleMsgMhfPlayStepupGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
// reduce real if trial don't cover cost
|
||||
if currType == 19 {
|
||||
_, err = s.server.db.Exec(`UPDATE characters
|
||||
SET gacha_trial = CASE WHEN (gacha_trial > $1) then gacha_trial - $1 else gacha_trial end,
|
||||
gacha_prem = CASE WHEN NOT (gacha_trial > $1) then gacha_prem - $1 else gacha_prem end
|
||||
WHERE id=$2`, currNumber, s.charID)
|
||||
|
||||
SET gacha_trial = CASE WHEN (gacha_trial > $1) then gacha_trial - $1 else gacha_trial end,
|
||||
gacha_prem = CASE WHEN NOT (gacha_trial > $1) then gacha_prem - $1 else gacha_prem end
|
||||
WHERE id=$2`, currNumber, s.charID)
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update gacha_items in db", zap.Error(err))
|
||||
@@ -565,9 +544,9 @@ func handleMsgMhfGetStepupStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||
step_progression = 0
|
||||
}
|
||||
_, err = s.server.db.Exec(`INSERT INTO stepup_state (shophash, step_progression, step_time, char_id)
|
||||
VALUES ($1,$2,$3,$4) ON CONFLICT (shophash, char_id)
|
||||
DO UPDATE SET step_progression=$2, step_time=$3
|
||||
WHERE EXCLUDED.char_id=$4 AND EXCLUDED.shophash=$1`, pkt.GachaHash, step_progression, midday, s.charID)
|
||||
VALUES ($1,$2,$3,$4) ON CONFLICT (shophash, char_id)
|
||||
DO UPDATE SET step_progression=$2, step_time=$3
|
||||
WHERE EXCLUDED.char_id=$4 AND EXCLUDED.shophash=$1`, pkt.GachaHash, step_progression, midday, s.charID)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update platedata savedata in db", zap.Error(err))
|
||||
}
|
||||
@@ -626,11 +605,11 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
// get gacha items and iterate through them for gacha roll
|
||||
shopEntries, err := s.server.db.Query(`SELECT itemhash, percentage, rarityIcon, itemCount, itemType, itemId, quantity
|
||||
FROM gacha_shop_items
|
||||
WHERE shophash=$1 AND entryType=100
|
||||
EXCEPT ALL SELECT itemhash, percentage, rarityIcon, itemCount, itemType, itemId, quantity
|
||||
FROM gacha_shop_items gsi JOIN lucky_box_state lbs ON gsi.itemhash = ANY(lbs.used_itemhash)
|
||||
WHERE lbs.char_id=$2`, pkt.GachaHash, s.charID)
|
||||
FROM gacha_shop_items
|
||||
WHERE shophash=$1 AND entryType=100
|
||||
EXCEPT ALL SELECT itemhash, percentage, rarityIcon, itemCount, itemType, itemId, quantity
|
||||
FROM gacha_shop_items gsi JOIN lucky_box_state lbs ON gsi.itemhash = ANY(lbs.used_itemhash)
|
||||
WHERE lbs.char_id=$2`, pkt.GachaHash, s.charID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -659,7 +638,7 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
dbUpdate.Seek(0, 0)
|
||||
// response needs all item info and the rarity
|
||||
resp.WriteBytes(dbUpdate.Data())
|
||||
resp.WriteUint8(uint8(items[ind].(*gachaItem).rarityIcon))
|
||||
resp.WriteUint8(items[ind].(*gachaItem).rarityIcon)
|
||||
|
||||
usedItemHash = append(usedItemHash, int64(items[ind].(*gachaItem).itemhash))
|
||||
}
|
||||
@@ -667,7 +646,7 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
items = append(items[:ind], items[ind+1:]...)
|
||||
}
|
||||
resp.Seek(0, 0)
|
||||
resp.WriteUint8(uint8(results))
|
||||
resp.WriteUint8(results)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
|
||||
// add claimables to DB
|
||||
@@ -677,18 +656,18 @@ func handleMsgMhfPlayBoxGacha(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.logger.Fatal("Failed to update gacha_items in db", zap.Error(err))
|
||||
}
|
||||
// update lucky_box_state
|
||||
_, err = s.server.db.Exec(` INSERT INTO lucky_box_state (char_id, shophash, used_itemhash)
|
||||
VALUES ($1,$2,$3) ON CONFLICT (char_id, shophash)
|
||||
DO UPDATE SET used_itemhash = COALESCE(lucky_box_state.used_itemhash::int[] || $3::int[], $3::int[])
|
||||
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.shophash=$2`, s.charID, pkt.GachaHash, usedItemHash)
|
||||
_, err = s.server.db.Exec(`INSERT INTO lucky_box_state (char_id, shophash, used_itemhash)
|
||||
VALUES ($1,$2,$3) ON CONFLICT (char_id, shophash)
|
||||
DO UPDATE SET used_itemhash = COALESCE(lucky_box_state.used_itemhash::int[] || $3::int[], $3::int[])
|
||||
WHERE EXCLUDED.char_id=$1 AND EXCLUDED.shophash=$2`, s.charID, pkt.GachaHash, usedItemHash)
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update lucky box state in db", zap.Error(err))
|
||||
}
|
||||
// deduct gacha coins if relevant, items are handled fine by the standard savedata packet immediately afterwards
|
||||
if currType == 19 {
|
||||
_, err = s.server.db.Exec(` UPDATE characters
|
||||
SET gacha_trial = CASE WHEN (gacha_trial > $1) then gacha_trial - $1 else gacha_trial end, gacha_prem = CASE WHEN NOT (gacha_trial > $1) then gacha_prem - $1 else gacha_prem end
|
||||
WHERE id=$2`, currNumber, s.charID)
|
||||
_, err = s.server.db.Exec(`UPDATE characters
|
||||
SET gacha_trial = CASE WHEN (gacha_trial > $1) then gacha_trial - $1 else gacha_trial end, gacha_prem = CASE WHEN NOT (gacha_trial > $1) then gacha_prem - $1 else gacha_prem end
|
||||
WHERE id=$2`, currNumber, s.charID)
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Fatal("Failed to update gacha_trial in db", zap.Error(err))
|
||||
|
||||
Reference in New Issue
Block a user