diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index c01a89b69..063da9355 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -16,6 +16,9 @@ #include "gamescc.h" #include "tetris.c" // replace with game code +int32_t GAMEDATA(struct games_player *P,void *ptr); +void GAMEJSON(UniValue &obj,struct games_player *P); + uint64_t _games_rngnext(uint64_t initseed) { uint16_t seeds[4]; int32_t i; @@ -92,19 +95,6 @@ gamesevent games_readevent(struct games_state *rs) //_quit(); return(27); } - /*if ( rs != 0 && rs->guiflag != 0 ) - { - if ( rs->num < sizeof(rs->buffered) ) - { - rs->buffered[rs->num++] = ch; - if ( rs->num > (sizeof(rs->buffered)*9)/10 && rs->needflush == 0 ) - { - rs->needflush = (uint32_t)time(NULL); - //fprintf(stderr,"needflush.%u %d of %d\n",rs->needflush,rs->num,(int32_t)sizeof(rs->buffered)); - //sleep(3); - } - } else fprintf(stderr,"buffer filled without flushed\n"); - }*/ } else fprintf(stderr,"readchar rs.%p non-gui error?\n",rs); return(ch); } @@ -121,7 +111,6 @@ int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int3 { rs->P = *player; rs->restoring = 1; - //fprintf(stderr,"restore player packsize.%d HP.%d\n",rs->P.packsize,rs->P.hitpoints); if ( rs->P.packsize > MAXPACK ) rs->P.packsize = MAXPACK; } @@ -150,14 +139,15 @@ int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int3 /*if ( (fp= fopen("checkfile","wb")) != 0 ) { //save_file(rs,fp,0); - //fprintf(stderr,"gold.%d hp.%d strength.%d/%d level.%d exp.%d dungeon.%d data[%d]\n",rs->P.gold,rs->P.hitpoints,rs->P.strength&0xffff,rs->P.strength>>16,rs->P.level,rs->P.experience,rs->P.dungeonlevel,rs->playersize); if ( newdata != 0 && rs->playersize > 0 ) memcpy(newdata,rs->playerdata,rs->playersize); }*/ if ( ptr != 0 ) { // extract data from ptr - if ( newdata != 0 && rs->playersize > 0 ) + if ( GAMEDATA(&rs->P,ptr) < 0 ) + memset(&rs->P,0,sizeof(rs->P)); + else if ( newdata != 0 && rs->playersize > 0 ) memcpy(newdata,rs->playerdata,rs->playersize); free(ptr); } @@ -695,7 +685,6 @@ UniValue games_playerobj(std::vector playerdata,uint256 playertxid,uint } datastr[i<<1] = 0; } - int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,pad; for (i=0; i playerdata,uint256 playertxid,uint 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)); + GAMEPLAYERJSON(obj,&P); obj.push_back(Pair("chain",symbol)); obj.push_back(Pair("pname",pname)); return(obj); @@ -834,6 +817,24 @@ int32_t games_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx, return(0); } +int64_t games_buyins(uint256 gametxid) +{ + int32_t i,vout; uint256 spenttxid,hashBlock; CTransaction spenttx; int64_t buyins = 0; + for (i=0; i= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + { + if ( spenttx.vout[0].nValue > GAMES_REGISTRATIONSIZE ) + buyins += (spenttx.vout[0].nValue - GAMES_REGISTRATIONSIZE); + } //else fprintf(stderr,"cant find spenttxid.%s\n",spenttxid.GetHex().c_str()); + } //else fprintf(stderr,"vout %d is unspent\n",vout); + } + return(buyins); +} + 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; @@ -861,6 +862,7 @@ uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 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("buyins",ValueFromAmount(game_buyins(gametxid)))); } obj.push_back(Pair("maxplayers",maxplayers)); obj.push_back(Pair("buyin",ValueFromAmount(buyin))); @@ -885,6 +887,27 @@ UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } else return(cclib_error(result,"couldnt reparse params")); } +void disp_gamesplayerdata(std::vector playerdata) +{ + struct games_player P; int32_t i; char packitemstr[512],line[512]; + if ( playerdata.size() > 0 ) + { + for (i=0; i &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]; gamesevent *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; + //fprintf(stderr,"got baton\n"); + 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); + } + else + { + *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; gamesevent *keystrokes = 0; std::vector newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33]; @@ -1380,7 +1478,7 @@ UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params,char *method) { //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 @@ -1393,8 +1491,8 @@ 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 = (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]; gamesevent *keystrokes = 0; std::vector playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,gamespk; uint8_t player[10000],mypriv[32],funcid; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + 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,numkeys,maxplayers,batonht,batonvout; char mygamesaddr[64]; gamesevent *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 ) @@ -1452,11 +1550,10 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) newdata[i] = player[i]; ((uint8_t *)&P)[i] = player[i]; } - if ( (P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0) ) + if ( disp_gamesplayer(str,&P) < 0 ) { //fprintf(stderr,"zero value character was killed -> no playerdata\n"); newdata.resize(0); - //P.gold = (P.gold * 8) / 10; } else { @@ -1464,7 +1561,7 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) 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); + fprintf(stderr,"\ncashout %.8f extracted %s\n",(double)cashout/COIN,str); if ( funcid == 'H' && maxplayers > 1 ) { if ( P.amulet == 0 ) @@ -1474,7 +1571,7 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) 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; + cashout += games_buyins(gametxid);//numplayers * buyin; } if ( cashout > 0 ) { @@ -1516,6 +1613,16 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } +UniValue games_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + return(games_finish(txfee,cp,params,"bailout")); +} + +UniValue games_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + return(games_finish(txfee,cp,params,"highlander")); +} + 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]; @@ -1638,6 +1745,59 @@ UniValue games_fund(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } +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],gamesaddr[64],str2[67],fname[64]; gamesevent *keystrokes; int32_t i,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; ievalcode == EVAL_GAMES ) \ 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 if ( strcmp(method,"bailout") == 0 ) \ + return(games_bailout(txfee,cp,params)); \ + else if ( strcmp(method,"highlander") == 0 ) \ + return(games_highlander(txfee,cp,params)); \ else if ( strcmp(method,"fund") == 0 ) \ return(games_fund(txfee,cp,params)); \ else \ diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index ee5f3d566..4b74e21b7 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -283,6 +283,24 @@ int32_t rogue_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx, return(0); } +int64_t rogue_buyins(uint256 gametxid) +{ + int32_t i,vout; uint256 spenttxid,hashBlock; CTransaction spenttx; int64_t buyins = 0; + for (i=0; i= 0 ) + { + if ( myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() > 0 ) + { + if ( spenttx.vout[0].nValue > ROGUE_REGISTRATIONSIZE ) + buyins += (spenttx.vout[0].nValue - ROGUE_REGISTRATIONSIZE); + } //else fprintf(stderr,"cant find spenttxid.%s\n",spenttxid.GetHex().c_str()); + } //else fprintf(stderr,"vout %d is unspent\n",vout); + } + return(buyins); +} + int32_t rogue_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 roguepk; uint64_t txfee = 10000; @@ -690,6 +708,7 @@ uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 obj.push_back(Pair("alive",rogue_playersalive(openslots,numplayers,gametxid,maxplayers,ht,tx))); obj.push_back(Pair("openslots",openslots)); obj.push_back(Pair("numplayers",numplayers)); + obj.push_back(Pair("buyins",ValueFromAmount(rogue_buyins(gametxid)))); } obj.push_back(Pair("maxplayers",maxplayers)); obj.push_back(Pair("buyin",ValueFromAmount(buyin))); @@ -1093,6 +1112,20 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } +int64_t rogue_cashout(struct rogue_player *P) +{ + int32_t dungeonlevel; int64_t mult = 10; + if ( P->amulet != 0 ) + mult *= 5; + dungeonlevel = P->dungeonlevel; + if ( P->amulet != 0 && dungeonlevel < 26 ) + dungeonlevel = 26; + if ( dungeonlevel > 42 ) + dungeonlevel = 42; + cashout = (uint64_t)P->gold * P->gold * mult * dungeonlevel; + return(cashout); +} + int32_t rogue_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; @@ -1105,17 +1138,9 @@ int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct C free(keystrokes); sprintf(fname,"rogue.%llu.pack",(long long)seed); remove(fname); - for (i=0; i 42 ) - dungeonlevel = 42; - *cashoutp = (uint64_t)P.gold * P.gold * mult * dungeonlevel; + *cashoutp = rogue_cashout(&P); if ( newdata == playerdata ) { if ( gametxid != prevgame ) @@ -1206,16 +1231,10 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param result.push_back(Pair("name","rogue")); result.push_back(Pair("method",method)); result.push_back(Pair("myrogueaddr",myrogueaddr)); + mult = 10; //100000; if ( strcmp(method,"bailout") == 0 ) - { funcid = 'Q'; - mult = 10; //100000; - } - else - { - funcid = 'H'; - mult = 20; //200000; - } + else funcid = 'H'; if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) { if ( n > 0 ) @@ -1264,13 +1283,10 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param 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)); - if ( P.amulet != 0 ) - mult *= 5; - dungeonlevel = P.dungeonlevel; - if ( P.amulet != 0 && dungeonlevel < 26 ) - dungeonlevel = 26; - cashout = (uint64_t)P.gold * P.gold * mult * dungeonlevel; + cashout = rogue_cashout(&P); fprintf(stderr,"\nextracted $$$gold.%d -> %.8f ROGUE 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 ( komodo_nextheight() > 77777 && cashout > ROGUE_MAXCASHOUT ) + cashout = ROGUE_MAXCASHOUT; if ( funcid == 'H' && maxplayers > 1 ) { if ( P.amulet == 0 ) @@ -1280,12 +1296,11 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param else if ( rogue_playersalive(tmp,tmp,gametxid,maxplayers,gameheight,gametx) > 1 ) return(cclib_error(result,"highlander must be a winner or last one standing")); } + cashout *= 2; cashout += numplayers * buyin; } if ( cashout > 0 ) { - if ( komodo_nextheight() > 77777 && cashout > ROGUE_MAXCASHOUT ) - cashout = ROGUE_MAXCASHOUT; if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,cashout,60,cp->unspendableCCaddr)) > cashout ) CCchange = (inputsum - cashout); else fprintf(stderr,"couldnt find enough utxos\n"); @@ -1598,13 +1613,13 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C if ( enabled != 0 ) return eval->Invalid("mismatched playerdata"); } + if ( height > 777777 && cashout > ROGUE_MAXCASHOUT ) + cashout = ROGUE_MAXCASHOUT; if ( funcid == 'H' ) { cashout *= 2; - //cashout += numplayers * buyin; + cashout += rogue_buyins(gametxid); } - if ( height > 777777 && cashout > ROGUE_MAXCASHOUT ) - cashout = ROGUE_MAXCASHOUT; 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 ) { diff --git a/src/cc/tetris.c b/src/cc/tetris.c index bd9a5526d..54ca3b953 100644 --- a/src/cc/tetris.c +++ b/src/cc/tetris.c @@ -7,12 +7,20 @@ also, the standalone game needs to support argv of seed gametxid, along with replay args */ -static int random_tetromino(struct games_state *rs) +int random_tetromino(struct games_state *rs) { rs->seed = _games_rngnext(rs->seed); return(rs->seed % NUM_TETROMINOS); } +int32_t tetrisdata(struct games_player *P,void *ptr) +{ + tetris_game *tg = ptr; + P->gold = tg->points; + P->dungeonlevel = tg->level; + return(0); +} + /***************************************************************************/ /** https://github.com/brenns10/tetris @file main.c @@ -676,7 +684,7 @@ void *gamesiterate(struct games_state *rs) if ( rs->guiflag != 0 ) { #ifdef STANDALONE - sleep_milli(10); + sleep_milli(25); c = games_readevent(rs); if ( c <= 0x7f || skipcount == 0x3fff ) { diff --git a/src/cc/tetris.cpp b/src/cc/tetris.cpp index 7f601bb56..e44b50925 100644 --- a/src/cc/tetris.cpp +++ b/src/cc/tetris.cpp @@ -14,14 +14,37 @@ * * ******************************************************************************/ -int32_t games_findbaton(struct CCcontract_info *cp,uint256 &playertxid,gamesevent **keystrokesp,int32_t &numkeys,int32_t ®slot,std::vector &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 games_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransaction &tx,int64_t &buyin,int32_t &maxplayers,uint256 txid,int32_t unspentv0); -uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *mygamesaddr); - // game specific code for daemon void games_packitemstr(char *packitemstr,struct games_packitem *item) { - sprintf(packitemstr,"not yet"); + sprintf(packitemstr,""); +} + +int64_t games_cashout(struct games_player *P) +{ + int32_t dungeonlevel = P->dungeonlevel; int64_t mult=1000,cashout = 0; + cashout = (uint64_t)P->gold * mult * dungeonlevel * dungeonlevel; + return(cashout); +} + +void tetrisjson(UniValue &obj,struct games_player *P) +{ + 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)); +} + +int32_t disp_gamesplayer(char *str,struct games_player *P) +{ + str[0] = 0; + if ( P->gold <= 0 || P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 ) + return(-1); + sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); + return(0); } int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) @@ -43,205 +66,6 @@ int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector pay } else return(-1); } -int64_t games_cashout(struct games_player *P) -{ - int32_t dungeonlevel; int64_t mult=10,cashout = 0; - if ( P->amulet != 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); -} - -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 &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]; gamesevent *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; - //fprintf(stderr,"got baton\n"); - 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); -} - -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],gamesaddr[64],str2[67],fname[64]; gamesevent *keystrokes; 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); -} - bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { return(true); diff --git a/src/cc/tetris.h b/src/cc/tetris.h index 338eee3cb..79a1c2c3e 100644 --- a/src/cc/tetris.h +++ b/src/cc/tetris.h @@ -163,9 +163,12 @@ void tg_print(tetris_game *obj, FILE *f); * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ -#define GAMENAME "tetris" -#define GAMEMAIN tetris -#define CHAINNAME "GTEST" +#define GAMENAME "tetris" // name of executable +#define GAMEMAIN tetris // main program of game +#define GAMEJSON tetrisjson // displays game specific json +#define GAMEDATA tetrisdata // extracts data from game specific variables into games_state +#define CHAINNAME "GTEST" // -ac_name= +typedef uint16_t gamesevent; // can be 8, 16, 32, or 64 bits #define MAXPACK 23 struct games_packitem @@ -180,8 +183,6 @@ struct games_player struct games_packitem gamespack[MAXPACK]; }; -typedef uint16_t gamesevent; - struct games_state { uint64_t seed,origseed; @@ -191,7 +192,7 @@ struct games_state FILE *logfp; struct games_player P; gamesevent buffered[5000],*keystrokes; - uint8_t playerdata[1024]; + uint8_t playerdata[8192]; }; extern struct games_state globalR; void *gamesiterate(struct games_state *rs); @@ -200,6 +201,7 @@ void games_packitemstr(char *packitemstr,struct games_packitem *item); uint64_t _games_rngnext(uint64_t initseed); int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); gamesevent games_revendian(gamesevent revx); +int32_t disp_gamesplayer(char *str,struct games_player *P); #endif