diff --git a/bin/backtask/config/config.json b/bin/backtask/config/config.json index 0793d3a4..840f766d 100644 --- a/bin/backtask/config/config.json +++ b/bin/backtask/config/config.json @@ -2,5 +2,7 @@ "gameapi_url": "https://game2006api-test.kingsome.cn", "net_id": 13473, "immutable_base_url": "https://api.sandbox.immutable.com", + "hero_contract_address": "0x65570A86E5aA2B14325f8a13C70b74f7d1E2f5c9", + "immutable_api_key": "sk_imapik-test-kbe8ZWVEzySQPmdiOd8H_ac92cd", "chain_name": "imtbl-zkevm-testnet" } diff --git a/server/backtask/mtb/mtb.auto_gen.go b/server/backtask/mtb/mtb.auto_gen.go index bca2b8bb..51bf145a 100644 --- a/server/backtask/mtb/mtb.auto_gen.go +++ b/server/backtask/mtb/mtb.auto_gen.go @@ -70,6 +70,8 @@ type Config struct { net_id int32 immutable_base_url string chain_name string + hero_contract_address string + immutable_api_key string _flags1_ uint64 _flags2_ uint64 @@ -402,6 +404,22 @@ func (this *Config) HasChainName() bool { return (this._flags1_ & (uint64(1) << 4)) > 0 } +func (this *Config) GetHeroContractAddress() string { + return this.hero_contract_address +} + +func (this *Config) HasHeroContractAddress() bool { + return (this._flags1_ & (uint64(1) << 5)) > 0 +} + +func (this *Config) GetImmutableApiKey() string { + return this.immutable_api_key +} + +func (this *Config) HasImmutableApiKey() bool { + return (this._flags1_ & (uint64(1) << 6)) > 0 +} + func (this *Item) GetName() string { return this.name } @@ -590,6 +608,8 @@ func (this *Config) LoadFromKv(kv map[string]interface{}) { f5.ReadMetaTableField(&this.net_id, "net_id", &this._flags1_, 2, kv) f5.ReadMetaTableField(&this.immutable_base_url, "immutable_base_url", &this._flags1_, 3, kv) f5.ReadMetaTableField(&this.chain_name, "chain_name", &this._flags1_, 4, kv) + f5.ReadMetaTableField(&this.hero_contract_address, "hero_contract_address", &this._flags1_, 5, kv) + f5.ReadMetaTableField(&this.immutable_api_key, "immutable_api_key", &this._flags1_, 6, kv) } func (this *Item) LoadFromKv(kv map[string]interface{}) { diff --git a/server/backtask/proto/mt.proto b/server/backtask/proto/mt.proto index 6a2ffd0b..bdb87948 100644 --- a/server/backtask/proto/mt.proto +++ b/server/backtask/proto/mt.proto @@ -59,6 +59,8 @@ message Config optional int32 net_id = 2; optional string immutable_base_url = 3; optional string chain_name = 4; + optional string hero_contract_address = 5; + optional string immutable_api_key = 6; } message Item diff --git a/server/backtask/task/refresh_meta.go b/server/backtask/task/refresh_meta.go index 88bd6871..a6d9b6e3 100644 --- a/server/backtask/task/refresh_meta.go +++ b/server/backtask/task/refresh_meta.go @@ -3,18 +3,58 @@ package task import ( "q5" "f5" + "mt" "fmt" "jccommon" "main/constant" - "main/service" - "math/rand" + //"math/rand" + "strings" + "net/http" + "io/ioutil" ) -type refreshMeta struct { +type nftInfo struct { + netId int32 + contractAddress string + tokenId string + apiMeta *apiNftMeta + nftMeta *nftMeta +} +type apiNftMeta struct { + TokenId string `json:"token_id"` + Name string `json:"name"` + Description string `json:"description"` + Image string `json:"image"` + //ExternalUrl string `json:"external_url"` + //AnimationUrl string `json:"animation_url"` + //YoutubeUrl string `json:"youtube_url"` + Attributes []struct { + TraitType string `json:"trait_type"` + Value interface{} `json:"value"` + } `json:"attributes"` +} + +type nftMeta struct { + Name string `json:"name"` + Description string `json:"description"` + Image string `json:"image"` + ExternalUrl string `json:"external_url"` + AnimationUrl string `json:"animation_url"` + YoutubeUrl string `json:"youtube_url"` + TokenId string `json:"token_id"` + Attributes []struct { + TraitType string `json:"trait_type"` + Value interface{} `json:"value"` + } `json:"attributes"` +} + +type refreshMeta struct { + batchNfts []*nftInfo } func (this* refreshMeta) init() { + this.batchNfts = []*nftInfo{} go this.process() } @@ -25,70 +65,105 @@ func (this* refreshMeta) process() { f5.GetGoStyleDb().LoopLoad( constant.BCNFT_DB, "refreshMeta", - "t_order", + "t_nft", func () int64 { - return 60 + q5.ToInt64(rand.Intn(3)) + return 30 }, func (lastIdx int64) string { sql := fmt.Sprintf(` -SELECT * FROM t_order WHERE idx > %d AND status = ? LIMIT 100`, +SELECT * FROM t_nft WHERE idx > %d AND last_refresh_meta_time = 0 LIMIT 200`, lastIdx, ) return sql }, []string{ - jccommon.ORDER_STATUS_ACTIVE, }, func () int64 { + this.doRefresh() + this.batchNfts = []*nftInfo{} return 3 }, func () int64 { - return 60 + q5.ToInt64(rand.Intn(3)) + this.doRefresh() + this.batchNfts = []*nftInfo{} + return 60 }, - this.repairPrice) + this.repairHeroMeta) } -func (this* refreshMeta) repairPrice(ds *f5.DataSet) bool { - if service.BcCurrency.GetLastRefreshOkTime() + 3600 * 2 < f5.GetApp().GetRealSeconds() { - return false - } - dbIdx := ds.GetByName("idx") - eventId := ds.GetByName("event_id") - srcPriceAmount := ds.GetByName("src_price_amount") - srcPriceContractAddress := ds.GetByName("src_price_contract_address") - srcPriceItemType := ds.GetByName("src_price_item_type") - if srcPriceAmount == "" { - p := new(jccommon.OrderUpdatedEvent) - err := q5.DecodeJson(ds.GetByName("event_data"), &p) - if err != nil { - return false - } - srcPriceAmount = p.Data.Buy[0].Amount - srcPriceContractAddress = p.Data.Buy[0].ContractAddress - srcPriceItemType = p.Data.Buy[0].ItemType - } - srcPriceExchangeRate, price := service.BcCurrency.ExchangeUSD( - srcPriceAmount, srcPriceItemType, srcPriceContractAddress) - updateFields := [][]string{ - {"src_price_amount", srcPriceAmount}, - {"src_price_contract_address", srcPriceContractAddress}, - {"src_price_item_type", srcPriceItemType}, - {"price", price}, - {"price_len", q5.ToString(len(price))}, - {"src_price_exchange_rate", q5.ToString(srcPriceExchangeRate)}, - } - f5.GetGoStyleDb().Update( - constant.BCNFT_DB, - "t_order", - [][]string{ - {"idx", q5.ToString(dbIdx)}, - {"event_id", eventId}, - }, - updateFields, - func (err error, lastInsertId int64, rowsAffected int64) { - if err != nil { - return - } - }) +func (this* refreshMeta) repairHeroMeta(ds *f5.DataSet) bool { + f5.GetSysLog().Info("refresh meta %s %s %s", + ds.GetByName("net_id"), + ds.GetByName("contract_address"), + ds.GetByName("token_id")) + nft := new(nftInfo) + nft.netId = q5.ToInt32(ds.GetByName("net_id")) + nft.contractAddress = ds.GetByName("contract_address") + nft.tokenId = ds.GetByName("token_id") + q5.AppendSlice(&this.batchNfts, nft) return true } + +//https://api.sandbox.immutable.com/v1/chains/{chain_name}/collections/{contract_address}/nfts/refresh-metadata +func (this* refreshMeta) doRefresh() { + nftMetas := []*nftMeta{} + for _, v := range this.batchNfts { + f5.GetHttpCliMgr().SendGoStyleRequest( + mt.Table.Config.GetById(0).GetGameapiUrl() + "/webapp/index.php", + map[string]string{ + "c": "OutAppNft", + "a": "nftMetaView", + "net_id": q5.ToString(v.netId), + "token_type": q5.ToString(jccommon.NFT_TYPE_CFHERO), + "token_id": v.tokenId, + }, + func (rsp f5.HttpCliResponse) { + if rsp.GetErr() != nil { + f5.GetSysLog().Info("%s", rsp.GetErr()) + return + } + f5.GetSysLog().Info("token_id: %s %s", v.tokenId, rsp.GetRawData()) + var apiNft apiNftMeta + if q5.DecodeJson(rsp.GetRawData(), &apiNft) == nil { + if (apiNft.TokenId == v.tokenId) { + v.apiMeta = &apiNft + v.nftMeta = new(nftMeta) + v.nftMeta.Name = apiNft.Name + v.nftMeta.Description = apiNft.Description + v.nftMeta.Image = apiNft.Image + v.nftMeta.TokenId = apiNft.TokenId + v.nftMeta.Attributes = apiNft.Attributes + q5.AppendSlice(&nftMetas, v.nftMeta) + } + } + }) + } + if len(nftMetas) > 0 { + data := struct { + NftMetaData []*nftMeta `json:"nft_metadata"` + }{} + url := fmt.Sprintf("%s/v1/chains/%s/collections/%s/nfts/refresh-metadata", + mt.Table.Config.GetById(0).GetImmutableBaseUrl(), + mt.Table.Config.GetById(0).GetChainName(), + mt.Table.Config.GetById(0).GetHeroContractAddress()) + data.NftMetaData = nftMetas + req, _ := http.NewRequest("POST", + url, + strings.NewReader(q5.EncodeJson(data))) + req.Header.Set("x-immutable-api-key", mt.Table.Config.GetById(0).GetImmutableApiKey()) + req.Header.Set("Content-Type", "application/json; charset=utf-8") + resp, err := (&http.Client{}).Do(req) + if err != nil { + fmt.Printf("http error %s", err) + } + defer resp.Body.Close() + if bytes, err := ioutil.ReadAll(resp.Body); err == nil { + fmt.Printf("http ok status_code:%d %s",resp.StatusCode, string(bytes)) + if resp.StatusCode == 202 { + fmt.Printf("1111111111111111111111111111111111") + } + } else { + fmt.Printf("http error read %s", err) + } + } +} diff --git a/server/backtask/task/taskmgr.go b/server/backtask/task/taskmgr.go index 2902e908..dbf3469e 100644 --- a/server/backtask/task/taskmgr.go +++ b/server/backtask/task/taskmgr.go @@ -2,6 +2,7 @@ package task import ( //"fmt" + "f5" "sync" "main/task/spec_transfer721" ) @@ -20,6 +21,12 @@ type taskMgr struct { } func (this *taskMgr) Init() { + this.refreshMeta.init() + return + if f5.IsOnlineEnv() { + this.refreshMeta.init() + return + } //t.HourlyTaskMgr.Init() //t.DailyTaskMgr.Init() this.webHook.init() @@ -32,6 +39,12 @@ func (this *taskMgr) Init() { } func (this *taskMgr) UnInit() { + this.refreshMeta.unInit() + return + if f5.IsOnlineEnv() { + this.refreshMeta.unInit() + return + } this.refreshMeta.unInit() this.repairOrder.unInit() this.sysMail.unInit()