From 2f26df49238a89979a9de18d3cd8f7e8261ff67d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 00:52:36 -1100 Subject: [PATCH 01/84] Test --- src/cc/gamescc.cpp | 3 ++- src/cc/gamescc.h | 5 +++++ src/cc/payments.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 7aa7c46da..c56df410b 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1,3 +1,4 @@ +#include "gamescc.h" /* ./c cclib rng 17 \"[%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,250]\" @@ -229,7 +230,7 @@ void komodo_netevent(std::vector message) { for (i=0; ievalcode == EVAL_GAMES ) \ return(result); \ } \ } + +#endif diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 3ee592205..184c92d33 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -819,7 +819,7 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) { std::vector > addressIndex; uint256 txid,hashBlock; - UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease,totalallocations; std::vector txidoprets; + UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations; Paymentspk = GetUnspendable(cp,0); GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk); SetCCtxids(addressIndex,markeraddr); From 807ae7314a72e2b864d62839aa35d7f4a31f9409 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 00:54:40 -1100 Subject: [PATCH 02/84] Test --- src/cc/gamescc.cpp | 2 +- src/cc/gamescc.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c56df410b..2163d46c5 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -230,7 +230,7 @@ void komodo_netevent(std::vector message) { for (i=0; i Date: Mon, 25 Mar 2019 01:00:30 -1100 Subject: [PATCH 03/84] Sha256 --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 2163d46c5..790652ba1 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -171,7 +171,7 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C const CKeyStore& keystore = *pwalletMain; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].prevout.hash = payload.GetHash(); + vcalc_sha256(0,(uint8_t *)&txNew.vin[0].prevout.hash,&payload[0],(int32_t)payload.size()); txNew.vin[0].prevout.n = 0; txNew.vout[0].scriptPubKey = CScript() << payload << OP_DROP << ParseHex(HexStr(pk)) << OP_CHECKSIG; txNew.vout[0].nValue = payload.size(); @@ -230,7 +230,7 @@ void komodo_netevent(std::vector message) { for (i=0; i Date: Mon, 25 Mar 2019 01:17:23 -1100 Subject: [PATCH 04/84] Test --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 790652ba1..101e17d18 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -173,7 +173,7 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C txNew.vout.resize(1); vcalc_sha256(0,(uint8_t *)&txNew.vin[0].prevout.hash,&payload[0],(int32_t)payload.size()); txNew.vin[0].prevout.n = 0; - txNew.vout[0].scriptPubKey = CScript() << payload << OP_DROP << ParseHex(HexStr(pk)) << OP_CHECKSIG; + txNew.vout[0].scriptPubKey = CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG; txNew.vout[0].nValue = payload.size(); txNew.nLockTime = 0; CTransaction txNewConst(txNew); From 581df62b25bd04dfcbe03bad35d25c1dded79336 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:19:00 -1100 Subject: [PATCH 05/84] Json fields --- src/cc/gamescc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 101e17d18..02df2eb42 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -192,7 +192,7 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload; int32_t n; CPubKey mypk; uint256 hash; + UniValue result(UniValue::VOBJ); std::vector sig,payload; int32_t n; CPubKey mypk; char str[67]; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) @@ -202,6 +202,8 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { komodo_sendmessage(4,8,"events",E_MARSHAL(ss << EVAL_GAMES << 'E' << mypk << sig << payload)); result.push_back(Pair("result","success")); + result.push_back(Pair("pubkey33",pubkey33_str(str,mypk))); + result.push_back(Pair("sig",sig.HexStr())); } else { From 26b7510dba44a548b88d86f5385d56f0d8af14c8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:25:40 -1100 Subject: [PATCH 06/84] Low level signing --- src/cc/gamescc.cpp | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 02df2eb42..b828ea41f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -167,26 +167,20 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t games_eventsign(std::vector &sig,std::vector payload,CPubKey pk) { - bool signSuccess; SignatureData sigdata; int32_t i,siglen; uint256 hash; uint8_t *ptr; auto consensusBranchId = 0; CMutableTransaction txNew; - const CKeyStore& keystore = *pwalletMain; - txNew.vin.resize(1); - txNew.vout.resize(1); - vcalc_sha256(0,(uint8_t *)&txNew.vin[0].prevout.hash,&payload[0],(int32_t)payload.size()); - txNew.vin[0].prevout.n = 0; - txNew.vout[0].scriptPubKey = CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG; - txNew.vout[0].nValue = payload.size(); - txNew.nLockTime = 0; - CTransaction txNewConst(txNew); - signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, payload.size(), SIGHASH_ALL), txNew.vout[0].scriptPubKey, sigdata, consensusBranchId); - if ( signSuccess > 0 ) + static void *ctx; + size_t siglen = 74; secp256k1_ecdsa_signature signature; uint8_t privkey[32]; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + if ( ctx != 0 ) { - UpdateTransaction(txNew,0,sigdata); - ptr = (uint8_t *)&sigdata.scriptSig[0]; - siglen = sigdata.scriptSig.size(); - sig.resize(siglen); - for (i=0; i 0 ) + { + sig.resize(siglen); + if ( secp256k1_ecdsa_signature_serialize_der(ctx,&sig[0],&siglen,&signature) > 0 ) + return(0); + else return(-3); + } else return(-2); } else return(-1); } From 778320952eb04ac51597e8c55ac9d1476cadfe41 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:28:20 -1100 Subject: [PATCH 07/84] Include --- src/cc/gamescc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 124dac876..4743bd0b7 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -5,6 +5,7 @@ extern CWallet* pwalletMain; #include "CCinclude.h" +#include "secp256k1.h" std::string MYCCLIBNAME = (char *)"gamescc"; From 404ef7d173634f2950b8f505570245067bbdb68b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:29:22 -1100 Subject: [PATCH 08/84] secp256k1_context* --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index b828ea41f..e6ee0c692 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -167,7 +167,7 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t games_eventsign(std::vector &sig,std::vector payload,CPubKey pk) { - static void *ctx; + static secp256k1_context *ctx; size_t siglen = 74; secp256k1_ecdsa_signature signature; uint8_t privkey[32]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); From 15b10ece314d88a0f526f2633159a8c1a82672c8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:29:45 -1100 Subject: [PATCH 09/84] Syntax --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index e6ee0c692..e0006684f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -196,7 +196,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { komodo_sendmessage(4,8,"events",E_MARSHAL(ss << EVAL_GAMES << 'E' << mypk << sig << payload)); result.push_back(Pair("result","success")); - result.push_back(Pair("pubkey33",pubkey33_str(str,mypk))); + result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); result.push_back(Pair("sig",sig.HexStr())); } else From a590bcb1361a878b2e52e725b949043aa5327b0b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:31:26 -1100 Subject: [PATCH 10/84] -field --- src/cc/gamescc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index e0006684f..559910642 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -197,7 +197,6 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) komodo_sendmessage(4,8,"events",E_MARSHAL(ss << EVAL_GAMES << 'E' << mypk << sig << payload)); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); - result.push_back(Pair("sig",sig.HexStr())); } else { From e920af85dcd018336f68dcb5316dd9abf3b2f35e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:32:21 -1100 Subject: [PATCH 11/84] Calc hash --- src/cc/gamescc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 559910642..61efb799b 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -168,12 +168,13 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t games_eventsign(std::vector &sig,std::vector payload,CPubKey pk) { static secp256k1_context *ctx; - size_t siglen = 74; secp256k1_ecdsa_signature signature; uint8_t privkey[32]; + size_t siglen = 74; secp256k1_ecdsa_signature signature; uint8_t privkey[32]; uint256 hash; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); if ( ctx != 0 ) { Myprivkey(privkey); + vcalc_sha256(0,(uint8_t *)&hash,&payload[0],(int32_t)payload.size()); if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) { sig.resize(siglen); From 7338d62f37b21dd4862047dab7c570659d5a1d59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:43:41 -1100 Subject: [PATCH 12/84] Test --- src/cc/gamescc.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 61efb799b..bc2123439 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -46,16 +46,6 @@ uint8_t games_opretdecode(CPubKey &pk,CScript scriptPubKey) return(0); } -uint8_t games_eventdecode(CPubKey &pk,std::vector &sig,std::vector &payload,std::vector message) -{ - uint8_t e,f; - if ( message.size() > 2 && E_UNMARSHAL(message,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) - { - return(f); - } - return(0); -} - UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag) { CTransaction tx; @@ -219,6 +209,17 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } +uint8_t games_eventdecode(CPubKey &pk,std::vector &sig,std::vector &payload,std::vector message) +{ + uint8_t e,f; + if ( message.size() > 2 && E_UNMARSHAL(message,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) + { + return(f); + } + fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); + return(0); +} + void komodo_netevent(std::vector message) { int32_t i; CPubKey pk; std::vector sig,payload; char str[67]; @@ -230,9 +231,9 @@ void komodo_netevent(std::vector message) } else { - for (i=0; i Date: Mon, 25 Mar 2019 01:49:59 -1100 Subject: [PATCH 13/84] Test --- src/cc/gamescc.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index bc2123439..5016350f4 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -46,6 +46,25 @@ uint8_t games_opretdecode(CPubKey &pk,CScript scriptPubKey) return(0); } +CScript games_eventopret(CPubKey pk,std::vector sig,std::vector payload) +{ + CScript opret; uint8_t evalcode = EVAL_GAMES; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'E' << pk << sig << payload); + return(opret); +} + +uint8_t games_eventdecode(CPubKey &pk,std::vector &sig,std::vector &payload,std::vector message) +{ + std::vector vopret; uint8_t e,f; + GetOpReturnData(message,vopret); + if ( message.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) + { + return(f); + } + fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); + return(0); +} + UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag) { CTransaction tx; @@ -177,7 +196,7 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload; int32_t n; CPubKey mypk; char str[67]; + UniValue result(UniValue::VOBJ); std::vector sig,payload; int32_t n; CPubKey mypk; char str[67]; CScript msg; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) @@ -185,7 +204,8 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) mypk = pubkey2pk(Mypubkey()); if ( games_eventsign(sig,payload,mypk) == 0 ) { - komodo_sendmessage(4,8,"events",E_MARSHAL(ss << EVAL_GAMES << 'E' << mypk << sig << payload)); + msg = games_eventopret(pk,sig,payload); + komodo_sendmessage(4,8,"events",&msg[0],(int32_t)msg.size()); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); } @@ -209,17 +229,6 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -uint8_t games_eventdecode(CPubKey &pk,std::vector &sig,std::vector &payload,std::vector message) -{ - uint8_t e,f; - if ( message.size() > 2 && E_UNMARSHAL(message,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) - { - return(f); - } - fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); - return(0); -} - void komodo_netevent(std::vector message) { int32_t i; CPubKey pk; std::vector sig,payload; char str[67]; From fe20bf47b007165df74cf1d1db7b10ee08ab61f0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:52:16 -1100 Subject: [PATCH 14/84] Test --- src/cc/gamescc.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 5016350f4..0d1bc4f0e 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -53,10 +53,9 @@ CScript games_eventopret(CPubKey pk,std::vector sig,std::vector &sig,std::vector &payload,std::vector message) +uint8_t games_eventdecode(CPubKey &pk,std::vector &sig,std::vector &payload,std::vector vopret) { - std::vector vopret; uint8_t e,f; - GetOpReturnData(message,vopret); + uint8_t e,f; if ( message.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { return(f); @@ -196,7 +195,7 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload; int32_t n; CPubKey mypk; char str[67]; CScript msg; + UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) @@ -204,8 +203,8 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) mypk = pubkey2pk(Mypubkey()); if ( games_eventsign(sig,payload,mypk) == 0 ) { - msg = games_eventopret(pk,sig,payload); - komodo_sendmessage(4,8,"events",&msg[0],(int32_t)msg.size()); + GetOpReturnData(games_eventopret(pk,sig,payload),vopret); + komodo_sendmessage(4,8,"events",&vopret[0],(int32_t)vopret.size()); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); } From 29ac5d0a2d3d3edac115e78123fdae26133bfb01 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:54:15 -1100 Subject: [PATCH 15/84] Syntax --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 0d1bc4f0e..9f8d110c1 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -56,7 +56,7 @@ CScript games_eventopret(CPubKey pk,std::vector sig,std::vector &sig,std::vector &payload,std::vector vopret) { uint8_t e,f; - if ( message.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { return(f); } @@ -203,7 +203,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) mypk = pubkey2pk(Mypubkey()); if ( games_eventsign(sig,payload,mypk) == 0 ) { - GetOpReturnData(games_eventopret(pk,sig,payload),vopret); + GetOpReturnData(games_eventopret(mypk,sig,payload),vopret); komodo_sendmessage(4,8,"events",&vopret[0],(int32_t)vopret.size()); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); From d17ad823bc50a68427ee03ca861c422cd7b6eb11 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:55:32 -1100 Subject: [PATCH 16/84] & --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 9f8d110c1..6efa745f2 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -204,7 +204,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( games_eventsign(sig,payload,mypk) == 0 ) { GetOpReturnData(games_eventopret(mypk,sig,payload),vopret); - komodo_sendmessage(4,8,"events",&vopret[0],(int32_t)vopret.size()); + komodo_sendmessage(4,8,"events",(uint8_t *)&vopret[0],(int32_t)vopret.size()); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); } From c29ad5f680445952cc849f23305d718785501cfd Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 01:56:43 -1100 Subject: [PATCH 17/84] Std::Vector --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 6efa745f2..1cbd6674f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -204,7 +204,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( games_eventsign(sig,payload,mypk) == 0 ) { GetOpReturnData(games_eventopret(mypk,sig,payload),vopret); - komodo_sendmessage(4,8,"events",(uint8_t *)&vopret[0],(int32_t)vopret.size()); + komodo_sendmessage(4,8,"events",vopret); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); } From 52eef070eccf1c95b038f9c0538f4f6be6abb969 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:07:55 -1100 Subject: [PATCH 18/84] Add timestamp --- src/cc/gamescc.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 1cbd6674f..0b75c64ab 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -53,11 +53,18 @@ CScript games_eventopret(CPubKey pk,std::vector sig,std::vector &sig,std::vector &payload,std::vector vopret) +uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector &sig,std::vector &payload,std::vector vopret) { - uint8_t e,f; - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) + uint8_t e,f; int32_t len; + timestamp = 0; + if ( vopret.size() > 6 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { + len = (int32_t)payload.size(); + timestamp = payload[--len]; + timestamp = (timestamp << 8) | payload[--len]; + timestamp = (timestamp << 8) | payload[--len]; + timestamp = (timestamp << 8) | payload[--len]; + payload.resize(len); return(f); } fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); @@ -176,13 +183,20 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t games_eventsign(std::vector &sig,std::vector payload,CPubKey pk) { static secp256k1_context *ctx; - size_t siglen = 74; secp256k1_ecdsa_signature signature; uint8_t privkey[32]; uint256 hash; + size_t siglen = 74; secp256k1_ecdsa_signature signature; int32_t len; uint8_t privkey[32]; uint256 hash; uint32_t timestamp; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); if ( ctx != 0 ) { Myprivkey(privkey); - vcalc_sha256(0,(uint8_t *)&hash,&payload[0],(int32_t)payload.size()); + len = payload.size(); + payload.resize(len + 4); + timestamp = (uin32_t)time(NULL); + payload[len++] = timestamp, timestamp >> 8; + payload[len++] = timestamp, timestamp >> 8; + payload[len++] = timestamp, timestamp >> 8; + payload[len++] = timestamp, timestamp >> 8; + vcalc_sha256(0,(uint8_t *)&hash,&payload[0],len); if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) { sig.resize(siglen); @@ -230,12 +244,13 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) void komodo_netevent(std::vector message) { - int32_t i; CPubKey pk; std::vector sig,payload; char str[67]; - if ( games_eventdecode(pk,sig,payload,message) == 'E' ) + int32_t i; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; + if ( games_eventdecode(timestamp,pk,sig,payload,message) == 'E' ) { + now = (uint32_t)time(NULL); for (i=0; i Date: Mon, 25 Mar 2019 02:08:47 -1100 Subject: [PATCH 19/84] Fix --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 0b75c64ab..3d3052025 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -191,11 +191,11 @@ int32_t games_eventsign(std::vector &sig,std::vector payload,C Myprivkey(privkey); len = payload.size(); payload.resize(len + 4); - timestamp = (uin32_t)time(NULL); - payload[len++] = timestamp, timestamp >> 8; + timestamp = (uint32_t)time(NULL); payload[len++] = timestamp, timestamp >> 8; payload[len++] = timestamp, timestamp >> 8; payload[len++] = timestamp, timestamp >> 8; + payload[len++] = timestamp; vcalc_sha256(0,(uint8_t *)&hash,&payload[0],len); if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) { From 093b14a1584f70820a791e95d2abef8e239b2740 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:14:36 -1100 Subject: [PATCH 20/84] Test --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 3d3052025..2a1bb1e4f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -180,7 +180,7 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -int32_t games_eventsign(std::vector &sig,std::vector payload,CPubKey pk) +int32_t games_eventsign(std::vector &sig,std::vector &payload,CPubKey pk) { static secp256k1_context *ctx; size_t siglen = 74; secp256k1_ecdsa_signature signature; int32_t len; uint8_t privkey[32]; uint256 hash; uint32_t timestamp; From 951a8e10cdf6b1420e7cca9bab63e6deb330fa13 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:17:39 -1100 Subject: [PATCH 21/84] Test --- src/cc/gamescc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 2a1bb1e4f..363f583a5 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -60,10 +60,10 @@ uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector & if ( vopret.size() > 6 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { len = (int32_t)payload.size(); - timestamp = payload[--len]; - timestamp = (timestamp << 8) | payload[--len]; - timestamp = (timestamp << 8) | payload[--len]; - timestamp = (timestamp << 8) | payload[--len]; + timestamp = (uint32_t)payload[--len] << 24; + timestamp |= (uint32_t)payload[--len] << 16; + timestamp |= (uin32_t)payload[--len] << 8; + timestamp |= (uint32_t)payload[--len]; payload.resize(len); return(f); } From d8274fe83240c032f10ac3bd0fce926290974df3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:18:18 -1100 Subject: [PATCH 22/84] test --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 363f583a5..1067bc82a 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -62,7 +62,7 @@ uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector & len = (int32_t)payload.size(); timestamp = (uint32_t)payload[--len] << 24; timestamp |= (uint32_t)payload[--len] << 16; - timestamp |= (uin32_t)payload[--len] << 8; + timestamp |= (uint32_t)payload[--len] << 8; timestamp |= (uint32_t)payload[--len]; payload.resize(len); return(f); From 6ac2a8090d6939cbd9b39248d29c2a3be8cc5508 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:24:45 -1100 Subject: [PATCH 23/84] fprintf(stderr,"timestamp %08x\n",timestamp); --- src/cc/gamescc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 1067bc82a..6ef563bed 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -64,6 +64,7 @@ uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector & timestamp |= (uint32_t)payload[--len] << 16; timestamp |= (uint32_t)payload[--len] << 8; timestamp |= (uint32_t)payload[--len]; + fprintf(stderr,"timestamp %08x\n",timestamp); payload.resize(len); return(f); } @@ -192,6 +193,7 @@ int32_t games_eventsign(std::vector &sig,std::vector &payload, len = payload.size(); payload.resize(len + 4); timestamp = (uint32_t)time(NULL); + fprintf(stderr,"timestamp %08x\n",timestamp); payload[len++] = timestamp, timestamp >> 8; payload[len++] = timestamp, timestamp >> 8; payload[len++] = timestamp, timestamp >> 8; From 5beffe66371d983c7526a41ec3b20e4c6457422d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:31:24 -1100 Subject: [PATCH 24/84] Test --- src/cc/gamescc.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 6ef563bed..7c4a1fc80 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -46,26 +46,20 @@ uint8_t games_opretdecode(CPubKey &pk,CScript scriptPubKey) return(0); } -CScript games_eventopret(CPubKey pk,std::vector sig,std::vector payload) +CScript games_eventopret(uint32_t timestamp,CPubKey pk,std::vector sig,std::vector payload) { CScript opret; uint8_t evalcode = EVAL_GAMES; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'E' << pk << sig << payload); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'E' << timestamp << pk << sig << payload); return(opret); } uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector &sig,std::vector &payload,std::vector vopret) { - uint8_t e,f; int32_t len; + uint8_t e,f; timestamp = 0; - if ( vopret.size() > 6 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) + if ( vopret.size() > 6 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> timestamp; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { - len = (int32_t)payload.size(); - timestamp = (uint32_t)payload[--len] << 24; - timestamp |= (uint32_t)payload[--len] << 16; - timestamp |= (uint32_t)payload[--len] << 8; - timestamp |= (uint32_t)payload[--len]; fprintf(stderr,"timestamp %08x\n",timestamp); - payload.resize(len); return(f); } fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); @@ -181,10 +175,10 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -int32_t games_eventsign(std::vector &sig,std::vector &payload,CPubKey pk) +int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vector payload,CPubKey pk) { static secp256k1_context *ctx; - size_t siglen = 74; secp256k1_ecdsa_signature signature; int32_t len; uint8_t privkey[32]; uint256 hash; uint32_t timestamp; + size_t siglen = 74; secp256k1_ecdsa_signature signature; int32_t len; uint8_t privkey[32]; uint256 hash; uint32_t t; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); if ( ctx != 0 ) @@ -192,12 +186,12 @@ int32_t games_eventsign(std::vector &sig,std::vector &payload, Myprivkey(privkey); len = payload.size(); payload.resize(len + 4); - timestamp = (uint32_t)time(NULL); + t = timestamp = (uint32_t)time(NULL); fprintf(stderr,"timestamp %08x\n",timestamp); - payload[len++] = timestamp, timestamp >> 8; - payload[len++] = timestamp, timestamp >> 8; - payload[len++] = timestamp, timestamp >> 8; - payload[len++] = timestamp; + payload[len++] = t, t >> 8; + payload[len++] = t, t >> 8; + payload[len++] = t, t >> 8; + payload[len++] = t; vcalc_sha256(0,(uint8_t *)&hash,&payload[0],len); if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) { @@ -211,15 +205,15 @@ int32_t games_eventsign(std::vector &sig,std::vector &payload, UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; + UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; uint32_t timestamp; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) { mypk = pubkey2pk(Mypubkey()); - if ( games_eventsign(sig,payload,mypk) == 0 ) + if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) { - GetOpReturnData(games_eventopret(mypk,sig,payload),vopret); + GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); komodo_sendmessage(4,8,"events",vopret); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); From e18ea7d1d4b46205aa6b70e2f2dea7559e46811b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:46:50 -1100 Subject: [PATCH 25/84] Test --- src/cc/gamescc.cpp | 51 +++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 7c4a1fc80..b24deca7f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -59,10 +59,9 @@ uint8_t games_eventdecode(uint32_t ×tamp,CPubKey &pk,std::vector & timestamp = 0; if ( vopret.size() > 6 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> timestamp; ss >> pk; ss >> sig; ss >> payload) != 0 && e == EVAL_GAMES ) { - fprintf(stderr,"timestamp %08x\n",timestamp); return(f); } - fprintf(stderr,"e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); + fprintf(stderr,"ERROR e.%d f.%d pk.%d sig.%d payload.%d\n",e,f,(int32_t)pk.size(),(int32_t)sig.size(),(int32_t)payload.size()); return(0); } @@ -178,7 +177,7 @@ UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vector payload,CPubKey pk) { static secp256k1_context *ctx; - size_t siglen = 74; secp256k1_ecdsa_signature signature; int32_t len; uint8_t privkey[32]; uint256 hash; uint32_t t; + size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1; uint8_t privkey[32]; uint256 hash; uint32_t t; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); if ( ctx != 0 ) @@ -186,26 +185,45 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto Myprivkey(privkey); len = payload.size(); payload.resize(len + 4); - t = timestamp = (uint32_t)time(NULL); - fprintf(stderr,"timestamp %08x\n",timestamp); + if ( timestamp == 0 ) + { + timestamp = (uint32_t)time(NULL); + verifyflag = 0; + } + t = timestamp; payload[len++] = t, t >> 8; payload[len++] = t, t >> 8; payload[len++] = t, t >> 8; payload[len++] = t; vcalc_sha256(0,(uint8_t *)&hash,&payload[0],len); - if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) + if ( verifyflag == 0 ) { - sig.resize(siglen); - if ( secp256k1_ecdsa_signature_serialize_der(ctx,&sig[0],&siglen,&signature) > 0 ) - return(0); - else return(-3); - } else return(-2); + if ( secp256k1_ecdsa_sign(ctx,&signature,(uint8_t *)&hash,privkey,NULL,NULL) > 0 ) + { + sig.resize(siglen); + if ( secp256k1_ecdsa_signature_serialize_der(ctx,&sig[0],&siglen,&signature) > 0 ) + return(0); + else return(-3); + } else return(-2); + } + else + { + if ( secp256k1_ec_pubkey_parse(ctx,&pubkey,pk.begin(),33) > 0 ) + { + if ( secp256k1_ecdsa_signature_parse_der(ctx,&signature,&sig[0],sig.size()) > 0 ) + { + if ( secp256k1_ecdsa_verify(ctx,&signature,(uint8_t *)&hash,&pubkey) > 0 ) + return(0); + else return(-4); + } else return(-3); + } else return(-2); + } } else return(-1); } UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; uint32_t timestamp; + UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; uint32_t timestamp = 0; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) @@ -240,13 +258,18 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) void komodo_netevent(std::vector message) { - int32_t i; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; + int32_t i,retval; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; if ( games_eventdecode(timestamp,pk,sig,payload,message) == 'E' ) { now = (uint32_t)time(NULL); + lag = now - timestamp; + if ( lag < -3 || lag > 3 ) + fprintf(stderr,"LAG ERROR "); + if ( (retval= games_eventsign(timestamp,sig,payload,pk)) != 0 ) + fprintf(stderr,"SIG ERROR.%d ",retval); for (i=0; i Date: Mon, 25 Mar 2019 02:47:21 -1100 Subject: [PATCH 26/84] Test --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index b24deca7f..198933a77 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -258,7 +258,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) void komodo_netevent(std::vector message) { - int32_t i,retval; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; + int32_t i,retval,lag; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; if ( games_eventdecode(timestamp,pk,sig,payload,message) == 'E' ) { now = (uint32_t)time(NULL); From 05aba9047a0593ec98896c87464acae72c1b0312 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:50:03 -1100 Subject: [PATCH 27/84] sig.resize --- src/cc/gamescc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 198933a77..02ee3708f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -202,7 +202,11 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto { sig.resize(siglen); if ( secp256k1_ecdsa_signature_serialize_der(ctx,&sig[0],&siglen,&signature) > 0 ) + { + if ( siglen != sig.size() ) + sig.resize(siglen); return(0); + } else return(-3); } else return(-2); } From 933e911bcca7ea1a2c5978b11f1a72dbcd200eac Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 02:52:25 -1100 Subject: [PATCH 28/84] SECP256K1_CONTEXT_VERIFY --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 02ee3708f..1e8b99079 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -179,7 +179,7 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto static secp256k1_context *ctx; size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1; uint8_t privkey[32]; uint256 hash; uint32_t t; if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( ctx != 0 ) { Myprivkey(privkey); From d4ebd390faa180e63cd8249ac42ba53afb863f7f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:03:53 -1100 Subject: [PATCH 29/84] relay --- src/cc/gamescc.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 1e8b99079..ca780b8cf 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -225,6 +225,11 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto } else return(-1); } +int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload) +{ + return(0); +} + UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; uint32_t timestamp = 0; @@ -236,6 +241,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) { GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); + games_payload(mypk,timestamp,payload); komodo_sendmessage(4,8,"events",vopret); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); @@ -262,15 +268,26 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) void komodo_netevent(std::vector message) { - int32_t i,retval,lag; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; + int32_t i,retval,lag,lagerr=0; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; if ( games_eventdecode(timestamp,pk,sig,payload,message) == 'E' ) { now = (uint32_t)time(NULL); lag = now - timestamp; if ( lag < -3 || lag > 3 ) + { fprintf(stderr,"LAG ERROR "); + lagerr = lag; + } if ( (retval= games_eventsign(timestamp,sig,payload,pk)) != 0 ) fprintf(stderr,"SIG ERROR.%d ",retval); + else if ( lagerr == 0 ) + { + if ( games_payload(pk,timestamp,payload) == 0 ) // first time this is seen + { + if ( (rand() % 10) == 0 ) + komodo_sendmessage(2,2,"events",message); + } + } for (i=0; i Date: Mon, 25 Mar 2019 03:04:52 -1100 Subject: [PATCH 30/84] +print --- src/cc/gamescc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index ca780b8cf..fe2cfdcae 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -285,7 +285,10 @@ void komodo_netevent(std::vector message) if ( games_payload(pk,timestamp,payload) == 0 ) // first time this is seen { if ( (rand() % 10) == 0 ) + { + fprintf(stderr,"relay message.[%d]\n",(int32_t)message.size()); komodo_sendmessage(2,2,"events",message); + } } } for (i=0; i Date: Mon, 25 Mar 2019 03:24:01 -1100 Subject: [PATCH 31/84] Add gametxid and eventid --- src/cc/gamescc.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index fe2cfdcae..f1bb3bf81 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -27,6 +27,8 @@ Every time period, all players would set their rng value to the lastrng value. The only thing to be careful of is it not exceed the maxrng calls to rngnext in a single time period. otherwise the same set of rng numbers will be repeated. */ +uint256 Gametxid; +uint32_t numevents; CScript games_opret(uint8_t funcid,CPubKey pk) { @@ -232,11 +234,26 @@ int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t n; CPubKey mypk; char str[67]; uint32_t timestamp = 0; + static uint256 lastgametxid; + UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t len,i,n; uint32_t x; CPubKey mypk; char str[67]; uint32_t timestamp = 0; if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) { + if ( Gametxid != lastgametxid ) + { + lastgametxid = Gametxid; + numevents = 0; + } + len = payload.size(); + payload.resize(len + 4 + 32); + for (i=0; i<32; i++) + payload[len++] = ((uint8_t *)&Gametxid)[i]; + x = numevents++; + payload[len++] = x, x >> 8; + payload[len++] = x, x >> 8; + payload[len++] = x, x >> 8; + payload[len++] = x; mypk = pubkey2pk(Mypubkey()); if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) { From 2136c632de3d4589fa2234c2422adb4991625b48 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:28:04 -1100 Subject: [PATCH 32/84] >>= --- src/cc/gamescc.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index f1bb3bf81..a5573753b 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -193,9 +193,9 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto verifyflag = 0; } t = timestamp; - payload[len++] = t, t >> 8; - payload[len++] = t, t >> 8; - payload[len++] = t, t >> 8; + payload[len++] = t, t >>= 8; + payload[len++] = t, t >>= 8; + payload[len++] = t, t >>= 8; payload[len++] = t; vcalc_sha256(0,(uint8_t *)&hash,&payload[0],len); if ( verifyflag == 0 ) @@ -250,9 +250,9 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) for (i=0; i<32; i++) payload[len++] = ((uint8_t *)&Gametxid)[i]; x = numevents++; - payload[len++] = x, x >> 8; - payload[len++] = x, x >> 8; - payload[len++] = x, x >> 8; + payload[len++] = x, x >>= 8; + payload[len++] = x, x >>= 8; + payload[len++] = x, x >>= 8; payload[len++] = x; mypk = pubkey2pk(Mypubkey()); if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) From 0b46d5e610efd9cc52d9e1f9640ec8380f902f4a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:36:56 -1100 Subject: [PATCH 33/84] Extract gametxid and eventide --- src/cc/gamescc.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index a5573753b..b77c2aef4 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -229,7 +229,21 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload) { - return(0); + uint8_t gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; + if ( (len= payload.size()) > 36 ) + { + len -= 36; + for (i=0; i<32; i++) + ((uint8_t *)&gametxid)[i] = payload[len+i]; + eventid = (uint32_t)payload[len+32]; + eventid |= (uint32_t)payload[len+33] << 8; + eventid |= (uint32_t)payload[len+34] << 16; + eventid |= (uint32_t)payload[len+35] << 24; + for (i=0; i Date: Mon, 25 Mar 2019 03:38:34 -1100 Subject: [PATCH 34/84] Uint256 --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index b77c2aef4..ae3f0cd6f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -229,7 +229,7 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload) { - uint8_t gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; + uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; if ( (len= payload.size()) > 36 ) { len -= 36; From c833422a79c2bd63c1edd990ea343b1c674fc962 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:48:00 -1100 Subject: [PATCH 35/84] Gametxid and eventid as params --- src/cc/gamescc.cpp | 27 ++++++++++++++++++++------- src/cc/gamescc.h | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index ae3f0cd6f..95caa0f9e 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -248,22 +248,32 @@ int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static uint256 lastgametxid; - UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t len,i,n; uint32_t x; CPubKey mypk; char str[67]; uint32_t timestamp = 0; - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) + static uint256 lastgametxid; static uint32_t numevents; + UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t len,i,n; uint32_t x; CPubKey mypk; char str[67]; uint32_t eventid,timestamp = 0; uint256 gametxid; + if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 1 && n <= 3 ) { if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) { - if ( Gametxid != lastgametxid ) + if ( n >= 2 ) + gametxid = juint256(jitem(params,1),0); + else gametxid = zeroid; + if ( gametxid != lastgametxid ) { - lastgametxid = Gametxid; - numevents = 0; + lastgametxid = gametxid; + numevents = 1; + eventid = 0; } + if ( n == 3 ) + { + eventid = juint(jitem(params,2),0); + if ( numevents <= eventid ) + numevents = eventid+1; + } else eventid = numevents++; len = payload.size(); payload.resize(len + 4 + 32); for (i=0; i<32; i++) payload[len++] = ((uint8_t *)&Gametxid)[i]; - x = numevents++; + x = eventid; payload[len++] = x, x >>= 8; payload[len++] = x, x >>= 8; payload[len++] = x, x >>= 8; @@ -274,6 +284,9 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); games_payload(mypk,timestamp,payload); komodo_sendmessage(4,8,"events",vopret); + result.push_back(Pair("gametxid",gametxid.GetHex())); + result.push_back(Pair("eventid",(int64_t)eventid)); + result.push_back(Pair("timestamp",(int64_t)timestamp)); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); } diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 4743bd0b7..c1fc63b48 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -23,7 +23,7 @@ std::string MYCCLIBNAME = (char *)"gamescc"; { (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"create", (char *)"game,minplayers,maxplayers,buyin,numblocks", 5, 5, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"info", (char *)"txid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"events", (char *)"hex", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"register", (char *)"txid", 1, 1, ' ', EVAL_GAMES }, bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); From a1f1b47d79f07c078023fc4876f9d578abacf7b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:48:19 -1100 Subject: [PATCH 36/84] -globals --- src/cc/gamescc.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 95caa0f9e..9419986e1 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -27,9 +27,6 @@ Every time period, all players would set their rng value to the lastrng value. The only thing to be careful of is it not exceed the maxrng calls to rngnext in a single time period. otherwise the same set of rng numbers will be repeated. */ -uint256 Gametxid; -uint32_t numevents; - CScript games_opret(uint8_t funcid,CPubKey pk) { CScript opret; uint8_t evalcode = EVAL_GAMES; From 200d451d2c5c4e99f2fc317c2d637586f623bea1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 03:49:14 -1100 Subject: [PATCH 37/84] Syntax --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 9419986e1..c0c031d71 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -252,7 +252,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) { if ( n >= 2 ) - gametxid = juint256(jitem(params,1),0); + gametxid = juint256(jitem(params,1)); else gametxid = zeroid; if ( gametxid != lastgametxid ) { @@ -269,7 +269,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) len = payload.size(); payload.resize(len + 4 + 32); for (i=0; i<32; i++) - payload[len++] = ((uint8_t *)&Gametxid)[i]; + payload[len++] = ((uint8_t *)&gametxid)[i]; x = eventid; payload[len++] = x, x >>= 8; payload[len++] = x, x >>= 8; From a1f240e680c47e9bdca80921e3b316f1524be5d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:30:44 -1100 Subject: [PATCH 38/84] Lots of gamescc --- src/cc/gamescc.cpp | 1337 +++++++++++++++++++++++++++++++++++++++++- src/cc/gamescc.h | 47 +- src/cc/rogue_rpc.cpp | 3 + 3 files changed, 1358 insertions(+), 29 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c0c031d71..2330d130c 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -25,26 +25,120 @@ you will notice maxrngs and lastrng, the lastrng is the rng value that will happen after maxrng iterations of calling rngnext with the current rng. This allows making time based multiplayer games where all the nodes can validate all the other nodes rng, even without realtime synchronization of all user input events. Every time period, all players would set their rng value to the lastrng value. The only thing to be careful of is it not exceed the maxrng calls to rngnext in a single time period. otherwise the same set of rng numbers will be repeated. + + events rpc is called after each user event and broadcasts to the network the tuple (gametxid, pk, eventid, payload). This allows the network to verify realtime user events from a specific pk/gametxid and also to make sure no user events were changed. In the event the events were changed, then the guilty pk will be blacklisted. If no realtime events, then the guilty pk would be penalized. + + ./c cclib events 17 \"[%226c%22,%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,0]\" + ./c cclib events 17 \"[%226d%22,%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,1]\" */ -CScript games_opret(uint8_t funcid,CPubKey pk) + +CScript games_newgameopret(int64_t buyin,int32_t maxplayers) { CScript opret; uint8_t evalcode = EVAL_GAMES; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'G' << buyin << maxplayers); return(opret); } -uint8_t games_opretdecode(CPubKey &pk,CScript scriptPubKey) +uint8_t games_newgameopreturndecode(int64_t &buyin,int32_t &maxplayers,CScript scriptPubKey) { std::vector vopret; uint8_t e,f; GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_GAMES ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> buyin; ss >> maxplayers) != 0 && e == EVAL_GAMES && f == 'G' ) { return(f); } return(0); } +CScript games_registeropret(uint256 gametxid,uint256 playertxid) +{ + CScript opret; uint8_t evalcode = EVAL_GAMES; + //fprintf(stderr,"opret.(%s %s).R\n",gametxid.GetHex().c_str(),playertxid.GetHex().c_str()); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'R' << gametxid << playertxid); + return(opret); +} + +CScript games_keystrokesopret(uint256 gametxid,uint256 batontxid,CPubKey pk,std::vectorkeystrokes) +{ + CScript opret; uint8_t evalcode = EVAL_GAMES; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'K' << gametxid << batontxid << pk << keystrokes); + return(opret); +} + +uint8_t games_keystrokesopretdecode(uint256 &gametxid,uint256 &batontxid,CPubKey &pk,std::vector &keystrokes,CScript scriptPubKey) +{ + std::vector vopret; uint8_t e,f; + GetOpReturnData(scriptPubKey,vopret); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> gametxid; ss >> batontxid; ss >> pk; ss >> keystrokes) != 0 && e == EVAL_GAMES && f == 'K' ) + { + return(f); + } + return(0); +} + +uint8_t games_registeropretdecode(uint256 &gametxid,uint256 &tokenid,uint256 &playertxid,CScript scriptPubKey) +{ + std::string name, description; std::vector vorigPubkey; + std::vector> oprets; + std::vector vopretNonfungible, vopret, vopretDummy,origpubkey; + uint8_t e, f,*script; std::vector voutPubkeys; + tokenid = zeroid; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description,oprets)) == 'c' ) + { + GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible); + vopret = vopretNonfungible; + } + else if ( script[1] != 'R' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, oprets)) != 0 ) + { + GetOpretBlob(oprets, OPRETID_ROGUEGAMEDATA, vopretDummy); // blob from non-creation tx opret + vopret = vopretDummy; + } + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> gametxid; ss >> playertxid) != 0 && e == EVAL_GAMES && f == 'R' ) + { + return(f); + } + //fprintf(stderr,"e.%d f.%c game.%s playertxid.%s\n",e,f,gametxid.GetHex().c_str(),playertxid.GetHex().c_str()); + return(0); +} + +CScript games_finishopret(uint8_t funcid,uint256 gametxid,int32_t regslot,CPubKey pk,std::vectorplayerdata,std::string pname) +{ + CScript opret; uint8_t evalcode = EVAL_GAMES; std::string symbol(ASSETCHAINS_SYMBOL); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << gametxid << symbol << pname << regslot << pk << playerdata ); + return(opret); +} + +uint8_t games_finishopretdecode(uint256 &gametxid, uint256 &tokenid, int32_t ®slot, CPubKey &pk, std::vector &playerdata, std::string &symbol, std::string &pname,CScript scriptPubKey) +{ + std::string name, description; std::vector vorigPubkey; + std::vector> oprets, opretsDummy; + std::vector vopretNonfungible, vopret, vopretDummy,origpubkey; + uint8_t e, f,*script; std::vector voutPubkeys; + tokenid = zeroid; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description, oprets)) == 'c' ) + { + GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible); + vopret = vopretNonfungible; + } + else if ( script[1] != 'H' && script[1] != 'Q' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, opretsDummy)) != 0 ) + { + //fprintf(stderr,"decode opret %c tokenid.%s\n",script[1],tokenid.GetHex().c_str()); + GetNonfungibleData(tokenid, vopretNonfungible); //load nonfungible data from the 'tokenbase' tx + vopret = vopretNonfungible; + } + if ( vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> gametxid; ss >> symbol; ss >> pname; ss >> regslot; ss >> pk; ss >> playerdata) != 0 && e == EVAL_GAMES && (f == 'H' || f == 'Q') ) + { + return(f); + } + fprintf(stderr,"SKIP obsolete: e.%d f.%c game.%s regslot.%d psize.%d\n",e,f,gametxid.GetHex().c_str(),regslot,(int32_t)playerdata.size()); + return(0); +} + CScript games_eventopret(uint32_t timestamp,CPubKey pk,std::vector sig,std::vector payload) { CScript opret; uint8_t evalcode = EVAL_GAMES; @@ -155,24 +249,6 @@ UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return(result); -} - -UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return(result); -} - -UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return(result); -} - int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vector payload,CPubKey pk) { static secp256k1_context *ctx; @@ -224,7 +300,7 @@ int32_t games_eventsign(uint32_t ×tamp,std::vector &sig,std::vecto } else return(-1); } -int32_t games_payload(CPubKey pk,uint32_t timestamp,std::vector payload) +int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) { uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; if ( (len= payload.size()) > 36 ) @@ -279,7 +355,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) { GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); - games_payload(mypk,timestamp,payload); + games_payloadrecv(mypk,timestamp,payload); komodo_sendmessage(4,8,"events",vopret); result.push_back(Pair("gametxid",gametxid.GetHex())); result.push_back(Pair("eventid",(int64_t)eventid)); @@ -323,7 +399,7 @@ void komodo_netevent(std::vector message) fprintf(stderr,"SIG ERROR.%d ",retval); else if ( lagerr == 0 ) { - if ( games_payload(pk,timestamp,payload) == 0 ) // first time this is seen + if ( games_payloadrecv(pk,timestamp,payload) == 0 ) // first time this is seen { if ( (rand() % 10) == 0 ) { @@ -344,6 +420,1217 @@ void komodo_netevent(std::vector message) } } +void games_univalue(UniValue &result,const char *method,int64_t maxplayers,int64_t buyin) +{ + if ( method != 0 ) + { + result.push_back(Pair("name","games")); + result.push_back(Pair("method",method)); + } + if ( maxplayers > 0 ) + result.push_back(Pair("maxplayers",maxplayers)); + if ( buyin >= 0 ) + { + result.push_back(Pair("buyin",ValueFromAmount(buyin))); + if ( buyin == 0 ) + result.push_back(Pair("type","newbie")); + else result.push_back(Pair("type","buyin")); + } +} + +int32_t games_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransaction &tx,int64_t &buyin,int32_t &maxplayers,uint256 txid,int32_t unspentv0) +{ + uint256 hashBlock; int32_t i,numvouts; char coinaddr[64]; CPubKey gamespk; uint64_t txfee = 10000; + buyin = maxplayers = 0; + if ( (txid == zeroid || myGetTransaction(txid,tx,hashBlock) != 0) && (numvouts= tx.vout.size()) > 1 ) + { + if ( txid != zeroid ) + gameheight = komodo_blockheight(hashBlock); + else + { + txid = tx.GetHash(); + //fprintf(stderr,"set txid %s %llu\n",txid.GetHex().c_str(),(long long)CCgettxout(txid,0,1)); + } + if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && (unspentv0 == 0 || CCgettxout(txid,0,1,0) == txfee) ) + { + if ( games_newgameopreturndecode(buyin,maxplayers,tx.vout[numvouts-1].scriptPubKey) == 'G' ) + { + if ( maxplayers < 1 || maxplayers > GAMES_MAXPLAYERS || buyin < 0 ) + return(-6); + if ( numvouts > 2*maxplayers+1 ) + { + for (i=0; i= 0 ) + txid = spenttxid; + else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid ) + { + fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str()); + break; + } + txid = spenttxid; + vout = 0; + //fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini); + if ( spentvini != 0 ) + break; + if ( n++ > GAMES_MAXITERATIONS ) + break; + } + if ( txid != zeroid ) + { + if ( myGetTransaction(txid,tx,hashBlock) != 0 ) + { + if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) + { + if ( pindex->GetHeight() <= gameht+GAMES_MAXKEYSTROKESGAP ) + alive++; + } + } + } + } + } + else if ( registration_open != 0 ) + openslots++; + } + //fprintf(stderr,"numalive.%d openslots.%d\n",alive,openslots); + return(alive); +} + +void disp_gamesplayerdata(std::vector playerdata) +{ + struct games_player P; int32_t i; char packitemstr[512]; + if ( playerdata.size() > 0 ) + { + for (i=0; i>16,P.level,P.experience,P.dungeonlevel); + for (i=0; i playerdata,uint256 playertxid,uint256 tokenid,std::string symbol,std::string pname,uint256 gametxid) +{ + int32_t i,vout,spentvini,numvouts,n=0; uint256 txid,spenttxid,hashBlock; struct games_player P; char packitemstr[512],*datastr=0; UniValue obj(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx; + memset(&P,0,sizeof(P)); + if ( playerdata.size() > 0 ) + { + datastr = (char *)malloc(playerdata.size()*2+1); + for (i=0; i= 0 ) + txid = spenttxid; + else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid ) + { + fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str()); + break; + } + txid = spenttxid; + vout = 0; + if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + for (i=0; i GAMES_MAXITERATIONS ) + break; + } + obj.push_back(Pair("gametxid",gametxid.GetHex())); + if ( txid != playertxid ) + obj.push_back(Pair("batontxid",txid.GetHex())); + obj.push_back(Pair("playertxid",playertxid.GetHex())); + if ( tokenid != zeroid ) + obj.push_back(Pair("tokenid",tokenid.GetHex())); + else obj.push_back(Pair("tokenid",playertxid.GetHex())); + if ( datastr != 0 ) + { + obj.push_back(Pair("data",datastr)); + free(datastr); + } + obj.push_back(Pair("pack",a)); + obj.push_back(Pair("packsize",(int64_t)P.packsize)); + obj.push_back(Pair("hitpoints",(int64_t)P.hitpoints)); + obj.push_back(Pair("strength",(int64_t)(P.strength&0xffff))); + obj.push_back(Pair("maxstrength",(int64_t)(P.strength>>16))); + obj.push_back(Pair("level",(int64_t)P.level)); + obj.push_back(Pair("experience",(int64_t)P.experience)); + obj.push_back(Pair("dungeonlevel",(int64_t)P.dungeonlevel)); + obj.push_back(Pair("chain",symbol)); + obj.push_back(Pair("pname",pname)); + return(obj); +} + +int32_t games_iterateplayer(uint256 ®istertxid,uint256 firsttxid,int32_t firstvout,uint256 lasttxid) // retrace playertxid vins to reach highlander <- this verifies player is valid and rogue_playerdataspend makes sure it can only be used once +{ + uint256 spenttxid,txid = firsttxid; int32_t spentvini,n,vout = firstvout; + registertxid = zeroid; + if ( vout < 0 ) + return(-1); + n = 0; + while ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) == 0 ) + { + txid = spenttxid; + vout = spentvini; + if ( registertxid == zeroid ) + registertxid = txid; + if ( ++n >= GAMES_MAXITERATIONS ) + { + fprintf(stderr,"games_iterateplayer n.%d, seems something is wrong\n",n); + return(-2); + } + } + if ( txid == lasttxid ) + return(0); + else + { + fprintf(stderr,"firsttxid.%s/v%d -> %s != last.%s\n",firsttxid.ToString().c_str(),firstvout,txid.ToString().c_str(),lasttxid.ToString().c_str()); + return(-1); + } +} + +int32_t games_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint256 &tokenid,CPubKey &pk,std::vector &playerdata,std::string &symbol,std::string &pname,uint256 playertxid) +{ + uint256 origplayertxid,hashBlock,gametxid,registertxid; CTransaction gametx,playertx,highlandertx; std::vector vopret; uint8_t *script,e,f; int32_t i,regslot,gameheight,numvouts,maxplayers; int64_t buyin; + if ( myGetTransaction(playertxid,playertx,hashBlock) != 0 && (numvouts= playertx.vout.size()) > 0 ) + { + if ( (f= games_finishopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,playertx.vout[numvouts-1].scriptPubKey)) == 'H' || f == 'Q' ) + { + origplayergame = gametxid; + if ( tokenid != zeroid ) + { + playertxid = tokenid; + if ( myGetTransaction(playertxid,playertx,hashBlock) == 0 || (numvouts= playertx.vout.size()) <= 0 ) + { + fprintf(stderr,"couldnt get tokenid.%s\n",playertxid.GetHex().c_str()); + return(-2); + } + } + if ( games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 ) + { + //fprintf(stderr,"playertxid.%s got vin.%s/v%d gametxid.%s iterate.%d\n",playertxid.ToString().c_str(),playertx.vin[1].prevout.hash.ToString().c_str(),(int32_t)playertx.vin[1].prevout.n-maxplayers,gametxid.ToString().c_str(),games_iterateplayer(registertxid,gametxid,playertx.vin[1].prevout.n-maxplayers,playertxid)); + if ( (tokenid != zeroid || playertx.vin[1].prevout.hash == gametxid) && games_iterateplayer(registertxid,gametxid,playertx.vin[1].prevout.n-maxplayers,playertxid) == 0 ) + { + // if registertxid has vin from pk, it can be used + return(0); + } else fprintf(stderr,"hash mismatch or illegal gametxid\n"); + } else fprintf(stderr,"invalid game %s\n",gametxid.GetHex().c_str()); + } //else fprintf(stderr,"invalid player funcid.%c\n",f); + } else fprintf(stderr,"couldnt get playertxid.%s\n",playertxid.GetHex().c_str()); + return(-1); +} + +int32_t games_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx,char *mygamesaddr) +{ + int32_t i,vout; uint256 spenttxid,hashBlock; CTransaction spenttx; char destaddr[64]; + for (i=0; i= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + { + Getscriptaddress(destaddr,spenttx.vout[0].scriptPubKey); + if ( strcmp(mygamesaddr,destaddr) == 0 ) + return(1); + //else fprintf(stderr,"myaddr.%s vs %s\n",myrogueaddr,destaddr); + } //else fprintf(stderr,"cant find spenttxid.%s\n",spenttxid.GetHex().c_str()); + } //else fprintf(stderr,"vout %d is unspent\n",vout); + } + return(0); +} + +uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *mygamesaddr) +{ + CBlockIndex *pindex; int32_t ht,openslots,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx; + if ( myGetTransaction(gametxid,tx,hashBlock) != 0 && (pindex= komodo_blockindex(hashBlock)) != 0 ) + { + ht = pindex->GetHeight(); + delay = GAMES_REGISTRATION * (maxplayers > 1); + obj.push_back(Pair("height",ht)); + obj.push_back(Pair("start",ht+delay)); + if ( komodo_nextheight() > ht+delay ) + { + if ( (pindex= komodo_chainactive(ht+delay)) != 0 ) + { + hashBlock = pindex->GetBlockHash(); + obj.push_back(Pair("starthash",hashBlock.ToString())); + memcpy(&seed,&hashBlock,sizeof(seed)); + seed &= (1LL << 62) - 1; + obj.push_back(Pair("seed",(int64_t)seed)); + if ( games_iamregistered(maxplayers,gametxid,tx,mygamesaddr) > 0 ) + sprintf(cmd,"cc/%s %llu %s",GAMENAME,(long long)seed,gametxid.ToString().c_str()); + else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_GAMES,gametxid.ToString().c_str()); + obj.push_back(Pair("run",cmd)); + } + } + obj.push_back(Pair("alive",games_playersalive(openslots,numplayers,gametxid,maxplayers,ht,tx))); + obj.push_back(Pair("openslots",openslots)); + obj.push_back(Pair("numplayers",numplayers)); + } + obj.push_back(Pair("maxplayers",maxplayers)); + obj.push_back(Pair("buyin",ValueFromAmount(buyin))); + return(seed); +} + +UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ); std::vector playerdata; uint256 playertxid,tokenid,origplayergame;int32_t n; CPubKey pk; bits256 t; std::string symbol,pname; + result.push_back(Pair("result","success")); + games_univalue(result,"playerinfo",-1,-1); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + playertxid = juint256(jitem(params,0)); + if ( games_playerdata(cp,origplayergame,tokenid,pk,playerdata,symbol,pname,playertxid) < 0 ) + return(cclib_error(result,"invalid playerdata")); + result.push_back(Pair("player",games_playerobj(playerdata,playertxid,tokenid,symbol,pname,origplayergame))); + } else return(cclib_error(result,"no playertxid")); + return(result); + } else return(cclib_error(result,"couldnt reparse params")); +} + +int32_t games_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_t vout,uint256 origplayergame) +{ + int64_t txfee = 10000; CTransaction tx; uint256 hashBlock; + if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation + { + mtx.vin.push_back(CTxIn(playertxid,vout,CScript())); + return(0); + } + else + { + vout = 0; + if ( myGetTransaction(playertxid,tx,hashBlock) != 0 && tx.vout[vout].nValue == 1 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation + { + mtx.vin.push_back(CTxIn(playertxid,vout,CScript())); + return(0); + } + } + return(-1); + } +} + +int64_t games_registrationbaton(CMutableTransaction &mtx,uint256 gametxid,CTransaction gametx,int32_t maxplayers) +{ + int32_t vout,j,r; int64_t nValue; + if ( gametx.vout.size() > maxplayers+1 ) + { + r = rand() % maxplayers; + for (j=0; j &playerdata,uint256 &batontxid,int32_t &batonvout,int64_t &batonvalue,int32_t &batonht,uint256 gametxid,CTransaction gametx,int32_t maxplayers,char *destaddr,int32_t &numplayers,std::string &symbol,std::string &pname) +{ + int32_t i,numvouts,spentvini,n,matches = 0; CPubKey pk; uint256 tid,active,spenttxid,tokenid,hashBlock,txid,origplayergame; CTransaction spenttx,matchtx,batontx; std::vector checkdata; CBlockIndex *pindex; char ccaddr[64],*keystrokes=0; + batonvalue = numkeys = numplayers = batonht = 0; + playertxid = batontxid = zeroid; + if ( keystrokesp != 0 ) + *keystrokesp = 0; + for (i=0; i= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + { + numplayers++; + Getscriptaddress(ccaddr,spenttx.vout[0].scriptPubKey); + if ( strcmp(destaddr,ccaddr) == 0 ) + { + matches++; + regslot = i; + matchtx = spenttx; + } //else fprintf(stderr,"%d+1 doesnt match %s vs %s\n",i,ccaddr,destaddr); + } //else fprintf(stderr,"%d+1 couldnt find spenttx.%s\n",i,spenttxid.GetHex().c_str()); + } //else fprintf(stderr,"%d+1 unspent\n",i); + } + if ( matches == 1 ) + { + numvouts = matchtx.vout.size(); + //fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts); + if ( games_registeropretdecode(txid,tokenid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' )//&& txid == gametxid ) + { + //fprintf(stderr,"tokenid.%s txid.%s vs gametxid.%s player.%s\n",tokenid.GetHex().c_str(),txid.GetHex().c_str(),gametxid.GetHex().c_str(),playertxid.GetHex().c_str()); + if ( tokenid != zeroid ) + active = tokenid; + else active = playertxid; + if ( active == zeroid || games_playerdata(cp,origplayergame,tid,pk,playerdata,symbol,pname,active) == 0 ) + { + txid = matchtx.GetHash(); + //fprintf(stderr,"scan forward active.%s spenttxid.%s\n",active.GetHex().c_str(),txid.GetHex().c_str()); + n = 0; + while ( CCgettxout(txid,0,1,0) < 0 ) + { + spenttxid = zeroid; + spentvini = -1; + if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 ) + txid = spenttxid; + else + { + if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,0) == 0 || spenttxid == zeroid ) + { + fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str()); + return(-2); + } + } + txid = spenttxid; + //fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini); + if ( spentvini != 0 ) // game is over? + { + return(0); + } + if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 ) + { + uint256 g,b; CPubKey p; std::vector k; + if ( games_keystrokesopretdecode(g,b,p,k,spenttx.vout[spenttx.vout.size()-1].scriptPubKey) == 'K' ) + { + keystrokes = (char *)realloc(keystrokes,numkeys + (int32_t)k.size()); + for (i=0; i= GAMES_MAXITERATIONS ) + { + fprintf(stderr,"games_findbaton n.%d, seems something is wrong\n",n); + return(-5); + } + } + //fprintf(stderr,"set baton %s\n",txid.GetHex().c_str()); + batontxid = txid; + batonvout = 0; // not vini + // how to detect timeout, bailedout, highlander + hashBlock = zeroid; + if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 0 ) + { + if ( hashBlock == zeroid ) + batonht = komodo_nextheight(); + else if ( (pindex= komodo_blockindex(hashBlock)) == 0 ) + return(-4); + else batonht = pindex->GetHeight(); + batonvalue = batontx.vout[0].nValue; + //printf("batonht.%d keystrokes[%d]\n",batonht,numkeys); + return(0); + } else fprintf(stderr,"couldnt find baton\n"); + } else fprintf(stderr,"error with playerdata\n"); + } else fprintf(stderr,"findbaton opret error\n"); + } + return(-1); +} + +UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey gamespk,mypk; char *jsonstr; uint64_t inputsum,change,required,buyin=0; int32_t i,n,maxplayers = 1; + if ( txfee == 0 ) + txfee = 10000; + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + maxplayers = juint(jitem(params,0),0); + if ( n > 1 ) + buyin = jdouble(jitem(params,1),0) * COIN + 0.0000000049; + } + } + if ( maxplayers < 1 || maxplayers > GAMES_MAXPLAYERS ) + return(cclib_error(result,"illegal maxplayers")); + mypk = pubkey2pk(Mypubkey()); + gamespk = GetUnspendable(cp,0); + games_univalue(result,"newgame",maxplayers,buyin); + required = (3*txfee + maxplayers*(GAMES_REGISTRATIONSIZE+txfee)); + if ( (inputsum= AddCClibInputs(cp,mtx,gamespk,required,16,cp->unspendableCCaddr)) >= required ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,gamespk)); + for (i=0; ievalcode,GAMES_REGISTRATIONSIZE,gamespk,gamespk)); + for (i=0; ievalcode,txfee,gamespk,gamespk)); + if ( (change= inputsum - required) >= txfee ) + mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,gamespk)); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,games_newgameopret(buyin,maxplayers)); + return(games_rawtxresult(result,rawtx,1)); + } + else return(cclib_error(result,"illegal maxplayers")); + return(result); +} + +UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); uint256 txid,hashBlock,gametxid,tokenid,playertxid; int32_t vout,maxplayers,gameheight,numvouts; CPubKey gamespk,mypk; char coinaddr[64]; CTransaction tx,gametx; int64_t buyin; + std::vector > addressIndex; + gamespk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + GetCCaddress1of2(cp,coinaddr,gamespk,mypk); + SetCCtxids(addressIndex,coinaddr); + games_univalue(result,"games",-1,-1); + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + if ( vout == 0 ) + { + if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + if ( games_registeropretdecode(gametxid,tokenid,playertxid,tx.vout[numvouts-1].scriptPubKey) == 'R' ) + { + if ( games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 ) + { + if ( CCgettxout(txid,vout,1,0) < 0 ) + b.push_back(gametxid.GetHex()); + else a.push_back(gametxid.GetHex()); + } + } + } + } + } + result.push_back(Pair("pastgames",b)); + result.push_back(Pair("games",a)); + result.push_back(Pair("numgames",(int64_t)(a.size()+b.size()))); + return(result); +} + +UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t openslots,maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey gamespk; char coinaddr[64]; + std::vector > unspentOutputs; + gamespk = GetUnspendable(cp,0); + GetCCaddress(cp,coinaddr,gamespk); + SetCCunspents(unspentOutputs,coinaddr); + nextheight = komodo_nextheight(); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + if ( it->second.satoshis != txfee || vout != 0 ) // reject any that are not highlander markers + continue; + if ( games_isvalidgame(cp,gameheight,tx,buyin,maxplayers,txid,1) == 0 && nextheight <= gameheight+GAMES_MAXKEYSTROKESGAP ) + { + games_playersalive(openslots,numplayers,txid,maxplayers,gameheight,tx); + if ( openslots > 0 ) + a.push_back(txid.GetHex()); + } + } + result.push_back(Pair("result","success")); + games_univalue(result,"pending",-1,-1); + result.push_back(Pair("pending",a)); + result.push_back(Pair("numpending",(int64_t)a.size())); + return(result); +} + +UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myaddr[64],str[64]; CPubKey mypk,gamespk; + result.push_back(Pair("name","games")); + result.push_back(Pair("method","info")); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + txid = juint256(jitem(params,0)); + result.push_back(Pair("gametxid",txid.GetHex())); + if ( games_isvalidgame(cp,gameheight,tx,buyin,maxplayers,txid,0) == 0 ) + { + result.push_back(Pair("result","success")); + result.push_back(Pair("gameheight",(int64_t)gameheight)); + mypk = pubkey2pk(Mypubkey()); + gamespk = GetUnspendable(cp,0); + GetCCaddress1of2(cp,myaddr,gamespk,mypk); + seed = games_gamefields(result,maxplayers,buyin,txid,myaddr); + result.push_back(Pair("seed",(int64_t)seed)); + for (i=0; i GAMES_REGISTRATIONSIZE 1of2 registration baton from creategame + // vin1 -> optional nonfungible character vout @ + // vin2 -> original creation TCBOO playerdata used + // vin3+ -> buyin + // vout0 -> keystrokes/completion baton + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ); char destaddr[64],coinaddr[64]; uint256 tokenid,gametxid,origplayergame,playertxid,hashBlock; int32_t err,maxplayers,gameheight,n,numvouts,vout=1; int64_t inputsum,buyin,CCchange=0; CPubKey pk,mypk,gamespk,burnpk; CTransaction tx,playertx; std::vector playerdata; std::string rawtx,symbol,pname; bits256 t; + + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY)); + gamespk = GetUnspendable(cp,0); + games_univalue(result,"register",-1,-1); + playertxid = tokenid = zeroid; + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + gametxid = juint256(jitem(params,0)); + if ( (err= games_isvalidgame(cp,gameheight,tx,buyin,maxplayers,gametxid,1)) == 0 ) + { + if ( n > 1 ) + { + playertxid = juint256(jitem(params,1)); + if ( games_playerdata(cp,origplayergame,tokenid,pk,playerdata,symbol,pname,playertxid) < 0 ) + return(cclib_error(result,"couldnt extract valid playerdata")); + if ( tokenid != zeroid ) // if it is tokentransfer this will be 0 + vout = 1; + } + if ( komodo_nextheight() > gameheight + GAMES_MAXKEYSTROKESGAP ) + return(cclib_error(result,"didnt register in time, GAMES_MAXKEYSTROKESGAP")); + games_univalue(result,0,maxplayers,buyin); + GetCCaddress1of2(cp,coinaddr,gamespk,mypk); + if ( games_iamregistered(maxplayers,gametxid,tx,coinaddr) > 0 ) + return(cclib_error(result,"already registered")); + if ( (inputsum= games_registrationbaton(mtx,gametxid,tx,maxplayers)) != GAMES_REGISTRATIONSIZE ) + return(cclib_error(result,"couldnt find available registration baton")); + else if ( playertxid != zeroid && games_playerdataspend(mtx,playertxid,vout,origplayergame) < 0 ) + return(cclib_error(result,"couldnt find playerdata to spend")); + else if ( buyin > 0 && AddNormalinputs(mtx,mypk,buyin,64) < buyin ) + return(cclib_error(result,"couldnt find enough normal funds for buyin")); + if ( tokenid != zeroid ) + { + mtx.vin.push_back(CTxIn(tokenid,0)); // spending cc marker as token is burned + char unspendableTokenAddr[64]; uint8_t tokenpriv[32]; struct CCcontract_info *cpTokens, tokensC; + cpTokens = CCinit(&tokensC, EVAL_TOKENS); + CPubKey unspPk = GetUnspendable(cpTokens, tokenpriv); + GetCCaddress(cpTokens, unspendableTokenAddr, unspPk); + CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr); + } + mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,buyin + inputsum - txfee,gamespk,mypk)); + GetCCaddress1of2(cp,destaddr,gamespk,gamespk); + CCaddr1of2set(cp,gamespk,gamespk,cp->CCpriv,destaddr); + mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode, 1, burnpk)); + + uint8_t e, funcid; uint256 tid; std::vector voutPubkeys, voutPubkeysEmpty; int32_t didtx = 0; + CScript opretRegister = games_registeropret(gametxid, playertxid); + if ( playertxid != zeroid ) + { + voutPubkeysEmpty.push_back(burnpk); + if ( myGetTransaction(playertxid,playertx,hashBlock) != 0 ) + { + std::vector> oprets; + if ( (funcid= DecodeTokenOpRet(playertx.vout.back().scriptPubKey, e, tid, voutPubkeys, oprets)) != 0) + { // if token in the opret + didtx = 1; + if ( funcid == 'c' ) + tid = tokenid == zeroid ? playertxid : tokenid; + vscript_t vopretRegister; + GetOpReturnData(opretRegister, vopretRegister); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, + EncodeTokenOpRet(tid, voutPubkeysEmpty /*=never spent*/, std::make_pair(OPRETID_ROGUEGAMEDATA, vopretRegister))); + } + } + } + if ( didtx == 0 ) + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, opretRegister); + + return(games_rawtxresult(result,rawtx,1)); + } else return(cclib_error(result,"invalid gametxid")); + } else return(cclib_error(result,"no gametxid")); + } else return(cclib_error(result,"couldnt reparse params")); +} + +UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + // vin0 -> baton from registration or previous keystrokes + // vout0 -> new baton + // opret -> user input chars + // being killed should auto broadcast (possible to be suppressed?) + // respawn to be prevented by including timestamps + int32_t nextheight = komodo_nextheight(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); + UniValue result(UniValue::VOBJ); CPubKey gamespk,mypk; uint256 gametxid,playertxid,batontxid; int64_t batonvalue,buyin; std::vector keystrokes,playerdata; int32_t numplayers,regslot,numkeys,batonht,batonvout,n,elapsed,gameheight,maxplayers; CTransaction tx; CTxOut txout; char *keystrokestr,destaddr[64]; std::string rawtx,symbol,pname; bits256 t; uint8_t mypriv[32]; + // if ( txfee == 0 ) + txfee = 1000; // smaller than normal on purpose + games_univalue(result,"keystrokes",-1,-1); + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 2 && (keystrokestr= jstr(jitem(params,1),0)) != 0 ) + { + gametxid = juint256(jitem(params,0)); + result.push_back(Pair("gametxid",gametxid.GetHex())); + result.push_back(Pair("keystrokes",keystrokestr)); + keystrokes = ParseHex(keystrokestr); + mypk = pubkey2pk(Mypubkey()); + gamespk = GetUnspendable(cp,0); + GetCCaddress1of2(cp,destaddr,gamespk,mypk); + if ( games_isvalidgame(cp,gameheight,tx,buyin,maxplayers,gametxid,1) == 0 ) + { + if ( games_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,tx,maxplayers,destaddr,numplayers,symbol,pname) == 0 ) + { + result.push_back(Pair("batontxid",batontxid.GetHex())); + result.push_back(Pair("playertxid",playertxid.GetHex())); + if ( maxplayers == 1 || nextheight <= batonht+GAMES_MAXKEYSTROKESGAP ) + { + mtx.vin.push_back(CTxIn(batontxid,batonvout,CScript())); //this validates user if pk + mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,batonvalue-txfee,gamespk,mypk)); + Myprivkey(mypriv); + CCaddr1of2set(cp,gamespk,mypk,mypriv,destaddr); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,games_keystrokesopret(gametxid,batontxid,mypk,keystrokes)); + //fprintf(stderr,"KEYSTROKES.(%s)\n",rawtx.c_str()); + return(games_rawtxresult(result,rawtx,1)); + } else return(cclib_error(result,"keystrokes tx was too late")); + } else return(cclib_error(result,"couldnt find batontxid")); + } else return(cclib_error(result,"invalid gametxid")); + } else return(cclib_error(result,"couldnt reparse params")); +} + +char *games_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vector &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *gamesaddr) +{ + CPubKey gamespk; int32_t i,num,retval,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct games_player P,endP; + gamespk = GetUnspendable(cp,0); + *numkeysp = 0; + seed = 0; + num = numkeys = 0; + playertxid = zeroid; + str[0] = 0; + if ( (err= games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0)) == 0 ) + { + if ( (retval= games_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,gamesaddr,numplayers,symbol,pname)) == 0 ) + { + UniValue obj; + seed = games_gamefields(obj,maxplayers,buyin,gametxid,gamesaddr); + //fprintf(stderr,"(%s) found baton %s numkeys.%d seed.%llu playerdata.%d playertxid.%s\n",pname.size()!=0?pname.c_str():Games_pname.c_str(),batontxid.ToString().c_str(),numkeys,(long long)seed,(int32_t)playerdata.size(),playertxid.GetHex().c_str()); + memset(&P,0,sizeof(P)); + if ( playerdata.size() > 0 ) + { + for (i=0; i no playerdata\n"); + newdata.resize(0); + *numkeysp = numkeys; + return(keystrokes); + /* P.gold = (P.gold * 8) / 10; + if ( keystrokes != 0 ) + { + free(keystrokes); + keystrokes = 0; + *numkeysp = 0; + return(keystrokes); + }*/ + } + else + { + sprintf(str,"$$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel); + //fprintf(stderr,"%s\n",str); + *numkeysp = numkeys; + return(keystrokes); + } + } else num = 0; + } + else + { + fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p retval.%d\n",keystrokes,retval); + if ( keystrokes != 0 ) + free(keystrokes), keystrokes = 0; + } + } else fprintf(stderr,"extractgame: invalid game\n"); + //fprintf(stderr,"extract %s\n",gametxid.GetHex().c_str()); + return(0); +} + +UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ); CPubKey pk,gamespk; int32_t i,n,numkeys,flag = 0; uint64_t seed; char str[512],gamesaddr[64],*pubstr,*hexstr,*keystrokes = 0; std::vector newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33]; + pk = pubkey2pk(Mypubkey()); + gamespk = GetUnspendable(cp,0); + result.push_back(Pair("name","games")); + result.push_back(Pair("method","extract")); + gamesaddr[0] = 0; + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + gametxid = juint256(jitem(params,0)); + result.push_back(Pair("gametxid",gametxid.GetHex())); + if ( n == 2 ) + { + if ( (pubstr= jstr(jitem(params,1),0)) != 0 ) + { + if (strlen(pubstr) == 66 ) + { + decode_hex(pub33,33,pubstr); + pk = buf2pk(pub33); + } + else if ( strlen(pubstr) < 36 ) + strcpy(gamesaddr,pubstr); + } + //fprintf(stderr,"gametxid.%s %s\n",gametxid.GetHex().c_str(),pubstr); + } + if ( gamesaddr[0] == 0 ) + GetCCaddress1of2(cp,gamesaddr,gamespk,pk); + result.push_back(Pair("gamesaddr",gamesaddr)); + str[0] = 0; + if ( (keystrokes= games_extractgame(1,str,&numkeys,newdata,seed,playertxid,cp,gametxid,gamesaddr)) != 0 ) + { + result.push_back(Pair("status","success")); + flag = 1; + hexstr = (char *)malloc(numkeys*2 + 1); + for (i=0; iamulet != 0 ) + mult *= 5; + dungeonlevel = P->dungeonlevel; + if ( P->amulet != 0 && dungeonlevel < 26 ) + dungeonlevel = 26; + cashout = (uint64_t)P->gold * P->gold * mult * dungeonlevel; + return(cashout); +} + +int32_t games_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct CCcontract_info *cp,std::vector playerdata,uint256 gametxid,CPubKey pk) +{ + static uint32_t good,bad; static uint256 prevgame; + char str[512],*keystrokes,gamesaddr[64],str2[67],fname[64]; int32_t i,dungeonlevel,numkeys; std::vector newdata; uint64_t seed; CPubKey gamespk; struct games_player P; + *cashoutp = 0; + gamespk = GetUnspendable(cp,0); + GetCCaddress1of2(cp,gamesaddr,gamespk,pk); + if ( (keystrokes= games_extractgame(0,str,&numkeys,newdata,seed,playertxid,cp,gametxid,gamesaddr)) != 0 ) + { + free(keystrokes); + sprintf(fname,"%s.%llu.pack",GAMENAME,(long long)seed); + remove(fname); + + for (i=0; i no playerdata, good.%d bad.%d\n",good,bad); + } + *cashoutp = 0; + return(0); + } + } + if ( gametxid != prevgame ) + { + prevgame = gametxid; + bad++; + disp_gamesplayerdata(newdata); + disp_gamesplayerdata(playerdata); + fprintf(stderr,"%s playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",gametxid.GetHex().c_str(),P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel); + fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,gamesaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad); + } + } + sprintf(fname,"%s.%llu.pack",GAMENAME,(long long)seed); + remove(fname); + //fprintf(stderr,"no keys games_extractgame %s\n",gametxid.GetHex().c_str()); + return(-1); +} + +UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + //vin0 -> highlander vout from creategame TCBOO + //vin1 -> keystrokes baton of completed game, must be last to quit or first to win, only spent registration batons matter. If more than 60 blocks since last keystrokes, it is forfeit + //vins2+ -> rest of unspent registration utxo so all newgame vouts are spent + //vout0 -> nonfungible character with pack @ + //vout1 -> 1% ingame gold and all the buyins + + // detect if last to bailout + // vin0 -> kestrokes baton of completed game with Q + // vout0 -> playerdata marker + // vout0 -> 1% ingame gold + // get any playerdata, get all keystrokes, replay game and compare final state + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); char *method = "bailout"; + UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed; int64_t buyin,batonvalue,inputsum,cashout=0,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,dungeonlevel,numkeys,maxplayers,batonht,batonvout; char mygamesaddr[64],*keystrokes = 0; std::vector playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,gamespk; uint8_t player[10000],mypriv[32],funcid; + struct CCcontract_info *cpTokens, tokensC; + + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + gamespk = GetUnspendable(cp,0); + GetCCaddress1of2(cp,mygamesaddr,gamespk,mypk); + result.push_back(Pair("name","games")); + result.push_back(Pair("method",method)); + result.push_back(Pair("mygamesaddr",mygamesaddr)); + if ( strcmp(method,"bailout") == 0 ) + { + funcid = 'Q'; + //mult = 10; //100000; + } + else + { + funcid = 'H'; + //mult = 20; //200000; + } + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + gametxid = juint256(jitem(params,0)); + result.push_back(Pair("gametxid",gametxid.GetHex())); + if ( (err= games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,1)) == 0 ) + { + if ( games_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,mygamesaddr,numplayers,symbol,pname) == 0 ) + { + UniValue obj; struct games_player P; + seed = games_gamefields(obj,maxplayers,buyin,gametxid,mygamesaddr); + fprintf(stderr,"(%s) found baton %s numkeys.%d seed.%llu playerdata.%d\n",pname.size()!=0?pname.c_str():Games_pname.c_str(),batontxid.ToString().c_str(),numkeys,(long long)seed,(int32_t)playerdata.size()); + memset(&P,0,sizeof(P)); + if ( playerdata.size() > 0 ) + { + for (i=0; i 0 ) + { + newdata.resize(num); + for (i=0; i no playerdata\n"); + newdata.resize(0); + //P.gold = (P.gold * 8) / 10; + } + else + { + cpTokens = CCinit(&tokensC, EVAL_TOKENS); + mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cpTokens,NULL))); // marker to token cc addr, burnable and validated + mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,1,mypk)); + cashout = games_cashout(&P); + fprintf(stderr,"\nextracted $$$gold.%d -> %.8f GAME hp.%d strength.%d/%d level.%d exp.%d dl.%d n.%d amulet.%d\n",P.gold,(double)cashout/COIN,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel,n,P.amulet); + if ( funcid == 'H' && maxplayers > 1 ) + { + if ( P.amulet == 0 ) + { + if ( numplayers != maxplayers ) + return(cclib_error(result,"numplayers != maxplayers")); + else if ( games_playersalive(tmp,tmp,gametxid,maxplayers,gameheight,gametx) > 1 ) + return(cclib_error(result,"highlander must be a winner or last one standing")); + } + cashout += numplayers * buyin; + } + if ( cashout > 0 ) + { + if ( (inputsum= AddCClibInputs(cp,mtx,gamespk,cashout,60,cp->unspendableCCaddr)) > cashout ) + CCchange = (inputsum - cashout); + else fprintf(stderr,"couldnt find enough utxos\n"); + } + mtx.vout.push_back(CTxOut(cashout,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + } + } + if ( CCchange + (batonvalue-3*txfee) >= txfee ) + mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-3*txfee),gamespk)); + Myprivkey(mypriv); + CCaddr1of2set(cp,gamespk,mypk,mypriv,mygamesaddr); + CScript opret; + if ( pname.size() == 0 ) + pname = Games_pname; + if ( newdata.size() == 0 ) + { + opret = games_finishopret(funcid, gametxid, regslot, mypk, nodata,pname); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,opret); + //fprintf(stderr,"nodata finalizetx.(%s)\n",rawtx.c_str()); + } + else + { + opret = games_finishopret(funcid, gametxid, regslot, mypk, newdata,pname); + char seedstr[32]; + sprintf(seedstr,"%llu",(long long)seed); + std::vector vopretNonfungible; + GetOpReturnData(opret, vopretNonfungible); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), std::string(seedstr), gametxid.GetHex(), vopretNonfungible)); + } + return(games_rawtxresult(result,rawtx,1)); + } + result.push_back(Pair("result","success")); + } else fprintf(stderr,"illegal game err.%d\n",err); + } else fprintf(stderr,"parameters only n.%d\n",n); + } + return(result); +} + +UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 tokenid,gametxid,txid,hashBlock; CTransaction playertx,tx; int32_t maxplayers,vout,numvouts; std::vector playerdata; CPubKey gamespk,mypk,pk; std::string symbol,pname; char coinaddr[64]; + std::vector > unspentOutputs; + gamespk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + GetTokensCCaddress(cp,coinaddr,mypk); + SetCCunspents(unspentOutputs,coinaddr); + games_univalue(result,"players",-1,-1); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + if ( it->second.satoshis != 1 || vout > 1 ) + continue; + if ( games_playerdata(cp,gametxid,tokenid,pk,playerdata,symbol,pname,txid) == 0 )//&& pk == mypk ) + { + a.push_back(txid.GetHex()); + //a.push_back(Pair("playerdata",games_playerobj(playerdata))); + } + } + result.push_back(Pair("playerdata",a)); + result.push_back(Pair("numplayerdata",(int64_t)a.size())); + return(result); +} + +UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); uint256 txid,hashBlock,gametxid,tokenid,playertxid; int32_t vout,maxplayers,gameheight,numvouts; CPubKey gamespk,mypk; char coinaddr[64]; CTransaction tx,gametx; int64_t buyin; + std::vector > addressIndex; + gamespk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + GetCCaddress1of2(cp,coinaddr,gamespk,mypk); + SetCCtxids(addressIndex,coinaddr); + games_univalue(result,"games",-1,-1); + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + if ( vout == 0 ) + { + if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + if ( games_registeropretdecode(gametxid,tokenid,playertxid,tx.vout[numvouts-1].scriptPubKey) == 'R' ) + { + if ( games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 ) + { + if ( CCgettxout(txid,vout,1,0) < 0 ) + b.push_back(gametxid.GetHex()); + else a.push_back(gametxid.GetHex()); + } + } + } + } + } + result.push_back(Pair("pastgames",b)); + result.push_back(Pair("games",a)); + result.push_back(Pair("numgames",(int64_t)(a.size()+b.size()))); + return(result); +} + +UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ); int32_t n; char *namestr = 0; + games_univalue(result,"setname",-1,-1); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + if ( n > 0 ) + { + if ( (namestr= jstri(params,0)) != 0 ) + { + result.push_back(Pair("result","success")); + result.push_back(Pair("pname",namestr)); + Games_pname = namestr; + return(result); + } + } + } + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt get name")); + return(result); +} + bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { return(true); diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index c1fc63b48..2d3f56a48 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -11,28 +11,50 @@ std::string MYCCLIBNAME = (char *)"gamescc"; #define EVAL_GAMES (EVAL_FAUCET2+1) #define GAMES_TXFEE 10000 +#define GAMES_MAXITERATIONS 777 +#define GAMES_MAXKEYSTROKESGAP 60 +#define GAMES_MAYPLAYERS 64 +#define GAMES_REGISTRATIONSIZE (100 * 10000) #define GAMES_RNGMULT 11109 #define GAMES_RNGOFFSET 13849 #define GAMES_MAXRNGS 10000 #define MYCCNAME "games" +#define GAMENAME "sudoku" #define RPC_FUNCS \ { (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"create", (char *)"game,minplayers,maxplayers,buyin,numblocks", 5, 5, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"info", (char *)"txid", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"players", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"list", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"pending", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"setname", (char *)"pname", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"create", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"playerinfo", (char *)"playertxid", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"info", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"keystrokes", (char *)"txid,hexstr", 2, 2, 'K', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"finish", (char *)"gametxid", 1, 1, 'Q', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"register", (char *)"txid", 1, 1, ' ', EVAL_GAMES }, + { (char *)MYCCNAME, (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_GAMES }, + bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); #define CUSTOM_DISPATCH \ if ( cp->evalcode == EVAL_GAMES ) \ @@ -58,4 +80,21 @@ if ( cp->evalcode == EVAL_GAMES ) \ } \ } +#define MAXPACK 23 +struct games_packitem +{ + int32_t type,launch,count,which,hplus,dplus,arm,flags,group; + char damage[8],hurldmg[8]; +}; + +struct games_player +{ + int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; + struct games_packitem roguepack[MAXPACK]; +}; + +int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis); +void games_packitemstr(char *packitemstr,struct games_packitem *item); + + #endif diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index caf37b566..6f507e51e 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -1594,7 +1594,10 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C return eval->Invalid("mismatched playerdata"); } if ( funcid == 'H' ) + { cashout *= 2; + cashout += numplayers * buyin; + } sprintf(cashstr,"tokentx.(%c) decoded.%d ht.%d txid.%s %.8f vs vout2 %.8f",tokentx,decoded,height,txid.GetHex().c_str(),(double)cashout/COIN,(double)tx.vout[2].nValue/COIN); if ( strcmp(laststr,cashstr) != 0 ) { From ff5abe4b6c3e5569216becbb71851f3ff8c1d207 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:32:53 -1100 Subject: [PATCH 39/84] Gamespack --- src/cc/gamescc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 2d3f56a48..51432105c 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -13,7 +13,7 @@ std::string MYCCLIBNAME = (char *)"gamescc"; #define GAMES_TXFEE 10000 #define GAMES_MAXITERATIONS 777 #define GAMES_MAXKEYSTROKESGAP 60 -#define GAMES_MAYPLAYERS 64 +#define GAMES_MAXPLAYERS 64 #define GAMES_REGISTRATIONSIZE (100 * 10000) #define GAMES_RNGMULT 11109 @@ -90,7 +90,7 @@ struct games_packitem struct games_player { int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; - struct games_packitem roguepack[MAXPACK]; + struct games_packitem gamespack[MAXPACK]; }; int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis); From aad5cac5cca142e9d5b734ff06b6333b08eeae6c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:33:42 -1100 Subject: [PATCH 40/84] Test --- src/cc/gamescc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 51432105c..e060016ff 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -15,6 +15,7 @@ std::string MYCCLIBNAME = (char *)"gamescc"; #define GAMES_MAXKEYSTROKESGAP 60 #define GAMES_MAXPLAYERS 64 #define GAMES_REGISTRATIONSIZE (100 * 10000) +#define GAMES_REGISTRATION 5 #define GAMES_RNGMULT 11109 #define GAMES_RNGOFFSET 13849 From 2a01bdd2d15807328e518243eb149de9b5681347 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:34:47 -1100 Subject: [PATCH 41/84] Games --- src/cc/gamescc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index e060016ff..8a6a3b656 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -22,6 +22,8 @@ std::string MYCCLIBNAME = (char *)"gamescc"; #define GAMES_MAXRNGS 10000 #define MYCCNAME "games" + +std::string Games_pname; #define GAMENAME "sudoku" #define RPC_FUNCS \ @@ -94,7 +96,7 @@ struct games_player struct games_packitem gamespack[MAXPACK]; }; -int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis); +int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); void games_packitemstr(char *packitemstr,struct games_packitem *item); From a9684309b85bd81e749751ee6e05c68941e0b902 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:39:05 -1100 Subject: [PATCH 42/84] Fixes --- src/cc/gamescc.cpp | 76 ++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 2330d130c..3dd9244aa 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -700,13 +700,47 @@ int32_t games_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx, Getscriptaddress(destaddr,spenttx.vout[0].scriptPubKey); if ( strcmp(mygamesaddr,destaddr) == 0 ) return(1); - //else fprintf(stderr,"myaddr.%s vs %s\n",myrogueaddr,destaddr); + //else fprintf(stderr,"myaddr.%s vs %s\n",mygamesaddr,destaddr); } //else fprintf(stderr,"cant find spenttxid.%s\n",spenttxid.GetHex().c_str()); } //else fprintf(stderr,"vout %d is unspent\n",vout); } return(0); } +void games_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers,char *mygamesaddr) +{ + // identify if bailout or quit or timed out + uint256 batontxid,spenttxid,gtxid,ptxid,tokenid,hashBlock,playertxid; CTransaction spenttx,batontx; int32_t numplayers,regslot,numkeys,batonvout,batonht,retval; int64_t batonvalue; std::vector playerdata; char destaddr[64]; std::string symbol,pname; + destaddr[0] = 0; + if ( myIsutxo_spent(spenttxid,gametxid,vout) >= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + Getscriptaddress(destaddr,spenttx.vout[0].scriptPubKey); + } + obj.push_back(Pair("slot",(int64_t)vout-1)); + if ( (retval= games_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,destaddr,numplayers,symbol,pname)) == 0 ) + { + if ( CCgettxout(gametxid,maxplayers+vout,1,0) == 10000 ) + { + if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 1 ) + { + if ( games_registeropretdecode(gtxid,tokenid,ptxid,batontx.vout[batontx.vout.size()-1].scriptPubKey) == 'R' && ptxid == playertxid && gtxid == gametxid ) + obj.push_back(Pair("status","registered")); + else obj.push_back(Pair("status","alive")); + } else obj.push_back(Pair("status","error")); + } else obj.push_back(Pair("status","finished")); + obj.push_back(Pair("baton",batontxid.ToString())); + obj.push_back(Pair("tokenid",tokenid.ToString())); + obj.push_back(Pair("batonaddr",destaddr)); + obj.push_back(Pair("ismine",strcmp(mygamesaddr,destaddr)==0)); + obj.push_back(Pair("batonvout",(int64_t)batonvout)); + obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue))); + obj.push_back(Pair("batonht",(int64_t)batonht)); + if ( playerdata.size() > 0 ) + obj.push_back(Pair("player",games_playerobj(playerdata,playertxid,tokenid,symbol,pname,gametxid))); + } else fprintf(stderr,"findbaton err.%d\n",retval); +} + uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *mygamesaddr) { CBlockIndex *pindex; int32_t ht,openslots,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx; @@ -939,42 +973,6 @@ UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); uint256 txid,hashBlock,gametxid,tokenid,playertxid; int32_t vout,maxplayers,gameheight,numvouts; CPubKey gamespk,mypk; char coinaddr[64]; CTransaction tx,gametx; int64_t buyin; - std::vector > addressIndex; - gamespk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - GetCCaddress1of2(cp,coinaddr,gamespk,mypk); - SetCCtxids(addressIndex,coinaddr); - games_univalue(result,"games",-1,-1); - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); - if ( vout == 0 ) - { - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 ) - { - if ( games_registeropretdecode(gametxid,tokenid,playertxid,tx.vout[numvouts-1].scriptPubKey) == 'R' ) - { - if ( games_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 ) - { - if ( CCgettxout(txid,vout,1,0) < 0 ) - b.push_back(gametxid.GetHex()); - else a.push_back(gametxid.GetHex()); - } - } - } - } - } - result.push_back(Pair("pastgames",b)); - result.push_back(Pair("games",a)); - result.push_back(Pair("numgames",(int64_t)(a.size()+b.size()))); - return(result); -} - UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t openslots,maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey gamespk; char coinaddr[64]; @@ -1029,7 +1027,7 @@ UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( CCgettxout(txid,i+1,1,0) < 0 ) { UniValue obj(UniValue::VOBJ); - games_playerinfo(cp,obj,txid,tx,i+1,maxplayers,myaddr); + games_gameplayerinfo(cp,obj,txid,tx,i+1,maxplayers,myaddr); a.push_back(obj); } else if ( 0 ) @@ -1423,7 +1421,7 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) // vout0 -> playerdata marker // vout0 -> 1% ingame gold // get any playerdata, get all keystrokes, replay game and compare final state - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); char *method = "bailout"; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); char *method = (char *)"bailout"; UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed; int64_t buyin,batonvalue,inputsum,cashout=0,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,dungeonlevel,numkeys,maxplayers,batonht,batonvout; char mygamesaddr[64],*keystrokes = 0; std::vector playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,gamespk; uint8_t player[10000],mypriv[32],funcid; struct CCcontract_info *cpTokens, tokensC; From e6371013aaff8463649f2dbdee227dc81559587c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:41:47 -1100 Subject: [PATCH 43/84] Reorder --- src/cc/gamescc.cpp | 68 +++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 3dd9244aa..aca989fd3 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -707,40 +707,6 @@ int32_t games_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx, return(0); } -void games_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers,char *mygamesaddr) -{ - // identify if bailout or quit or timed out - uint256 batontxid,spenttxid,gtxid,ptxid,tokenid,hashBlock,playertxid; CTransaction spenttx,batontx; int32_t numplayers,regslot,numkeys,batonvout,batonht,retval; int64_t batonvalue; std::vector playerdata; char destaddr[64]; std::string symbol,pname; - destaddr[0] = 0; - if ( myIsutxo_spent(spenttxid,gametxid,vout) >= 0 ) - { - if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) - Getscriptaddress(destaddr,spenttx.vout[0].scriptPubKey); - } - obj.push_back(Pair("slot",(int64_t)vout-1)); - if ( (retval= games_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,destaddr,numplayers,symbol,pname)) == 0 ) - { - if ( CCgettxout(gametxid,maxplayers+vout,1,0) == 10000 ) - { - if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 1 ) - { - if ( games_registeropretdecode(gtxid,tokenid,ptxid,batontx.vout[batontx.vout.size()-1].scriptPubKey) == 'R' && ptxid == playertxid && gtxid == gametxid ) - obj.push_back(Pair("status","registered")); - else obj.push_back(Pair("status","alive")); - } else obj.push_back(Pair("status","error")); - } else obj.push_back(Pair("status","finished")); - obj.push_back(Pair("baton",batontxid.ToString())); - obj.push_back(Pair("tokenid",tokenid.ToString())); - obj.push_back(Pair("batonaddr",destaddr)); - obj.push_back(Pair("ismine",strcmp(mygamesaddr,destaddr)==0)); - obj.push_back(Pair("batonvout",(int64_t)batonvout)); - obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue))); - obj.push_back(Pair("batonht",(int64_t)batonht)); - if ( playerdata.size() > 0 ) - obj.push_back(Pair("player",games_playerobj(playerdata,playertxid,tokenid,symbol,pname,gametxid))); - } else fprintf(stderr,"findbaton err.%d\n",retval); -} - uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *mygamesaddr) { CBlockIndex *pindex; int32_t ht,openslots,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx; @@ -936,6 +902,40 @@ int32_t games_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke return(-1); } +void games_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers,char *mygamesaddr) +{ + // identify if bailout or quit or timed out + uint256 batontxid,spenttxid,gtxid,ptxid,tokenid,hashBlock,playertxid; CTransaction spenttx,batontx; int32_t numplayers,regslot,numkeys,batonvout,batonht,retval; int64_t batonvalue; std::vector playerdata; char destaddr[64]; std::string symbol,pname; + destaddr[0] = 0; + if ( myIsutxo_spent(spenttxid,gametxid,vout) >= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + Getscriptaddress(destaddr,spenttx.vout[0].scriptPubKey); + } + obj.push_back(Pair("slot",(int64_t)vout-1)); + if ( (retval= games_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,destaddr,numplayers,symbol,pname)) == 0 ) + { + if ( CCgettxout(gametxid,maxplayers+vout,1,0) == 10000 ) + { + if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 1 ) + { + if ( games_registeropretdecode(gtxid,tokenid,ptxid,batontx.vout[batontx.vout.size()-1].scriptPubKey) == 'R' && ptxid == playertxid && gtxid == gametxid ) + obj.push_back(Pair("status","registered")); + else obj.push_back(Pair("status","alive")); + } else obj.push_back(Pair("status","error")); + } else obj.push_back(Pair("status","finished")); + obj.push_back(Pair("baton",batontxid.ToString())); + obj.push_back(Pair("tokenid",tokenid.ToString())); + obj.push_back(Pair("batonaddr",destaddr)); + obj.push_back(Pair("ismine",strcmp(mygamesaddr,destaddr)==0)); + obj.push_back(Pair("batonvout",(int64_t)batonvout)); + obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue))); + obj.push_back(Pair("batonht",(int64_t)batonht)); + if ( playerdata.size() > 0 ) + obj.push_back(Pair("player",games_playerobj(playerdata,playertxid,tokenid,symbol,pname,gametxid))); + } else fprintf(stderr,"findbaton err.%d\n",retval); +} + UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); From e97460a58dee3e50f3eaf1ee1b78f2feb7dbc61d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:43:18 -1100 Subject: [PATCH 44/84] Stub functions --- src/cc/gamescc.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index aca989fd3..b68c9f55c 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1634,4 +1634,14 @@ bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C return(true); } +int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis) +{ + return(-1); +} + +void games_packitemstr(char *packitemstr,struct games_packitem *item) +{ + sprintf(packitemstr,"not yet"); +} + From c1be8157e76b8c3f7d225d9afdde494b2c5565f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 06:51:16 -1100 Subject: [PATCH 45/84] Dont advance keystrokes unless keystrokes tx worked --- src/cc/rogue/main.c | 15 ++++++++++----- src/cc/rogue/rogue.c | 16 ++++++---------- src/cc/rogue/rogue.h | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index f146cfb4d..616ade086 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -784,9 +784,9 @@ int32_t rogue_sendrawtransaction(char *rawtx) return(retval); } -void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) +int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) { - char cmd[16384],hexstr[16384],params[32768],*retstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys; cJSON *retjson,*resobj; + char cmd[16384],hexstr[16384],params[32768],*retstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; //fprintf(stderr,"rogue_progress num.%d\n",num); if ( rs->guiflag != 0 && Gametxidstr[0] != 0 ) { @@ -795,7 +795,7 @@ void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char * if ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 ) { if ( waitflag == 0 ) - return; + return(0); else if ( 0 ) { while ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 ) @@ -866,8 +866,12 @@ void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char * { if ( rs->keystrokeshex != 0 ) free(rs->keystrokeshex); - rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1); - strcpy(rs->keystrokeshex,rawtx); + if ( (errstr= jstr(resobj,"error")) == 0 ) + { + rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1); + strcpy(rs->keystrokeshex,rawtx); + retflag = 1; + } else fprintf(stderr,"error sending keystrokes tx\n"), sleep(1); //fprintf(stderr,"set keystrokestx <- %s\n",rs->keystrokeshex); } free_json(retjson); @@ -885,6 +889,7 @@ void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char * } } } + return(retflag); } int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr) diff --git a/src/cc/rogue/rogue.c b/src/cc/rogue/rogue.c index 7a8e38c15..c687fd019 100644 --- a/src/cc/rogue/rogue.c +++ b/src/cc/rogue/rogue.c @@ -158,7 +158,7 @@ int32_t flushkeystrokes_local(struct rogue_state *rs,int32_t waitflag) #ifdef BUILD_ROGUE // stubs for inside daemon -void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) +int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) { } @@ -172,15 +172,11 @@ int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag) { if ( rs->num > 0 ) { - // need to get existing keystrokes including mempool - // create keystrokes that are not saved - //rs->keytxid = rogue_progress(rs,waitflag,rs->seed,&rs->buffered[rs->lastnum],rs->num - rs->lastnum); - //rs->lastnum = rs->num; - rogue_progress(rs,waitflag,rs->seed,rs->buffered,rs->num); - flushkeystrokes_local(rs,waitflag); - memset(rs->buffered,0,sizeof(rs->buffered)); - //rs->num = 0; - //rs->counter++; + if ( rogue_progress(rs,waitflag,rs->seed,rs->buffered,rs->num) > 0 ) + { + flushkeystrokes_local(rs,waitflag); + memset(rs->buffered,0,sizeof(rs->buffered)); + } } return(0); } diff --git a/src/cc/rogue/rogue.h b/src/cc/rogue/rogue.h index 5540da2da..65ddf1e51 100644 --- a/src/cc/rogue/rogue.h +++ b/src/cc/rogue/rogue.h @@ -380,7 +380,7 @@ int32_t rogue_restorepack(struct rogue_state *rs); void restore_player(struct rogue_state *rs); int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis); void rogue_bailout(struct rogue_state *rs); -void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num); +int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num); int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr); #define ROGUE_MAXTOTAL (pstats.s_str*2) From 259b9a983851e44f7d9fc7f8cbc0eb6d8a77ea49 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:35:23 -1100 Subject: [PATCH 46/84] Errata --- src/cc/gamescc.cpp | 896 ++++++++++++++++++++++++++++++++++++++++++++ src/cc/rogue/main.c | 2 +- 2 files changed, 897 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index b68c9f55c..88df9586d 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * Copyright © 2014-2019 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + #include "gamescc.h" /* @@ -1645,3 +1660,884 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) } +/***************************************************************************/ +/** https://github.com/brenns10/tetris + @file main.c + @author Stephen Brennan + @date Created Wednesday, 10 June 2015 + @brief Main program for tetris. + @copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised + BSD License. See LICENSE.txt for details. + *******************************************************************************/ + + +#ifndef TETRIS_H +#define TETRIS_H + +#include // for FILE +#include // for bool +#include +#include +#include +#include +#include +#include + +#ifdef BUILD_GAMES +#include "cursesd.h" +#include "rogue/cursesd.c" +#else +#include +#endif + + +/* + Convert a tetromino type to its corresponding cell. + */ +#define TYPE_TO_CELL(x) ((x)+1) + +/* + Strings for how you would print a tetris board. + */ +#define TC_EMPTY_STR " " +#define TC_BLOCK_STR "\u2588" + +/* + Questions about a tetris cell. + */ +#define TC_IS_EMPTY(x) ((x) == TC_EMPTY) +#define TC_IS_FILLED(x) (!TC_IS_EMPTY(x)) + +/* + How many cells in a tetromino? + */ +#define TETRIS 4 +/* + How many tetrominos? + */ +#define NUM_TETROMINOS 7 +/* + How many orientations of a tetromino? + */ +#define NUM_ORIENTATIONS 4 + +/* + Level constants. + */ +#define MAX_LEVEL 19 +#define LINES_PER_LEVEL 10 + +/* + A "cell" is a 1x1 block within a tetris board. + */ +typedef enum { + TC_EMPTY, TC_CELLI, TC_CELLJ, TC_CELLL, TC_CELLO, TC_CELLS, TC_CELLT, TC_CELLZ +} tetris_cell; + +/* + A "type" is a type/shape of a tetromino. Not including orientation. + */ +typedef enum { + TET_I, TET_J, TET_L, TET_O, TET_S, TET_T, TET_Z +} tetris_type; + +/* + A row,column pair. Negative numbers allowed, because we need them for + offsets. + */ +typedef struct { + int row; + int col; +} tetris_location; + +/* + A "block" is a struct that contains information about a tetromino. + Specifically, what type it is, what orientation it has, and where it is. + */ +typedef struct { + int typ; + int ori; + tetris_location loc; +} tetris_block; + +/* + All possible moves to give as input to the game. + */ +typedef enum { + TM_LEFT, TM_RIGHT, TM_CLOCK, TM_COUNTER, TM_DROP, TM_HOLD, TM_NONE +} tetris_move; + +/* + A game object! + */ +typedef struct { + /* + Game board stuff: + */ + int rows; + int cols; + char *board; + /* + Scoring information: + */ + int points; + int level; + /* + Falling block is the one currently going down. Next block is the one that + will be falling after this one. Stored is the block that you can swap out. + */ + tetris_block falling; + tetris_block next; + tetris_block stored; + /* + Number of game ticks until the block will move down. + */ + int ticks_till_gravity; + /* + Number of lines until you advance to the next level. + */ + int lines_remaining; +} tetris_game; + +/* + This array stores all necessary information about the cells that are filled by + each tetromino. The first index is the type of the tetromino (i.e. shape, + e.g. I, J, Z, etc.). The next index is the orientation (0-3). The final + array contains 4 tetris_location objects, each mapping to an offset from a + point on the upper left that is the tetromino "origin". + */ +extern tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS]; + +/* + This array tells you how many ticks per gravity by level. Decreases as level + increases, to add difficulty. + */ +extern int GRAVITY_LEVEL[MAX_LEVEL+1]; + +// Data structure manipulation. +void tg_init(tetris_game *obj, int rows, int cols); +tetris_game *tg_create(int rows, int cols); +void tg_destroy(tetris_game *obj); +void tg_delete(tetris_game *obj); +tetris_game *tg_load(FILE *f); +void tg_save(tetris_game *obj, FILE *f); + +// Public methods not related to memory: +char tg_get(tetris_game *obj, int row, int col); +bool tg_check(tetris_game *obj, int row, int col); +bool tg_tick(tetris_game *obj, tetris_move move); +void tg_print(tetris_game *obj, FILE *f); + +#endif // TETRIS_H + + +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + +/******************************************************************************* + Array Definitions + *******************************************************************************/ + +tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS] = { + // I + {{{1, 0}, {1, 1}, {1, 2}, {1, 3}}, + {{0, 2}, {1, 2}, {2, 2}, {3, 2}}, + {{3, 0}, {3, 1}, {3, 2}, {3, 3}}, + {{0, 1}, {1, 1}, {2, 1}, {3, 1}}}, + // J + {{{0, 0}, {1, 0}, {1, 1}, {1, 2}}, + {{0, 1}, {0, 2}, {1, 1}, {2, 1}}, + {{1, 0}, {1, 1}, {1, 2}, {2, 2}}, + {{0, 1}, {1, 1}, {2, 0}, {2, 1}}}, + // L + {{{0, 2}, {1, 0}, {1, 1}, {1, 2}}, + {{0, 1}, {1, 1}, {2, 1}, {2, 2}}, + {{1, 0}, {1, 1}, {1, 2}, {2, 0}}, + {{0, 0}, {0, 1}, {1, 1}, {2, 1}}}, + // O + {{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, + {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, + {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, + {{0, 1}, {0, 2}, {1, 1}, {1, 2}}}, + // S + {{{0, 1}, {0, 2}, {1, 0}, {1, 1}}, + {{0, 1}, {1, 1}, {1, 2}, {2, 2}}, + {{1, 1}, {1, 2}, {2, 0}, {2, 1}}, + {{0, 0}, {1, 0}, {1, 1}, {2, 1}}}, + // T + {{{0, 1}, {1, 0}, {1, 1}, {1, 2}}, + {{0, 1}, {1, 1}, {1, 2}, {2, 1}}, + {{1, 0}, {1, 1}, {1, 2}, {2, 1}}, + {{0, 1}, {1, 0}, {1, 1}, {2, 1}}}, + // Z + {{{0, 0}, {0, 1}, {1, 1}, {1, 2}}, + {{0, 2}, {1, 1}, {1, 2}, {2, 1}}, + {{1, 0}, {1, 1}, {2, 1}, {2, 2}}, + {{0, 1}, {1, 0}, {1, 1}, {2, 0}}}, +}; + +int GRAVITY_LEVEL[MAX_LEVEL+1] = { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, + //10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 30, 28, 26, 24, 22, 20, 16, 12, 8, 4 +}; + +/******************************************************************************* + Helper Functions for Blocks + *******************************************************************************/ + +void sleep_milli(int milliseconds) +{ + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = milliseconds * 1000 * 1000; + nanosleep(&ts, NULL); +} + +/* + Return the block at the given row and column. + */ +char tg_get(tetris_game *obj, int row, int column) +{ + return obj->board[obj->cols * row + column]; +} + +/* + Set the block at the given row and column. + */ +static void tg_set(tetris_game *obj, int row, int column, char value) +{ + obj->board[obj->cols * row + column] = value; +} + +/* + Check whether a row and column are in bounds. + */ +bool tg_check(tetris_game *obj, int row, int col) +{ + return 0 <= row && row < obj->rows && 0 <= col && col < obj->cols; +} + +/* + Place a block onto the board. + */ +static void tg_put(tetris_game *obj, tetris_block block) +{ + int i; + for (i = 0; i < TETRIS; i++) { + tetris_location cell = TETROMINOS[block.typ][block.ori][i]; + tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, + TYPE_TO_CELL(block.typ)); + } +} + +/* + Clear a block out of the board. + */ +static void tg_remove(tetris_game *obj, tetris_block block) +{ + int i; + for (i = 0; i < TETRIS; i++) { + tetris_location cell = TETROMINOS[block.typ][block.ori][i]; + tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, TC_EMPTY); + } +} + +/* + Check if a block can be placed on the board. + */ +static bool tg_fits(tetris_game *obj, tetris_block block) +{ + int i, r, c; + for (i = 0; i < TETRIS; i++) { + tetris_location cell = TETROMINOS[block.typ][block.ori][i]; + r = block.loc.row + cell.row; + c = block.loc.col + cell.col; + if (!tg_check(obj, r, c) || TC_IS_FILLED(tg_get(obj, r, c))) { + return false; + } + } + return true; +} + +/* + Return a random tetromino type. + */ +static int random_tetromino(void) +{ + return rand() % NUM_TETROMINOS; +} + +/* + Create a new falling block and populate the next falling block with a random + one. + */ +static void tg_new_falling(tetris_game *obj) +{ + // Put in a new falling tetromino. + obj->falling = obj->next; + obj->next.typ = random_tetromino(); + obj->next.ori = 0; + obj->next.loc.row = 0; + obj->next.loc.col = obj->cols/2 - 2; +} + +/******************************************************************************* + Game Turn Helpers + *******************************************************************************/ + +/* + Tick gravity, and move the block down if gravity should act. + */ +static void tg_do_gravity_tick(tetris_game *obj) +{ + obj->ticks_till_gravity--; + if (obj->ticks_till_gravity <= 0) { + tg_remove(obj, obj->falling); + obj->falling.loc.row++; + if (tg_fits(obj, obj->falling)) { + obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; + } else { + obj->falling.loc.row--; + tg_put(obj, obj->falling); + + tg_new_falling(obj); + } + tg_put(obj, obj->falling); + } +} + +/* + Move the falling tetris block left (-1) or right (+1). + */ +static void tg_move(tetris_game *obj, int direction) +{ + tg_remove(obj, obj->falling); + obj->falling.loc.col += direction; + if (!tg_fits(obj, obj->falling)) { + obj->falling.loc.col -= direction; + } + tg_put(obj, obj->falling); +} + +/* + Send the falling tetris block to the bottom. + */ +static void tg_down(tetris_game *obj) +{ + tg_remove(obj, obj->falling); + while (tg_fits(obj, obj->falling)) { + obj->falling.loc.row++; + } + obj->falling.loc.row--; + tg_put(obj, obj->falling); + tg_new_falling(obj); +} + +/* + Rotate the falling block in either direction (+/-1). + */ +static void tg_rotate(tetris_game *obj, int direction) +{ + tg_remove(obj, obj->falling); + + while (true) { + obj->falling.ori = (obj->falling.ori + direction) % NUM_ORIENTATIONS; + + // If the new orientation fits, we're done. + if (tg_fits(obj, obj->falling)) + break; + + // Otherwise, try moving left to make it fit. + obj->falling.loc.col--; + if (tg_fits(obj, obj->falling)) + break; + + // Finally, try moving right to make it fit. + obj->falling.loc.col += 2; + if (tg_fits(obj, obj->falling)) + break; + + // Put it back in its original location and try the next orientation. + obj->falling.loc.col--; + // Worst case, we come back to the original orientation and it fits, so this + // loop will terminate. + } + + tg_put(obj, obj->falling); +} + +/* + Swap the falling block with the block in the hold buffer. + */ +static void tg_hold(tetris_game *obj) +{ + tg_remove(obj, obj->falling); + if (obj->stored.typ == -1) { + obj->stored = obj->falling; + tg_new_falling(obj); + } else { + int typ = obj->falling.typ, ori = obj->falling.ori; + obj->falling.typ = obj->stored.typ; + obj->falling.ori = obj->stored.ori; + obj->stored.typ = typ; + obj->stored.ori = ori; + while (!tg_fits(obj, obj->falling)) { + obj->falling.loc.row--; + } + } + tg_put(obj, obj->falling); +} + +/* + Perform the action specified by the move. + */ +static void tg_handle_move(tetris_game *obj, tetris_move move) +{ + switch (move) { + case TM_LEFT: + tg_move(obj, -1); + break; + case TM_RIGHT: + tg_move(obj, 1); + break; + case TM_DROP: + tg_down(obj); + break; + case TM_CLOCK: + tg_rotate(obj, 1); + break; + case TM_COUNTER: + tg_rotate(obj, -1); + break; + case TM_HOLD: + tg_hold(obj); + break; + default: + // pass + break; + } +} + +/* + Return true if line i is full. + */ +static bool tg_line_full(tetris_game *obj, int i) +{ + int j; + for (j = 0; j < obj->cols; j++) { + if (TC_IS_EMPTY(tg_get(obj, i, j))) + return false; + } + return true; +} + +/* + Shift every row above r down one. + */ +static void tg_shift_lines(tetris_game *obj, int r) +{ + int i, j; + for (i = r-1; i >= 0; i--) { + for (j = 0; j < obj->cols; j++) { + tg_set(obj, i+1, j, tg_get(obj, i, j)); + tg_set(obj, i, j, TC_EMPTY); + } + } +} + +/* + Find rows that are filled, remove them, shift, and return the number of + cleared rows. + */ +static int tg_check_lines(tetris_game *obj) +{ + int i, nlines = 0; + tg_remove(obj, obj->falling); // don't want to mess up falling block + + for (i = obj->rows-1; i >= 0; i--) { + if (tg_line_full(obj, i)) { + tg_shift_lines(obj, i); + i++; // do this line over again since they're shifted + nlines++; + } + } + + tg_put(obj, obj->falling); // replace + return nlines; +} + +/* + Adjust the score for the game, given how many lines were just cleared. + */ +static void tg_adjust_score(tetris_game *obj, int lines_cleared) +{ + static int line_multiplier[] = {0, 40, 100, 300, 1200}; + obj->points += line_multiplier[lines_cleared] * (obj->level + 1); + if (lines_cleared >= obj->lines_remaining) { + obj->level = MIN(MAX_LEVEL, obj->level + 1); + lines_cleared -= obj->lines_remaining; + obj->lines_remaining = LINES_PER_LEVEL - lines_cleared; + } else { + obj->lines_remaining -= lines_cleared; + } +} + +/* + Return true if the game is over. + */ +static bool tg_game_over(tetris_game *obj) +{ + int i, j; + bool over = false; + tg_remove(obj, obj->falling); + for (i = 0; i < 2; i++) { + for (j = 0; j < obj->cols; j++) { + if (TC_IS_FILLED(tg_get(obj, i, j))) { + over = true; + } + } + } + tg_put(obj, obj->falling); + return over; +} + +/******************************************************************************* + Main Public Functions + *******************************************************************************/ + +/* + Do a single game tick: process gravity, user input, and score. Return true if + the game is still running, false if it is over. + */ +bool tg_tick(tetris_game *obj, tetris_move move) +{ + int lines_cleared; + // Handle gravity. + tg_do_gravity_tick(obj); + + // Handle input. + tg_handle_move(obj, move); + + // Check for cleared lines + lines_cleared = tg_check_lines(obj); + + tg_adjust_score(obj, lines_cleared); + + // Return whether the game will continue (NOT whether it's over) + return !tg_game_over(obj); +} + +void tg_init(tetris_game *obj, int rows, int cols) +{ + // Initialization logic + obj->rows = rows; + obj->cols = cols; + obj->board = (char *)malloc(rows * cols); + memset(obj->board, TC_EMPTY, rows * cols); + obj->points = 0; + obj->level = 0; + obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; + obj->lines_remaining = LINES_PER_LEVEL; + srand(time(NULL)); + tg_new_falling(obj); + tg_new_falling(obj); + obj->stored.typ = -1; + obj->stored.ori = 0; + obj->stored.loc.row = 0; + obj->next.loc.col = obj->cols/2 - 2; + printf("%d", obj->falling.loc.col); +} + +tetris_game *tg_create(int rows, int cols) +{ + tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game)); + tg_init(obj, rows, cols); + return obj; +} + +void tg_destroy(tetris_game *obj) +{ + // Cleanup logic + free(obj->board); +} + +void tg_delete(tetris_game *obj) { + tg_destroy(obj); + free(obj); +} + +/* + Load a game from a file. + */ +tetris_game *tg_load(FILE *f) +{ + tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game)); + if (fread(obj, sizeof(tetris_game), 1, f) != 1 ) + { + fprintf(stderr,"read game error\n"); + free(obj); + obj = 0; + } + else + { + obj->board = (char *)malloc(obj->rows * obj->cols); + if (fread(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) + { + fprintf(stderr,"fread error\n"); + free(obj->board); + free(obj); + obj = 0; + } + } + return obj; +} + +/* + Save a game to a file. + */ +void tg_save(tetris_game *obj, FILE *f) +{ + if (fwrite(obj, sizeof(tetris_game), 1, f) != 1 ) + fprintf(stderr,"error writing tetrisgame\n"); + else if (fwrite(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) + fprintf(stderr,"error writing board\n"); +} + +/* + Print a game board to a file. Really just for early debugging. + */ +void tg_print(tetris_game *obj, FILE *f) { + int i, j; + for (i = 0; i < obj->rows; i++) { + for (j = 0; j < obj->cols; j++) { + if (TC_IS_EMPTY(tg_get(obj, i, j))) { + fputs(TC_EMPTY_STR, f); + } else { + fputs(TC_BLOCK_STR, f); + } + } + fputc('\n', f); + } +} + +/* + 2 columns per cell makes the game much nicer. + */ +#define COLS_PER_CELL 2 +/* + Macro to print a cell of a specific type to a window. + */ +#define ADD_BLOCK(w,x) waddch((w),' '|A_REVERSE|COLOR_PAIR(x)); \ +waddch((w),' '|A_REVERSE|COLOR_PAIR(x)) +#define ADD_EMPTY(w) waddch((w), ' '); waddch((w), ' ') + +/* + Print the tetris board onto the ncurses window. + */ +void display_board(WINDOW *w, tetris_game *obj) +{ + int i, j; + box(w, 0, 0); + for (i = 0; i < obj->rows; i++) { + wmove(w, 1 + i, 1); + for (j = 0; j < obj->cols; j++) { + if (TC_IS_FILLED(tg_get(obj, i, j))) { + ADD_BLOCK(w,tg_get(obj, i, j)); + } else { + ADD_EMPTY(w); + } + } + } + wnoutrefresh(w); +} + +/* + Display a tetris piece in a dedicated window. + */ +void display_piece(WINDOW *w, tetris_block block) +{ + int b; + tetris_location c; + wclear(w); + box(w, 0, 0); + if (block.typ == -1) { + wnoutrefresh(w); + return; + } + for (b = 0; b < TETRIS; b++) { + c = TETROMINOS[block.typ][block.ori][b]; + wmove(w, c.row + 1, c.col * COLS_PER_CELL + 1); + ADD_BLOCK(w, TYPE_TO_CELL(block.typ)); + } + wnoutrefresh(w); +} + +/* + Display score information in a dedicated window. + */ +void display_score(WINDOW *w, tetris_game *tg) +{ + wclear(w); + box(w, 0, 0); + wprintw(w, "Score\n%d\n", tg->points); + wprintw(w, "Level\n%d\n", tg->level); + wprintw(w, "Lines\n%d\n", tg->lines_remaining); + wnoutrefresh(w); +} + +/* + Save and exit the game. + */ +void save(tetris_game *game, WINDOW *w) +{ + FILE *f; + + wclear(w); + box(w, 0, 0); // return the border + wmove(w, 1, 1); + wprintw(w, "Save and exit? [Y/n] "); + wrefresh(w); + timeout(-1); + if (getch() == 'n') { + timeout(0); + return; + } + f = fopen("tetris.save", "w"); + tg_save(game, f); + fclose(f); + tg_delete(game); + endwin(); + printf("Game saved to \"tetris.save\".\n"); + printf("Resume by passing the filename as an argument to this program.\n"); + exit(EXIT_SUCCESS); +} + +/* + Do the NCURSES initialization steps for color blocks. + */ +void init_colors(void) +{ + start_color(); + //init_color(COLOR_ORANGE, 1000, 647, 0); + init_pair(TC_CELLI, COLOR_CYAN, COLOR_BLACK); + init_pair(TC_CELLJ, COLOR_BLUE, COLOR_BLACK); + init_pair(TC_CELLL, COLOR_WHITE, COLOR_BLACK); + init_pair(TC_CELLO, COLOR_YELLOW, COLOR_BLACK); + init_pair(TC_CELLS, COLOR_GREEN, COLOR_BLACK); + init_pair(TC_CELLT, COLOR_MAGENTA, COLOR_BLACK); + init_pair(TC_CELLZ, COLOR_RED, COLOR_BLACK); +} + +/* + Main tetris game! + */ +#ifndef STANDALONE + +int main(int argc, char **argv) +{ + tetris_game *tg; + tetris_move move = TM_NONE; + bool running = true; + WINDOW *board, *next, *hold, *score; + //Mix_Music *music; + + // Load file if given a filename. + if (argc >= 2) { + FILE *f = fopen(argv[1], "r"); + if (f == NULL) { + perror("tetris"); + exit(EXIT_FAILURE); + } + tg = tg_load(f); + fclose(f); + } else { + // Otherwise create new game. + tg = tg_create(22, 10); + } + // NCURSES initialization: + initscr(); // initialize curses + cbreak(); // pass key presses to program, but not signals + noecho(); // don't echo key presses to screen + keypad(stdscr, TRUE); // allow arrow keys + timeout(0); // no blocking on getch() + curs_set(0); // set the cursor to invisible + init_colors(); // setup tetris colors + + // Create windows for each section of the interface. + board = newwin(tg->rows + 2, 2 * tg->cols + 2, 0, 0); + next = newwin(6, 10, 0, 2 * (tg->cols + 1) + 1); + hold = newwin(6, 10, 7, 2 * (tg->cols + 1) + 1); + score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); + int32_t counter = 0; + // Game loop + while (running) { + running = tg_tick(tg, move); + display_board(board, tg); + display_piece(next, tg->next); + display_piece(hold, tg->stored); + display_score(score, tg); + if ( (counter++ % 5) == 0 ) + doupdate(); + sleep_milli(10); + + switch (getch()) { + case KEY_LEFT: + move = TM_LEFT; + break; + case KEY_RIGHT: + move = TM_RIGHT; + break; + case KEY_UP: + move = TM_CLOCK; + break; + case KEY_DOWN: + move = TM_DROP; + break; + case 'q': + running = false; + move = TM_NONE; + break; + case 'p': + wclear(board); + box(board, 0, 0); + wmove(board, tg->rows/2, (tg->cols*COLS_PER_CELL-6)/2); + wprintw(board, "PAUSED"); + wrefresh(board); + timeout(-1); + getch(); + timeout(0); + move = TM_NONE; + break; + case 's': + save(tg, board); + move = TM_NONE; + break; + case ' ': + move = TM_HOLD; + break; + default: + move = TM_NONE; + } + } + + // Deinitialize NCurses + wclear(stdscr); + endwin(); + + /* Deinitialize Sound + Mix_HaltMusic(); + Mix_FreeMusic(music); + Mix_CloseAudio(); + Mix_Quit();*/ + + // Output ending message. + printf("Game over!\n"); + printf("You finished with %d points on level %d.\n", tg->points, tg->level); + + // Deinitialize Tetris + tg_delete(tg); + return 0; +} + diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 616ade086..093b73d70 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -786,7 +786,7 @@ int32_t rogue_sendrawtransaction(char *rawtx) int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) { - char cmd[16384],hexstr[16384],params[32768],*retstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; + char cmd[16384],hexstr[16384],params[32768],*retstr,*errstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; //fprintf(stderr,"rogue_progress num.%d\n",num); if ( rs->guiflag != 0 && Gametxidstr[0] != 0 ) { From a266b5e613f05f686c056a56e6047fd950dee090 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:36:23 -1100 Subject: [PATCH 47/84] Test --- src/cc/gamescc.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 88df9586d..4b5dca4f5 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2525,13 +2525,6 @@ int main(int argc, char **argv) // Deinitialize NCurses wclear(stdscr); endwin(); - - /* Deinitialize Sound - Mix_HaltMusic(); - Mix_FreeMusic(music); - Mix_CloseAudio(); - Mix_Quit();*/ - // Output ending message. printf("Game over!\n"); printf("You finished with %d points on level %d.\n", tg->points, tg->level); @@ -2540,4 +2533,5 @@ int main(int argc, char **argv) tg_delete(tg); return 0; } +#endif From 59b34d0a1c68fd2cdb13fb9bbe2da4dab074f934 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:39:13 -1100 Subject: [PATCH 48/84] #include "rogue/cursesd.c" --- src/cc/cclib.cpp | 1 + src/cc/gamescc.cpp | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 65c706862..95748def4 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -692,6 +692,7 @@ int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len) #elif BUILD_GAMESCC #include "gamescc.cpp" +#include "rogue/cursesd.c" #else #include "sudoku.cpp" diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 4b5dca4f5..3415c3eb7 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1685,7 +1685,6 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #ifdef BUILD_GAMES #include "cursesd.h" -#include "rogue/cursesd.c" #else #include #endif @@ -2433,7 +2432,7 @@ void init_colors(void) /* Main tetris game! */ -#ifndef STANDALONE +#ifdef STANDALONE int main(int argc, char **argv) { From 284a57b31f774f2800661354e81c12a2310a5ace Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:46:19 -1100 Subject: [PATCH 49/84] BUILD_GAMESCC --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 3415c3eb7..0d2564042 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1683,7 +1683,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include -#ifdef BUILD_GAMES +#ifdef BUILD_GAMESCC #include "cursesd.h" #else #include From f800ced0e20af6e559b6b24f5096960a4d2249b5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:46:59 -1100 Subject: [PATCH 50/84] Rogue/cursesd --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 0d2564042..81942ebe4 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1684,7 +1684,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #ifdef BUILD_GAMESCC -#include "cursesd.h" +#include "rogue/cursesd.h" #else #include #endif From 7a1a5f15299816629b7c22124e68b56e2c14f29f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:51:45 -1100 Subject: [PATCH 51/84] Endif --- src/cc/gamescc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 81942ebe4..c6206b2ee 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1659,6 +1659,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) sprintf(packitemstr,"not yet"); } +#ifdef includgame /***************************************************************************/ /** https://github.com/brenns10/tetris @@ -2533,4 +2534,5 @@ int main(int argc, char **argv) return 0; } #endif +#endif From 347ba53d84c64133f5a3c695f7cb3f4515759090 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:52:57 -1100 Subject: [PATCH 52/84] // --- src/cc/rogue_rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index 6f507e51e..fbb1a3d93 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -1596,7 +1596,7 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C if ( funcid == 'H' ) { cashout *= 2; - cashout += numplayers * buyin; + //cashout += numplayers * buyin; } sprintf(cashstr,"tokentx.(%c) decoded.%d ht.%d txid.%s %.8f vs vout2 %.8f",tokentx,decoded,height,txid.GetHex().c_str(),(double)cashout/COIN,(double)tx.vout[2].nValue/COIN); if ( strcmp(laststr,cashstr) != 0 ) From 9c555e6168c8442e5994fdc69551e4865bf5cb46 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 07:59:17 -1100 Subject: [PATCH 53/84] Colors --- src/cc/gamescc.cpp | 3 --- src/cc/rogue/cursesd.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c6206b2ee..694846350 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1659,8 +1659,6 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) sprintf(packitemstr,"not yet"); } -#ifdef includgame - /***************************************************************************/ /** https://github.com/brenns10/tetris @file main.c @@ -2534,5 +2532,4 @@ int main(int argc, char **argv) return 0; } #endif -#endif diff --git a/src/cc/rogue/cursesd.h b/src/cc/rogue/cursesd.h index cb74941e5..fbac07855 100644 --- a/src/cc/rogue/cursesd.h +++ b/src/cc/rogue/cursesd.h @@ -16,6 +16,24 @@ #ifndef H_CURSESD_H #define H_CURSESD_H +#define COLOR_BLACK 0 + +#ifdef PDC_RGB /* RGB */ +# define COLOR_RED 1 +# define COLOR_GREEN 2 +# define COLOR_BLUE 4 +#else /* BGR */ +# define COLOR_BLUE 1 +# define COLOR_GREEN 2 +# define COLOR_RED 4 +#endif + +#define COLOR_CYAN (COLOR_BLUE | COLOR_GREEN) +#define COLOR_MAGENTA (COLOR_RED | COLOR_BLUE) +#define COLOR_YELLOW (COLOR_RED | COLOR_GREEN) + +#define COLOR_WHITE 7 + #define LINES 24 #define COLS 80 From 02facf2da73eda9e77633fead9c7e0c4228f1177 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 08:04:50 -1100 Subject: [PATCH 54/84] Test --- src/cc/gamescc.cpp | 12 ++++++------ src/cc/rogue/cursesd.h | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 694846350..175cc3dc2 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2379,9 +2379,9 @@ void display_score(WINDOW *w, tetris_game *tg) { wclear(w); box(w, 0, 0); - wprintw(w, "Score\n%d\n", tg->points); - wprintw(w, "Level\n%d\n", tg->level); - wprintw(w, "Lines\n%d\n", tg->lines_remaining); + wprintw(w, (char *)"Score\n%d\n", tg->points); + wprintw(w, (char *)"Level\n%d\n", tg->level); + wprintw(w, (char *)"Lines\n%d\n", tg->lines_remaining); wnoutrefresh(w); } @@ -2395,7 +2395,7 @@ void save(tetris_game *game, WINDOW *w) wclear(w); box(w, 0, 0); // return the border wmove(w, 1, 1); - wprintw(w, "Save and exit? [Y/n] "); + wprintw(w, (char *)"Save and exit? [Y/n] "); wrefresh(w); timeout(-1); if (getch() == 'n') { @@ -2407,8 +2407,8 @@ void save(tetris_game *game, WINDOW *w) fclose(f); tg_delete(game); endwin(); - printf("Game saved to \"tetris.save\".\n"); - printf("Resume by passing the filename as an argument to this program.\n"); + fprintf(stderr,"Game saved to \"tetris.save\".\n"); + fprintf(stderr,"Resume by passing the filename as an argument to this program.\n"); exit(EXIT_SUCCESS); } diff --git a/src/cc/rogue/cursesd.h b/src/cc/rogue/cursesd.h index fbac07855..0ae992427 100644 --- a/src/cc/rogue/cursesd.h +++ b/src/cc/rogue/cursesd.h @@ -168,6 +168,12 @@ char *unctrl(char c); #define leaveok(win,bf) 0 #define halfdelay(x) 0 #define nocbreak() 0 +#define init_color(a,b,c) 0 +#define start_color() 0 +#define box(a,b,c) 0 +#define A_REVERSE 0 +#define COLOR_PAIR(a) 0 +#define timeout(x) 0 #ifndef TRUE #define TRUE 1 From a06129b526ff501c30bfed43625a325938e2107c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 08:07:18 -1100 Subject: [PATCH 55/84] init_pair --- src/cc/rogue/cursesd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue/cursesd.h b/src/cc/rogue/cursesd.h index 0ae992427..cdad704ed 100644 --- a/src/cc/rogue/cursesd.h +++ b/src/cc/rogue/cursesd.h @@ -168,7 +168,7 @@ char *unctrl(char c); #define leaveok(win,bf) 0 #define halfdelay(x) 0 #define nocbreak() 0 -#define init_color(a,b,c) 0 +#define init_pair(a,b,c) 0 #define start_color() 0 #define box(a,b,c) 0 #define A_REVERSE 0 From b91cd4346bca52fcd668c3748f535785b8a3ba25 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 08:50:49 -1100 Subject: [PATCH 56/84] Standalone --- src/cc/gamescc.cpp | 995 ++++++++++++++++++++++++++++++++++++++++- src/cc/rogue/cursesd.h | 3 + 2 files changed, 996 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 175cc3dc2..59adfae1d 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1659,6 +1659,997 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) sprintf(packitemstr,"not yet"); } +#ifdef STANDALONE + +#include +#include +#include +#include +#include +#include +#include +#include + +char USERPASS[8192]; uint16_t GAMES_PORT; +extern char Gametxidstr[67]; + +#define SMALLVAL 0.000000000000001 +#define SATOSHIDEN ((uint64_t)100000000L) +#define dstr(x) ((double)(x) / SATOSHIDEN) +#define KOMODO_ASSETCHAIN_MAXLEN 65 +char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],IPADDRESS[100]; + +#ifndef _BITS256 +#define _BITS256 +union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; }; +typedef union _bits256 bits256; +#endif + +#ifdef _WIN32 +#ifdef _MSC_VER +int gettimeofday(struct timeval * tp, struct timezone * tzp) +{ + // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long)((time - EPOCH) / 10000000L); + tp->tv_usec = (long)(system_time.wMilliseconds * 1000); + return 0; +} +#endif // _MSC_VER +#endif + + + +double OS_milliseconds() +{ + struct timeval tv; double millis; +#ifdef __MINGW32__ + mingw_gettimeofday(&tv,NULL); +#else + gettimeofday(&tv,NULL); +#endif + millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.); + //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis); + return(millis); +} + +int32_t _unhex(char c) +{ + if ( c >= '0' && c <= '9' ) + return(c - '0'); + else if ( c >= 'a' && c <= 'f' ) + return(c - 'a' + 10); + else if ( c >= 'A' && c <= 'F' ) + return(c - 'A' + 10); + return(-1); +} + +int32_t is_hexstr(char *str,int32_t n) +{ + int32_t i; + if ( str == 0 || str[0] == 0 ) + return(0); + for (i=0; str[i]!=0; i++) + { + if ( n > 0 && i >= n ) + break; + if ( _unhex(str[i]) < 0 ) + break; + } + if ( n == 0 ) + return(i); + return(i == n); +} + +int32_t unhex(char c) +{ + int32_t hex; + if ( (hex= _unhex(c)) < 0 ) + { + //printf("unhex: illegal hexchar.(%c)\n",c); + } + return(hex); +} + +unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); } + +int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex) +{ + int32_t adjust,i = 0; + //printf("decode.(%s)\n",hex); + if ( is_hexstr(hex,n) <= 0 ) + { + memset(bytes,0,n); + return(n); + } + if ( hex[n-1] == '\n' || hex[n-1] == '\r' ) + hex[--n] = 0; + if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) ) + { + if ( n > 0 ) + { + bytes[0] = unhex(hex[0]); + printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex)); + } + bytes++; + hex++; + adjust = 1; + } else adjust = 0; + if ( n > 0 ) + { + for (i=0; i>4) & 0xf); + hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf); + //printf("i.%d (%02x) [%c%c]\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1]); + } + hexbytes[len*2] = 0; + //printf("len.%ld\n",len*2+1); + return((int32_t)len*2+1); +} + +char *bits256_str(char hexstr[65],bits256 x) +{ + init_hexbytes_noT(hexstr,x.bytes,sizeof(x)); + return(hexstr); +} + +long _stripwhite(char *buf,int accept) +{ + int32_t i,j,c; + if ( buf == 0 || buf[0] == 0 ) + return(0); + for (i=j=0; buf[i]!=0; i++) + { + buf[j] = c = buf[i]; + if ( c == accept || (c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != '\b') ) + j++; + } + buf[j] = 0; + return(j); +} + +char *clonestr(char *str) +{ + char *clone; + if ( str == 0 || str[0] == 0 ) + { + printf("warning cloning nullstr.%p\n",str); +#ifdef __APPLE__ + while ( 1 ) sleep(1); +#endif + str = (char *)""; + } + clone = (char *)malloc(strlen(str)+16); + strcpy(clone,str); + return(clone); +} + +char *parse_conf_line(char *line,char *field) +{ + line += strlen(field); + for (; *line!='='&&*line!=0; line++) + break; + if ( *line == 0 ) + return(0); + if ( *line == '=' ) + line++; + while ( line[strlen(line)-1] == '\r' || line[strlen(line)-1] == '\n' || line[strlen(line)-1] == ' ' ) + line[strlen(line)-1] = 0; + //printf("LINE.(%s)\n",line); + _stripwhite(line,0); + return(clonestr(line)); +} + +int32_t safecopy(char *dest,char *src,long len) +{ + int32_t i = -1; + if ( src != 0 && dest != 0 && src != dest ) + { + if ( dest != 0 ) + memset(dest,0,len); + for (i=0; i buflen ) + { + *allocsizep = filesize; + *bufp = buf = (uint8_t *)realloc(buf,(long)*allocsizep+64); + } + rewind(fp); + if ( buf == 0 ) + printf("Null buf ???\n"); + else + { + if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) + printf("error reading filesize.%ld\n",(long)filesize); + buf[filesize] = 0; + } + fclose(fp); + *lenp = filesize; + //printf("loaded.(%s)\n",buf); + } //else printf("OS_loadfile couldnt load.(%s)\n",fname); + return(buf); +} + +uint8_t *OS_fileptr(long *allocsizep,char *fname) +{ + long filesize = 0; uint8_t *buf = 0; void *retptr; + *allocsizep = 0; + retptr = OS_loadfile(fname,&buf,&filesize,allocsizep); + return((uint8_t *)retptr); +} + +struct MemoryStruct { char *memory; size_t size; }; +struct return_string { char *ptr; size_t len; }; + +// return data from the server +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) + + +/************************************************************************ + * + * Initialize the string handler so that it is thread safe + * + ************************************************************************/ + +void init_string(struct return_string *s) +{ + s->len = 0; + s->ptr = (char *)calloc(1,s->len+1); + if ( s->ptr == NULL ) + { + fprintf(stderr,"init_string malloc() failed\n"); + exit(-1); + } + s->ptr[0] = '\0'; +} + +/************************************************************************ + * + * Use the "writer" to accumulate text until done + * + ************************************************************************/ + +size_t accumulatebytes(void *ptr,size_t size,size_t nmemb,struct return_string *s) +{ + size_t new_len = s->len + size*nmemb; + s->ptr = (char *)realloc(s->ptr,new_len+1); + if ( s->ptr == NULL ) + { + fprintf(stderr, "accumulate realloc() failed\n"); + exit(-1); + } + memcpy(s->ptr+s->len,ptr,size*nmemb); + s->ptr[new_len] = '\0'; + s->len = new_len; + return(size * nmemb); +} + +/************************************************************************ + * + * return the current system time in milliseconds + * + ************************************************************************/ + +#define EXTRACT_BITCOIND_RESULT // if defined, ensures error is null and returns the "result" field +#ifdef EXTRACT_BITCOIND_RESULT + +/************************************************************************ + * + * perform post processing of the results + * + ************************************************************************/ + +char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *params) +{ + long i,j,len; char *retstr = 0; cJSON *json,*result,*error; + //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); + if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) + { + if ( strcmp(command,"signrawtransaction") != 0 ) + printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); + return(rpcstr); + } + json = cJSON_Parse(rpcstr); + if ( json == 0 ) + { + printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params); + free(rpcstr); + return(0); + } + result = cJSON_GetObjectItem(json,"result"); + error = cJSON_GetObjectItem(json,"error"); + if ( error != 0 && result != 0 ) + { + if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) + { + retstr = cJSON_Print(result); + len = strlen(retstr); + if ( retstr[0] == '"' && retstr[len-1] == '"' ) + { + for (i=1,j=0; itype&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) + { + if ( strcmp(command,"signrawtransaction") != 0 ) + printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC (%s) error.%s\n",debugstr,command,rpcstr); + } + free(rpcstr); + } else retstr = rpcstr; + free_json(json); + //fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr); + return(retstr); +} +#endif + +#ifdef _WIN32 +#ifdef _MSC_VER +#define sleep(x) Sleep(1000*(x)) +#endif +#endif + +/************************************************************************ + * + * perform the query + * + ************************************************************************/ + +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) +{ + static int didinit,count,count2; static double elapsedsum,elapsedsum2; + struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; + char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; + if ( didinit == 0 ) + { + didinit = 1; + curl_global_init(CURL_GLOBAL_ALL); //init the curl session + } + numretries = 0; + if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 ) + specialcase = 1; + else specialcase = 0; + if ( url[0] == 0 ) + strcpy(url,"http://127.0.0.1:7876/nxt"); + if ( specialcase != 0 && 0 ) + printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params); +try_again: + if ( retstrp != 0 ) + *retstrp = 0; + starttime = OS_milliseconds(); + curl_handle = curl_easy_init(); + init_string(&s); + headers = curl_slist_append(0,"Expect:"); + + curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); + curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl_handle,CURLOPT_URL, url); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulatebytes); // send all data to this function + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback + curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash + curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback + if ( strncmp(url,"https",5) == 0 ) + { + curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); + curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0); + } + if ( userpass != 0 ) + curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass); + databuf = 0; + if ( params != 0 ) + { + if ( command != 0 && specialcase == 0 ) + { + len = strlen(params); + if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) { + bracket0 = bracket1 = (char *)""; + } + else + { + bracket0 = (char *)"["; + bracket1 = (char *)"]"; + } + + databuf = (char *)malloc(256 + strlen(command) + strlen(params)); + sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1); + //printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf); + // + } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params); + curl_easy_setopt(curl_handle,CURLOPT_POST,1L); + if ( databuf != 0 ) + curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf); + else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params); + } + //laststart = milliseconds(); + res = curl_easy_perform(curl_handle); + curl_slist_free_all(headers); + curl_easy_cleanup(curl_handle); + if ( databuf != 0 ) // clean up temporary buffer + { + free(databuf); + databuf = 0; + } + if ( res != CURLE_OK ) + { + numretries++; + if ( specialcase != 0 ) + { + printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); + free(s.ptr); + return(0); + } + else if ( numretries >= 1 ) + { + //printf("Maximum number of retries exceeded!\n"); + free(s.ptr); + return(0); + } + if ( (rand() % 1000) == 0 ) + printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); + free(s.ptr); + sleep((1< (%s)\n",params,s.ptr); + count2++; + elapsedsum2 += (OS_milliseconds() - starttime); + if ( (count2 % 10000) == 0) + printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command); + return(s.ptr); + } + } + printf("bitcoind_RPC: impossible case\n"); + free(s.ptr); + return(0); +} + +static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) +{ + size_t realsize = (size * nmemb); + struct MemoryStruct *mem = (struct MemoryStruct *)data; + mem->memory = (char *)((ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1)); + if ( mem->memory != 0 ) + { + if ( ptr != 0 ) + memcpy(&(mem->memory[mem->size]),ptr,realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + //printf("got %d bytes\n",(int32_t)(size*nmemb)); + return(realsize); +} + +char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3) +{ + struct MemoryStruct chunk; CURL *cHandle; long code; struct curl_slist *headers = 0; + if ( (cHandle= *cHandlep) == NULL ) + *cHandlep = cHandle = curl_easy_init(); + else curl_easy_reset(cHandle); + //#ifdef DEBUG + //curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1); + //#endif + curl_easy_setopt(cHandle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); + curl_easy_setopt(cHandle,CURLOPT_SSL_VERIFYPEER,0); + //curl_easy_setopt(cHandle,CURLOPT_SSLVERSION,1); + curl_easy_setopt(cHandle,CURLOPT_URL,url); + curl_easy_setopt(cHandle,CURLOPT_CONNECTTIMEOUT,10); + if ( userpass != 0 && userpass[0] != 0 ) + curl_easy_setopt(cHandle,CURLOPT_USERPWD,userpass); + if ( postfields != 0 && postfields[0] != 0 ) + { + curl_easy_setopt(cHandle,CURLOPT_POST,1); + curl_easy_setopt(cHandle,CURLOPT_POSTFIELDS,postfields); + } + if ( hdr0 != NULL && hdr0[0] != 0 ) + { + //printf("HDR0.(%s) HDR1.(%s) HDR2.(%s) HDR3.(%s)\n",hdr0!=0?hdr0:"",hdr1!=0?hdr1:"",hdr2!=0?hdr2:"",hdr3!=0?hdr3:""); + headers = curl_slist_append(headers,hdr0); + if ( hdr1 != 0 && hdr1[0] != 0 ) + headers = curl_slist_append(headers,hdr1); + if ( hdr2 != 0 && hdr2[0] != 0 ) + headers = curl_slist_append(headers,hdr2); + if ( hdr3 != 0 && hdr3[0] != 0 ) + headers = curl_slist_append(headers,hdr3); + } //headers = curl_slist_append(0,"Expect:"); + if ( headers != 0 ) + curl_easy_setopt(cHandle,CURLOPT_HTTPHEADER,headers); + //res = curl_easy_perform(cHandle); + memset(&chunk,0,sizeof(chunk)); + curl_easy_setopt(cHandle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback); + curl_easy_setopt(cHandle,CURLOPT_WRITEDATA,(void *)&chunk); + curl_easy_perform(cHandle); + curl_easy_getinfo(cHandle,CURLINFO_RESPONSE_CODE,&code); + if ( headers != 0 ) + curl_slist_free_all(headers); + if ( code != 200 ) + printf("(%s) server responded with code %ld (%s)\n",url,code,chunk.memory); + return(chunk.memory); +} + +uint16_t _komodo_userpass(char *username, char *password, FILE *fp) +{ + char *rpcuser,*rpcpassword,*str,*ipaddress,line[8192]; uint16_t port = 0; + rpcuser = rpcpassword = 0; + username[0] = password[0] = 0; + while ( fgets(line,sizeof(line),fp) != 0 ) + { + if ( line[0] == '#' ) + continue; + //printf("line.(%s) %p %p\n",line,strstr(line,(char *)"rpcuser"),strstr(line,(char *)"rpcpassword")); + if ( (str= strstr(line,(char *)"rpcuser")) != 0 ) + rpcuser = parse_conf_line(str,(char *)"rpcuser"); + else if ( (str= strstr(line,(char *)"rpcpassword")) != 0 ) + rpcpassword = parse_conf_line(str,(char *)"rpcpassword"); + else if ( (str= strstr(line,(char *)"rpcport")) != 0 ) + { + port = atoi(parse_conf_line(str,(char *)"rpcport")); + //fprintf(stderr,"rpcport.%u in file\n",port); + } + else if ( (str= strstr(line,(char *)"ipaddress")) != 0 ) + { + ipaddress = parse_conf_line(str,(char *)"ipaddress"); + strcpy(IPADDRESS,ipaddress); + } + } + if ( rpcuser != 0 && rpcpassword != 0 ) + { + strcpy(username,rpcuser); + strcpy(password,rpcpassword); + } + //printf("rpcuser.(%s) rpcpassword.(%s) %u ipaddress.%s\n",rpcuser,rpcpassword,port,ipaddress); + if ( rpcuser != 0 ) + free(rpcuser); + if ( rpcpassword != 0 ) + free(rpcpassword); + return(port); +} + +uint16_t komodo_userpass(char *userpass,char *symbol) +{ + FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN]; + userpass[0] = 0; + if ( strcmp("KMD",symbol) == 0 ) + { +#ifdef __APPLE__ + sprintf(confname,"Komodo.conf"); +#else + sprintf(confname,"komodo.conf"); +#endif + } + else sprintf(confname,"%s.conf",symbol); + //komodo_statefname(fname,symbol,confname); + if ( (fp= fopen(confname,"rb")) != 0 ) + { + port = _komodo_userpass(username,password,fp); + sprintf(userpass,"%s:%s",username,password); + if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 ) + strcpy(USERPASS,userpass); + fclose(fp); + } + return(port); +} + +#define is_cJSON_True(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_True) + +char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) +{ + //static void *cHandle; + char url[512],*retstr=0,*retstr2=0,postdata[8192]; + if ( params == 0 || params[0] == 0 ) + params = (char *)"[]"; + if ( strlen(params) < sizeof(postdata)-128 ) + { + sprintf(url,(char *)"http://%s:%u",IPADDRESS,port); + sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params); + //printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,USERPASS); + retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params); + //retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0); + } + return(retstr2); +} + +int32_t games_sendrawtransaction(char *rawtx) +{ + char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1; + params = (char *)malloc(strlen(rawtx) + 16); + sprintf(params,"[\"%s\"]",rawtx); + if ( (retstr= komodo_issuemethod(USERPASS,"sendrawtransaction",params,GAMES_PORT)) != 0 ) + { + if ( 0 ) // causes 4th level crash + { + static FILE *fp; + if ( fp == 0 ) + fp = fopen("games.sendlog","wb"); + if ( fp != 0 ) + { + fprintf(fp,"%s\n",retstr); + fflush(fp); + } + } + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (resobj= jobj(retjson,"result")) != 0 ) + { + if ( (hexstr= jstr(resobj,0)) != 0 && is_hexstr(hexstr,64) == 64 ) + retval = 0; + } + free_json(retjson); + } + + /* log sendrawtx result in file */ + + /* + FILE *debug_file; + debug_file = fopen("tx_debug.log", "a"); + fprintf(debug_file, "%s\n", retstr); + fflush(debug_file); + fclose(debug_file); + */ + + free(retstr); + } + free(params); + return(retval); +} + +int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) +{ + char cmd[16384],hexstr[16384],params[32768],*retstr,*errstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; + if ( rs->guiflag != 0 && Gametxidstr[0] != 0 ) + { + if ( rs->keystrokeshex != 0 ) + { + if ( games_sendrawtransaction(rs->keystrokeshex) == 0 ) + { + if ( waitflag == 0 ) + return(0); + else if ( 0 ) + { + while ( games_sendrawtransaction(rs->keystrokeshex) == 0 ) + { + //fprintf(stderr,"pre-rebroadcast\n"); + sleep(10); + } + } + } + free(rs->keystrokeshex), rs->keystrokeshex = 0; + } + if ( 0 && (pastkeys= games_keystrokesload(&numpastkeys,seed,1)) != 0 ) + { + sprintf(params,"[\"extract\",\"17\",\"[%%22%s%%22]\"]",Gametxidstr); + if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (resobj= jobj(retjson,"result")) != 0 && (keys= jstr(resobj,"keystrokes")) != 0 ) + { + len = strlen(keys) / 2; + pastcmp = (char *)malloc(len + 1); + decode_hex(pastcmp,len,keys); + fprintf(stderr,"keystrokes.(%s) vs pastkeys\n",keys); + for (i=0; i> keystrokes.log",ASSETCHAINS_SYMBOL,Gametxidstr,hexstr); + if ( system(cmd) != 0 ) + fprintf(stderr,"error issuing (%s)\n",cmd); + } + else + { + static FILE *fp; + if ( fp == 0 ) + fp = fopen("keystrokes.log","a"); + sprintf(params,"[\"keystrokes\",\"17\",\"[%%22%s%%22,%%22%s%%22]\"]",Gametxidstr,hexstr); + if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + { + if ( fp != 0 ) + { + fprintf(fp,"%s\n",params); + fprintf(fp,"%s\n",retstr); + fflush(fp); + } + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (resobj= jobj(retjson,"result")) != 0 && (rawtx= jstr(resobj,"hex")) != 0 ) + { + if ( rs->keystrokeshex != 0 ) + free(rs->keystrokeshex); + if ( (errstr= jstr(resobj,"error")) == 0 ) + { + rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1); + strcpy(rs->keystrokeshex,rawtx); + retflag = 1; + } else fprintf(stderr,"error sending keystrokes tx\n"), sleep(1); + //fprintf(stderr,"set keystrokestx <- %s\n",rs->keystrokeshex); + } + free_json(retjson); + } + free(retstr); + } + if ( 0 && waitflag != 0 && rs->keystrokeshex != 0 ) + { + while ( games_sendrawtransaction(rs->keystrokeshex) == 0 ) + { + //fprintf(stderr,"post-rebroadcast\n"); + sleep(3); + } + free(rs->keystrokeshex), rs->keystrokeshex = 0; + } + } + } + return(retflag); +} + +int32_t games_setplayerdata(struct games_state *rs,char *gametxidstr) +{ + char cmd[32768]; int32_t i,n,retval=-1; char params[1024],*filestr=0,*pname,*statusstr,*datastr,fname[128]; long allocsize; cJSON *retjson,*array,*item,*resultjson; + if ( rs->guiflag == 0 ) + return(-1); + if ( gametxidstr == 0 || *gametxidstr == 0 ) + return(retval); + if ( 0 ) + { + sprintf(fname,"%s.gameinfo",gametxidstr); + sprintf(cmd,"./komodo-cli -ac_name=%s cclib gameinfo 17 \\\"[%%22%s%%22]\\\" > %s",ASSETCHAINS_SYMBOL,gametxidstr,fname); + if ( system(cmd) != 0 ) + fprintf(stderr,"error issuing (%s)\n",cmd); + else filestr = (char *)OS_fileptr(&allocsize,fname); + } + else + { + sprintf(params,"[\"gameinfo\",\"17\",\"[%%22%s%%22]\"]",gametxidstr); + filestr = komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT); + } + if ( filestr != 0 ) + { + if ( (retjson= cJSON_Parse(filestr)) != 0 && (resultjson= jobj(retjson,"result")) != 0 ) + { + //fprintf(stderr,"gameinfo.(%s)\n",jprint(resultjson,0)); + if ( (array= jarray(&n,resultjson,"players")) != 0 ) + { + for (i=0; iP,(int32_t)strlen(datastr)/2,datastr); + fprintf(stderr,"set pname[%s] %s\n",pname==0?"":pname,jprint(item,0)); + rs->restoring = 1; + } + } + } + } + } + free_json(retjson); + } + free(filestr); + } + return(retval); +} + +#ifdef _WIN32 +#ifdef _MSC_VER +__inline int msver(void) { + switch (_MSC_VER) { + case 1500: return 2008; + case 1600: return 2010; + case 1700: return 2012; + case 1800: return 2013; + case 1900: return 2015; + //case 1910: return 2017; + default: return (_MSC_VER / 100); + } +} + +static inline bool is_x64(void) { +#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) + return 1; +#elif defined(__amd64__) || defined(__amd64) || defined(_M_X64) || defined(_M_IA64) + return 1; +#else + return 0; +#endif +} + +#define BUILD_DATE __DATE__ " " __TIME__ +#endif // _WIN32 +#endif // _MSC_VER + +int main(int argc, char **argv) +{ + uint64_t seed; FILE *fp = 0; int32_t i,j,c; char userpass[8192]; + +#ifdef _WIN32 +#ifdef _MSC_VER + printf("*** games for Windows [ Build %s ] ***\n", BUILD_DATE); + const char* arch = is_x64() ? "64-bits" : "32-bits"; + printf(" Built with VC++ %d (%ld) %s\n\n", msver(), _MSC_FULL_VER, arch); +#endif +#endif + + for (i=j=0; argv[0][i]!=0&&j= 2) { @@ -2531,5 +3521,6 @@ int main(int argc, char **argv) tg_delete(tg); return 0; } + #endif diff --git a/src/cc/rogue/cursesd.h b/src/cc/rogue/cursesd.h index cdad704ed..e3eec5d41 100644 --- a/src/cc/rogue/cursesd.h +++ b/src/cc/rogue/cursesd.h @@ -168,12 +168,15 @@ char *unctrl(char c); #define leaveok(win,bf) 0 #define halfdelay(x) 0 #define nocbreak() 0 + +// for tetris #define init_pair(a,b,c) 0 #define start_color() 0 #define box(a,b,c) 0 #define A_REVERSE 0 #define COLOR_PAIR(a) 0 #define timeout(x) 0 +// end for tetris #ifndef TRUE #define TRUE 1 From 1d57bee66d4697a550e1df72d80e03e20478201b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 08:54:27 -1100 Subject: [PATCH 57/84] Maketetris --- src/cc/gamescc.cpp | 4 +++- src/cc/maketetris | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 59adfae1d..454af601d 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -15,6 +15,8 @@ #include "gamescc.h" +#ifndef STANDALONE + /* ./c cclib rng 17 \"[%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,250]\" { @@ -1658,8 +1660,8 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) { sprintf(packitemstr,"not yet"); } +#else -#ifdef STANDALONE #include #include diff --git a/src/cc/maketetris b/src/cc/maketetris index 9c2a005a0..b83bef611 100755 --- a/src/cc/maketetris +++ b/src/cc/maketetris @@ -1,2 +1,2 @@ -gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -DSTANDALONE tetris.cpp -lncurses -o tetris +gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -DSTANDALONE gamescc.cpp -lncurses -o tetris From 3a7ca41dab30e01631befa8ca0ff02482ca5de4f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:13:13 -1100 Subject: [PATCH 58/84] Realtime events --- src/cc/gamescc.cpp | 56 +++++++++++++++++++++++++++++----------------- src/cc/gamescc.h | 12 ++++++++++ 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 454af601d..33d6722cd 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -336,12 +336,34 @@ int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector pay } else return(-1); } +int32_t games_event(uint32_t timestamp,uint256 gametxid,int32_t eventid,std::vector payload) +{ + std::vector sig,vopret; CPubKey mypk; uint32_t x; int32_t i,len = payload.size(); + payload.resize(len + 4 + 32); + for (i=0; i<32; i++) + payload[len++] = ((uint8_t *)&gametxid)[i]; + x = eventid; + payload[len++] = x, x >>= 8; + payload[len++] = x, x >>= 8; + payload[len++] = x, x >>= 8; + payload[len++] = x; + mypk = pubkey2pk(Mypubkey()); + if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) + { + GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); + games_payloadrecv(mypk,timestamp,payload); + komodo_sendmessage(4,8,"events",vopret); + return(0); + } else return(-1); +} + UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static uint256 lastgametxid; static uint32_t numevents; - UniValue result(UniValue::VOBJ); std::vector sig,payload,vopret; int32_t len,i,n; uint32_t x; CPubKey mypk; char str[67]; uint32_t eventid,timestamp = 0; uint256 gametxid; + UniValue result(UniValue::VOBJ); std::vector payload; int32_t len,i,n; uint32_t x; CPubKey mypk; char str[67]; uint32_t eventid,timestamp = 0; uint256 gametxid; if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 1 && n <= 3 ) { + mypk = pubkey2pk(Mypubkey()); if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 ) { if ( n >= 2 ) @@ -359,21 +381,8 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( numevents <= eventid ) numevents = eventid+1; } else eventid = numevents++; - len = payload.size(); - payload.resize(len + 4 + 32); - for (i=0; i<32; i++) - payload[len++] = ((uint8_t *)&gametxid)[i]; - x = eventid; - payload[len++] = x, x >>= 8; - payload[len++] = x, x >>= 8; - payload[len++] = x, x >>= 8; - payload[len++] = x; - mypk = pubkey2pk(Mypubkey()); - if ( games_eventsign(timestamp,sig,payload,mypk) == 0 ) + if ( games_event(timestamp,gametxid,eventid,payload) == 0 ) { - GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); - games_payloadrecv(mypk,timestamp,payload); - komodo_sendmessage(4,8,"events",vopret); result.push_back(Pair("gametxid",gametxid.GetHex())); result.push_back(Pair("eventid",(int64_t)eventid)); result.push_back(Pair("timestamp",(int64_t)timestamp)); @@ -2587,7 +2596,7 @@ static inline bool is_x64(void) { int main(int argc, char **argv) { uint64_t seed; FILE *fp = 0; int32_t i,j,c; char userpass[8192]; - + strcpy(ASSETCHAINS_SYMBOL,"GTEST"); #ifdef _WIN32 #ifdef _MSC_VER printf("*** games for Windows [ Build %s ] ***\n", BUILD_DATE); @@ -2610,8 +2619,8 @@ int main(int argc, char **argv) #ifdef _WIN32 #ifdef _MSC_VER - if (strncmp(ASSETCHAINS_SYMBOL, "TETRIS.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0 || strncmp(ASSETCHAINS_SYMBOL, "TETRIS54.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0) { - strcpy(ASSETCHAINS_SYMBOL, "TETRIS"); // accept TETRIS.conf, instead of TETRIS.EXE.conf or TETRIS54.EXE.conf if build with MSVC + if (strncmp(ASSETCHAINS_SYMBOL, "GTEST.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0 || strncmp(ASSETCHAINS_SYMBOL, "GTEST54.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0) { + strcpy(ASSETCHAINS_SYMBOL, "GTEST"); // accept TETRIS.conf, instead of TETRIS.EXE.conf or TETRIS54.EXE.conf if build with MSVC } #endif #endif @@ -3432,7 +3441,7 @@ int tetris(int argc, char **argv) tetris_move move = TM_NONE; bool running = true; WINDOW *board, *next, *hold, *score; - + int32_t c; uint256 gametxid; std::vector payload; uint32_t eventid = 0; // Load file if given a filename. if (argc >= 2) { FILE *f = fopen(argv[1], "r"); @@ -3462,6 +3471,7 @@ int tetris(int argc, char **argv) score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); int32_t counter = 0; // Game loop + payload.resize(1); while (running) { running = tg_tick(tg, move); display_board(board, tg); @@ -3471,8 +3481,12 @@ int tetris(int argc, char **argv) if ( (counter++ % 5) == 0 ) doupdate(); sleep_milli(10); - - switch (getch()) { + c = getch(); + payload[0] = c; + games_event(0,gametxid,eventid,payload); + eventid++; + switch ( c ) + { case KEY_LEFT: move = TM_LEFT; break; diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 8a6a3b656..9a48a14a4 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -96,6 +96,18 @@ struct games_player struct games_packitem gamespack[MAXPACK]; }; +struct games_state +{ + uint64_t seed; + char *keystrokes,*keystrokeshex; + uint32_t needflush,replaydone; + int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum; + FILE *logfp; + struct games_player P; + char buffered[10000]; + uint8_t playerdata[10000]; +}; + int32_t games_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); void games_packitemstr(char *packitemstr,struct games_packitem *item); From dfd756b938f96f3153d39099010bfd674fcd9a4d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:23:42 -1100 Subject: [PATCH 59/84] issue_games_events --- src/cc/gamescc.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 33d6722cd..c73b0e46f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2360,6 +2360,32 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) return(retstr2); } +int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) +{ + char params[512],*retstr; cJSON *retjson,*retobj; int32_t retval = -1; + sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",c,gametxid.GetHex().c_str(),eventid); + if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (resobj= jobj(retjson,"result")) != 0 ) + { + retval = 0; + if ( fp == 0 ) + fp = fopen("events.log","wb"); + if ( fp != 0 ) + { + fprintf(fp,"%s\n",jprint(resobj,0)); + fflush(fp); + } + } + free_json(retjson); + } + free(retstr); + } + return(retval); +} + int32_t games_sendrawtransaction(char *rawtx) { char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1; @@ -3483,7 +3509,7 @@ int tetris(int argc, char **argv) sleep_milli(10); c = getch(); payload[0] = c; - games_event(0,gametxid,eventid,payload); + issue_games_events(0,gametxid,eventid,payload); eventid++; switch ( c ) { From 3ee77bc360950fe63170783c3d59403b108692f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:26:42 -1100 Subject: [PATCH 60/84] Test --- src/cc/gamescc.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c73b0e46f..6ea6981c1 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2362,7 +2362,10 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) { + static FILE *fp; char params[512],*retstr; cJSON *retjson,*retobj; int32_t retval = -1; + if ( fp == 0 ) + fp = fopen("events.log","wb"); sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",c,gametxid.GetHex().c_str(),eventid); if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) { @@ -2371,8 +2374,6 @@ int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) if ( (resobj= jobj(retjson,"result")) != 0 ) { retval = 0; - if ( fp == 0 ) - fp = fopen("events.log","wb"); if ( fp != 0 ) { fprintf(fp,"%s\n",jprint(resobj,0)); @@ -2380,9 +2381,9 @@ int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) } } free_json(retjson); - } + } else fprintf(fp,"error parsing %s\n",jprint(retstr)); free(retstr); - } + } else fprintf(fp,"error issuing method %s\n",params); return(retval); } From 11b4733cb7e2c06e86764022cc730d76da1c4192 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:38:26 -1100 Subject: [PATCH 61/84] (char *) --- src/cc/gamescc.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 6ea6981c1..826012f43 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2363,15 +2363,15 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) { static FILE *fp; - char params[512],*retstr; cJSON *retjson,*retobj; int32_t retval = -1; + char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; if ( fp == 0 ) fp = fopen("events.log","wb"); sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",c,gametxid.GetHex().c_str(),eventid); - if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (resobj= jobj(retjson,"result")) != 0 ) + if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) { retval = 0; if ( fp != 0 ) @@ -2381,7 +2381,7 @@ int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) } } free_json(retjson); - } else fprintf(fp,"error parsing %s\n",jprint(retstr)); + } else fprintf(fp,"error parsing %s\n",retstr); free(retstr); } else fprintf(fp,"error issuing method %s\n",params); return(retval); @@ -2392,7 +2392,7 @@ int32_t games_sendrawtransaction(char *rawtx) char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1; params = (char *)malloc(strlen(rawtx) + 16); sprintf(params,"[\"%s\"]",rawtx); - if ( (retstr= komodo_issuemethod(USERPASS,"sendrawtransaction",params,GAMES_PORT)) != 0 ) + if ( (retstr= komodo_issuemethod(USERPASS,(char *)"sendrawtransaction",params,GAMES_PORT)) != 0 ) { if ( 0 ) // causes 4th level crash { @@ -2407,7 +2407,7 @@ int32_t games_sendrawtransaction(char *rawtx) } if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (resobj= jobj(retjson,"result")) != 0 ) + if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) { if ( (hexstr= jstr(resobj,0)) != 0 && is_hexstr(hexstr,64) == 64 ) retval = 0; @@ -2460,7 +2460,7 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,cha { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (resobj= jobj(retjson,"result")) != 0 && (keys= jstr(resobj,"keystrokes")) != 0 ) + if ( (resobj= jobj(retjson,(char *)"result")) != 0 && (keys= jstr(resobj,(char *)"keystrokes")) != 0 ) { len = strlen(keys) / 2; pastcmp = (char *)malloc(len + 1); @@ -2508,11 +2508,11 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,cha } if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (resobj= jobj(retjson,"result")) != 0 && (rawtx= jstr(resobj,"hex")) != 0 ) + if ( (resobj= jobj(retjson,(char *)"result")) != 0 && (rawtx= jstr(resobj,(char *)"hex")) != 0 ) { if ( rs->keystrokeshex != 0 ) free(rs->keystrokeshex); - if ( (errstr= jstr(resobj,"error")) == 0 ) + if ( (errstr= jstr(resobj,(char *)"error")) == 0 ) { rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1); strcpy(rs->keystrokeshex,rawtx); @@ -2556,26 +2556,26 @@ int32_t games_setplayerdata(struct games_state *rs,char *gametxidstr) else { sprintf(params,"[\"gameinfo\",\"17\",\"[%%22%s%%22]\"]",gametxidstr); - filestr = komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT); + filestr = komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT); } if ( filestr != 0 ) { - if ( (retjson= cJSON_Parse(filestr)) != 0 && (resultjson= jobj(retjson,"result")) != 0 ) + if ( (retjson= cJSON_Parse(filestr)) != 0 && (resultjson= jobj(retjson,(char *)"result")) != 0 ) { //fprintf(stderr,"gameinfo.(%s)\n",jprint(resultjson,0)); - if ( (array= jarray(&n,resultjson,"players")) != 0 ) + if ( (array= jarray(&n,resultjson,(char *)"players")) != 0 ) { for (i=0; iP,(int32_t)strlen(datastr)/2,datastr); fprintf(stderr,"set pname[%s] %s\n",pname==0?"":pname,jprint(item,0)); From 5f2317bd8e368933c94665ebff2dac682a6ff8eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:42:42 -1100 Subject: [PATCH 62/84] fixes --- src/cc/gamescc.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 826012f43..5217d5fa1 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1684,6 +1684,9 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; +#define MAX_STR 1024 +char whoami[MAXSTR]; + #define SMALLVAL 0.000000000000001 #define SATOSHIDEN ((uint64_t)100000000L) #define dstr(x) ((double)(x) / SATOSHIDEN) @@ -2433,7 +2436,7 @@ int32_t games_sendrawtransaction(char *rawtx) int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num) { - char cmd[16384],hexstr[16384],params[32768],*retstr,*errstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; + char cmd[16384],hexstr[16384],params[32768],*retstr,*errstr,*rawtx,*pastkeys,*keys; int32_t i,len,numpastkeys,retflag = -1; cJSON *retjson,*resobj; uint8_t *pastcmp; if ( rs->guiflag != 0 && Gametxidstr[0] != 0 ) { if ( rs->keystrokeshex != 0 ) @@ -2456,7 +2459,7 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,cha if ( 0 && (pastkeys= games_keystrokesload(&numpastkeys,seed,1)) != 0 ) { sprintf(params,"[\"extract\",\"17\",\"[%%22%s%%22]\"]",Gametxidstr); - if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -2498,7 +2501,7 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,cha if ( fp == 0 ) fp = fopen("keystrokes.log","a"); sprintf(params,"[\"keystrokes\",\"17\",\"[%%22%s%%22,%%22%s%%22]\"]",Gametxidstr,hexstr); - if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( fp != 0 ) { @@ -3510,7 +3513,7 @@ int tetris(int argc, char **argv) sleep_milli(10); c = getch(); payload[0] = c; - issue_games_events(0,gametxid,eventid,payload); + issue_games_events(gametxid,eventid,payload); eventid++; switch ( c ) { From 89f6370c5e66aea81ec14fb7e55c64e0e02c9af0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:44:58 -1100 Subject: [PATCH 63/84] Test --- src/cc/gamescc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 5217d5fa1..2f68fdfd8 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -13,10 +13,11 @@ * * ******************************************************************************/ -#include "gamescc.h" #ifndef STANDALONE +#include "gamescc.h" + /* ./c cclib rng 17 \"[%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,250]\" { @@ -1684,7 +1685,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; -#define MAX_STR 1024 +#define MAXSTR 1024 char whoami[MAXSTR]; #define SMALLVAL 0.000000000000001 @@ -2466,7 +2467,7 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,cha if ( (resobj= jobj(retjson,(char *)"result")) != 0 && (keys= jstr(resobj,(char *)"keystrokes")) != 0 ) { len = strlen(keys) / 2; - pastcmp = (char *)malloc(len + 1); + pastcmp = (uint8_t *)malloc(len + 1); decode_hex(pastcmp,len,keys); fprintf(stderr,"keystrokes.(%s) vs pastkeys\n",keys); for (i=0; i Date: Mon, 25 Mar 2019 09:47:58 -1100 Subject: [PATCH 64/84] #include "../core_io.h" #include "../script/sign.h" #include "../wallet/wallet.h" #include --- src/cc/gamescc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 2f68fdfd8..de08b8992 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1681,6 +1681,9 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include #include +#include "../core_io.h" +#include "../wallet/wallet.h" +#include char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; From 43b96f15b9ed811c94433b246dde54e0f2526d66 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:52:12 -1100 Subject: [PATCH 65/84] Ifdef --- src/cc/gamescc.cpp | 3 ++- src/cc/gamescc.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index de08b8992..0721e88fe 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -13,10 +13,11 @@ * * ******************************************************************************/ +#include "gamescc.h" + #ifndef STANDALONE -#include "gamescc.h" /* ./c cclib rng 17 \"[%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,250]\" diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 9a48a14a4..b6b53e82e 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -1,6 +1,8 @@ #ifndef H_GAMESCC_H #define H_GAMESCC_H +#ifndef STANDALONE + #define ENABLE_WALLET extern CWallet* pwalletMain; @@ -82,6 +84,7 @@ if ( cp->evalcode == EVAL_GAMES ) \ return(result); \ } \ } +#endif #define MAXPACK 23 struct games_packitem From d4d7d1adfdb6ab8cfab9f2e6a8129ff6fd9893f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:53:19 -1100 Subject: [PATCH 66/84] Stdio --- src/cc/gamescc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index b6b53e82e..034fee044 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -1,6 +1,9 @@ #ifndef H_GAMESCC_H #define H_GAMESCC_H +#include +#include + #ifndef STANDALONE #define ENABLE_WALLET From e774c89ab5c37ec3329dcc359cb6d1bc2a8cfd6f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:55:11 -1100 Subject: [PATCH 67/84] -stdlib --- src/cc/gamescc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 0721e88fe..57ff21131 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1676,7 +1676,6 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include -#include #include #include #include From e7031c29640864a0e8d109bb3a3c1593c09b25d4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:58:21 -1100 Subject: [PATCH 68/84] Test --- src/cc/gamescc.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 57ff21131..ffb92bc0d 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1679,12 +1679,15 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include #include -#include -#include #include "../core_io.h" #include "../wallet/wallet.h" #include +#define inline +#include +#include +#undef inline + char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; @@ -3475,7 +3478,7 @@ int tetris(int argc, char **argv) tetris_move move = TM_NONE; bool running = true; WINDOW *board, *next, *hold, *score; - int32_t c; uint256 gametxid; std::vector payload; uint32_t eventid = 0; + int32_t c; uint256 gametxid; uint32_t eventid = 0; // Load file if given a filename. if (argc >= 2) { FILE *f = fopen(argv[1], "r"); @@ -3516,8 +3519,7 @@ int tetris(int argc, char **argv) doupdate(); sleep_milli(10); c = getch(); - payload[0] = c; - issue_games_events(gametxid,eventid,payload); + issue_games_events(gametxid,eventid,c); eventid++; switch ( c ) { From 23cd6f2cbef1aab8af7b2606358085dddfbecb4f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 09:58:56 -1100 Subject: [PATCH 69/84] Mv --- src/cc/gamescc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index ffb92bc0d..cc78ee5fe 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1679,13 +1679,13 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include #include -#include "../core_io.h" -#include "../wallet/wallet.h" -#include #define inline #include #include +#include "../core_io.h" +#include "../wallet/wallet.h" +#include #undef inline char USERPASS[8192]; uint16_t GAMES_PORT; From 901bc3fc952d0a3311a275fcabda8413372c5814 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:00:52 -1100 Subject: [PATCH 70/84] Test --- src/cc/gamescc.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index cc78ee5fe..9ec9f3cb0 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1679,14 +1679,8 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include #include - -#define inline #include #include -#include "../core_io.h" -#include "../wallet/wallet.h" -#include -#undef inline char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; From 6bce1c76135f585f3b9bf8e9b6443d411a960e61 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:03:02 -1100 Subject: [PATCH 71/84] Test --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 9ec9f3cb0..229e7d066 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2364,7 +2364,7 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) return(retstr2); } -int32_t issue_games_events(uint256 gametxid,uint32_t eventid,char c) +int32_t issue_games_events(bits256 gametxid,uint32_t eventid,char c) { static FILE *fp; char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; @@ -3472,7 +3472,7 @@ int tetris(int argc, char **argv) tetris_move move = TM_NONE; bool running = true; WINDOW *board, *next, *hold, *score; - int32_t c; uint256 gametxid; uint32_t eventid = 0; + int32_t c; bits256 gametxid; uint32_t eventid = 0; // Load file if given a filename. if (argc >= 2) { FILE *f = fopen(argv[1], "r"); From 28f2d009b96e387c49f90e81c5ba98213e655c21 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:06:05 -1100 Subject: [PATCH 72/84] Void *malloc --- src/cc/gamescc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 229e7d066..1c5818568 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1682,6 +1682,8 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include +void *malloc(size_t size); + char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; @@ -2367,10 +2369,10 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) int32_t issue_games_events(bits256 gametxid,uint32_t eventid,char c) { static FILE *fp; - char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; + char params[512],*retstr,str[65]; cJSON *retjson,*resobj; int32_t retval = -1; if ( fp == 0 ) fp = fopen("events.log","wb"); - sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",c,gametxid.GetHex().c_str(),eventid); + sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",c,bits256_str(str,gametxid),eventid); if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -3502,7 +3504,6 @@ int tetris(int argc, char **argv) score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); int32_t counter = 0; // Game loop - payload.resize(1); while (running) { running = tg_tick(tg, move); display_board(board, tg); From a19b854238731b7373f73ad728b7c620031774e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:09:35 -1100 Subject: [PATCH 73/84] -def --- src/cc/gamescc.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 1c5818568..81bd3f48b 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1682,8 +1682,6 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include #include -void *malloc(size_t size); - char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; From 09589bd0e04aa334290418317447a73715531829 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:11:31 -1100 Subject: [PATCH 74/84] Test --- src/cc/gamescc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 81bd3f48b..34d0740c4 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1861,7 +1861,7 @@ long _stripwhite(char *buf,int accept) char *clonestr(char *str) { - char *clone; + char *clone; int32_t len; if ( str == 0 || str[0] == 0 ) { printf("warning cloning nullstr.%p\n",str); @@ -1870,7 +1870,8 @@ char *clonestr(char *str) #endif str = (char *)""; } - clone = (char *)malloc(strlen(str)+16); + len = strlen(str); + clone = (char *)malloc(len+16); strcpy(clone,str); return(clone); } From ce31112c570f45661be5a1586baf434844aad59b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:12:09 -1100 Subject: [PATCH 75/84] Calloc --- src/cc/gamescc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 34d0740c4..4d461ee08 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1871,7 +1871,7 @@ char *clonestr(char *str) str = (char *)""; } len = strlen(str); - clone = (char *)malloc(len+16); + clone = (char *)calloc(1,len+16); strcpy(clone,str); return(clone); } From f83da7830241f3c22878b8a279be2fa1971f6ea9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:14:14 -1100 Subject: [PATCH 76/84] char *clonestr(char *str) --- src/cc/gamescc.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 4d461ee08..cd87e9995 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1684,6 +1684,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) char USERPASS[8192]; uint16_t GAMES_PORT; extern char Gametxidstr[67]; +char *clonestr(char *str); #define MAXSTR 1024 char whoami[MAXSTR]; @@ -1859,23 +1860,6 @@ long _stripwhite(char *buf,int accept) return(j); } -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - char *parse_conf_line(char *line,char *field) { line += strlen(field); @@ -2722,6 +2706,22 @@ int main(int argc, char **argv) #include #endif +char *clonestr(char *str) +{ + char *clone; int32_t len; + if ( str == 0 || str[0] == 0 ) + { + printf("warning cloning nullstr.%p\n",str); +#ifdef __APPLE__ + while ( 1 ) sleep(1); +#endif + str = (char *)""; + } + len = strlen(str); + clone = (char *)calloc(1,len+16); + strcpy(clone,str); + return(clone); +} /* Convert a tetromino type to its corresponding cell. From 8665d036e6abc1718c145ee02a7508b06193d0ab Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:15:27 -1100 Subject: [PATCH 77/84] char *clonestr(char *str) --- src/cc/gamescc.cpp | 2 +- src/cc/maketetris | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index cd87e9995..fa36e8537 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -1683,7 +1683,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item) #include char USERPASS[8192]; uint16_t GAMES_PORT; -extern char Gametxidstr[67]; +char Gametxidstr[67]; char *clonestr(char *str); #define MAXSTR 1024 diff --git a/src/cc/maketetris b/src/cc/maketetris index b83bef611..9f0af354e 100755 --- a/src/cc/maketetris +++ b/src/cc/maketetris @@ -1,2 +1,2 @@ -gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -DSTANDALONE gamescc.cpp -lncurses -o tetris +gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -DSTANDALONE gamescc.cpp -lncurses -lcurl -o tetris From be9c3500ac7c7d8170c908580f8bf97c12f2faff Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:17:38 -1100 Subject: [PATCH 78/84] Games replay --- src/cc/gamescc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index fa36e8537..9fb135dfe 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -3568,5 +3568,10 @@ int tetris(int argc, char **argv) return 0; } +int32_t games_replay(uint64_t seed,int32_t sleeptime) +{ + return(-1); +} + #endif From 361c928fc835fa1bfca5124ca28f946f40092fc3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:20:53 -1100 Subject: [PATCH 79/84] Move clonestr --- src/cc/gamescc.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 9fb135dfe..ca9419d83 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2706,23 +2706,6 @@ int main(int argc, char **argv) #include #endif -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - /* Convert a tetromino type to its corresponding cell. */ @@ -3466,6 +3449,22 @@ void init_colors(void) Main tetris game! */ #ifdef STANDALONE +char *clonestr(char *str) +{ + char *clone; int32_t len; + if ( str == 0 || str[0] == 0 ) + { + printf("warning cloning nullstr.%p\n",str); +#ifdef __APPLE__ + while ( 1 ) sleep(1); +#endif + str = (char *)""; + } + len = strlen(str); + clone = (char *)calloc(1,len+16); + strcpy(clone,str); + return(clone); +} int tetris(int argc, char **argv) { From 63ebb9d604ed36af16de650e183a14ba03e35ad0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:25:44 -1100 Subject: [PATCH 80/84] strcpy(ASSETCHAINS_SYMBOL,"GTEST"); --- src/cc/gamescc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index ca9419d83..85f01ba43 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -2612,7 +2612,6 @@ static inline bool is_x64(void) { int main(int argc, char **argv) { uint64_t seed; FILE *fp = 0; int32_t i,j,c; char userpass[8192]; - strcpy(ASSETCHAINS_SYMBOL,"GTEST"); #ifdef _WIN32 #ifdef _MSC_VER printf("*** games for Windows [ Build %s ] ***\n", BUILD_DATE); @@ -2640,7 +2639,8 @@ int main(int argc, char **argv) } #endif #endif - + strcpy(ASSETCHAINS_SYMBOL,"GTEST"); + GAMES_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL); if ( IPADDRESS[0] == 0 ) strcpy(IPADDRESS,"127.0.0.1"); From ab954658167edf41a0233fd0ac0cc3cadde87ddd Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:45:04 -1100 Subject: [PATCH 81/84] Test --- src/cc/gamescc.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 85f01ba43..c80c4e161 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -387,6 +387,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { result.push_back(Pair("gametxid",gametxid.GetHex())); result.push_back(Pair("eventid",(int64_t)eventid)); + result.push_back(Pair("payload",jstr(jitem(params,0),0))); result.push_back(Pair("timestamp",(int64_t)timestamp)); result.push_back(Pair("result","success")); result.push_back(Pair("pubkey33",pubkey33_str(str,(uint8_t *)&mypk))); @@ -436,9 +437,9 @@ void komodo_netevent(std::vector message) } } } - for (i=0; i= 2) { FILE *f = fopen(argv[1], "r"); From 2a4a05055748694b8b49d1d44d72610bc6233ed2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 10:49:02 -1100 Subject: [PATCH 82/84] Test --- src/cc/gamescc.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c80c4e161..7f7b15c89 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -51,6 +51,24 @@ ./c cclib events 17 \"[%226d%22,%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,1]\" */ +int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) +{ + uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; + if ( (len= payload.size()) > 36 ) + { + len -= 36; + for (i=0; i<32; i++) + ((uint8_t *)&gametxid)[i] = payload[len+i]; + eventid = (uint32_t)payload[len+32]; + eventid |= (uint32_t)payload[len+33] << 8; + eventid |= (uint32_t)payload[len+34] << 16; + eventid |= (uint32_t)payload[len+35] << 24; + for (i=0; i &sig,std::vecto } else return(-1); } -int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) -{ - uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; - if ( (len= payload.size()) > 36 ) - { - len -= 36; - for (i=0; i<32; i++) - ((uint8_t *)&gametxid)[i] = payload[len+i]; - eventid = (uint32_t)payload[len+32]; - eventid |= (uint32_t)payload[len+33] << 8; - eventid |= (uint32_t)payload[len+34] << 16; - eventid |= (uint32_t)payload[len+35] << 24; - for (i=0; i payload) { std::vector sig,vopret; CPubKey mypk; uint32_t x; int32_t i,len = payload.size(); @@ -3514,7 +3513,8 @@ int tetris(int argc, char **argv) doupdate(); sleep_milli(10); c = getch(); - issue_games_events(gametxid,eventid,c); + if ( c >= 0 ) + issue_games_events(gametxid,eventid,c); eventid++; switch ( c ) { From 9277db7e1e0beef080feb6f753e79724c36899d8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 11:11:24 -1100 Subject: [PATCH 83/84] Skip count --- src/cc/gamescc.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index 7f7b15c89..b355584db 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -3472,7 +3472,7 @@ int tetris(int argc, char **argv) tetris_move move = TM_NONE; bool running = true; WINDOW *board, *next, *hold, *score; - int32_t c; bits256 gametxid; uint32_t eventid = 0; + int32_t c,skipcount=0; bits256 gametxid; uint32_t eventid = 0; memset(&gametxid,0,sizeof(gametxid)); // Load file if given a filename. if (argc >= 2) { @@ -3514,7 +3514,12 @@ int tetris(int argc, char **argv) sleep_milli(10); c = getch(); if ( c >= 0 ) + { + if ( skipcount > 0 ) + issue_games_events(gametxid,eventid-skipcount,skipcount | 0x4000); issue_games_events(gametxid,eventid,c); + skipcount = 0; + } else skipcount++; eventid++; switch ( c ) { From 81006ce271fc91f09abe725c580ea8d1acc030f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 25 Mar 2019 11:50:08 -1100 Subject: [PATCH 84/84] Match rogue roc --- src/cc/gamescc.cpp | 6 +++--- src/cc/gamescc.h | 37 ++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index b355584db..758d2fc78 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -964,7 +964,7 @@ void games_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gamet } else fprintf(stderr,"findbaton err.%d\n",retval); } -UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +UniValue games_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey gamespk,mypk; char *jsonstr; uint64_t inputsum,change,required,buyin=0; int32_t i,n,maxplayers = 1; @@ -1030,7 +1030,7 @@ UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +UniValue games_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myaddr[64],str[64]; CPubKey mypk,gamespk; result.push_back(Pair("name","games")); @@ -1599,7 +1599,7 @@ UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +UniValue games_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); uint256 txid,hashBlock,gametxid,tokenid,playertxid; int32_t vout,maxplayers,gameheight,numvouts; CPubKey gamespk,mypk; char coinaddr[64]; CTransaction tx,gametx; int64_t buyin; std::vector > addressIndex; diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index 034fee044..19e5f8d26 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -35,29 +35,28 @@ std::string Games_pname; { (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"players", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"list", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"games", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"pending", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"setname", (char *)"pname", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"create", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"newgame", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"playerinfo", (char *)"playertxid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"info", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ + { (char *)MYCCNAME, (char *)"gameinfo", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"keystrokes", (char *)"txid,hexstr", 2, 2, 'K', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"finish", (char *)"gametxid", 1, 1, 'Q', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, ' ', EVAL_GAMES }, \ { (char *)MYCCNAME, (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_GAMES }, - bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_list(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); @@ -71,14 +70,30 @@ if ( cp->evalcode == EVAL_GAMES ) \ return(games_rng(txfee,cp,params)); \ else if ( strcmp(method,"rngnext") == 0 ) \ return(games_rngnext(txfee,cp,params)); \ - else if ( strcmp(method,"create") == 0 ) \ - return(games_create(txfee,cp,params)); \ - else if ( strcmp(method,"info") == 0 ) \ - return(games_info(txfee,cp,params)); \ + else if ( strcmp(method,"newgame") == 0 ) \ + return(games_newgame(txfee,cp,params)); \ + else if ( strcmp(method,"gameinfo") == 0 ) \ + return(games_gameinfo(txfee,cp,params)); \ else if ( strcmp(method,"register") == 0 ) \ return(games_register(txfee,cp,params)); \ else if ( strcmp(method,"events") == 0 ) \ return(games_events(txfee,cp,params)); \ + else if ( strcmp(method,"players") == 0 ) \ + return(games_players(txfee,cp,params)); \ + else if ( strcmp(method,"games") == 0 ) \ + return(games_games(txfee,cp,params)); \ + else if ( strcmp(method,"pending") == 0 ) \ + return(games_pending(txfee,cp,params)); \ + else if ( strcmp(method,"setname") == 0 ) \ + return(games_setname(txfee,cp,params)); \ + else if ( strcmp(method,"playerinfo") == 0 ) \ + return(games_playerinfo(txfee,cp,params)); \ + else if ( strcmp(method,"keystrokes") == 0 ) \ + return(games_keystrokes(txfee,cp,params)); \ + else if ( strcmp(method,"extract") == 0 ) \ + return(games_extract(txfee,cp,params)); \ + else if ( strcmp(method,"finish") == 0 ) \ + return(games_finish(txfee,cp,params)); \ else \ { \ result.push_back(Pair("result","error")); \