//--------------------------------------------------------------------------- #include #include #include #pragma hdrstop #include "BacDPThread.h" #include "GlobalUnit.h" #include "GameUnit.h" #include "UtilityUnit.h" #include "TableUnit.h" //#include "ActiveFormUnit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //软件过期时间 #define TM_ABORT 125000 void __fastcall WriteData( char* msg ) { SYSTEMTIME st; GetLocalTime(&st); char szDataFile[256]; sprintf( szDataFile, "%s/data/%04d%02d%02d.txt", g_AppPath, st.wYear, st.wMonth, st.wDay); // FILE* fp = NULL; // if(!FileExists(szDataFile)){ // fp = fopen(szDataFile, "w"); // if(fp) // fprintf( fp, "时间,台桌,手数,结果\n" ); // } // else{ // fp = fopen(szDataFile, "a"); // } FILE* fp = fopen(szDataFile, "r+"); if(!fp){ fp = fopen(szDataFile, "w"); if(fp) fprintf( fp, "时间,台桌,手数,结果\n" ); } else fseek(fp, 0, SEEK_END); if( fp ){ fprintf( fp, "%02d:%02d:%02d,%s\n", st.wHour, st.wMinute, st.wSecond, msg ); fclose( fp ); } else{ g_bBacData = false; ShowMessage("导出数据失败! errno=" + IntToStr((int)GetLastError())); } } //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // TBetWayThread __fastcall TDataParseThread::TDataParseThread() { m_hDataEvent = CreateEvent(NULL, FALSE, TRUE, NULL); // m_tmGST = 0; // m_tmExpire = GetCompileTime() + 30 * 86400; //编译时间后30天过期 } //--------------------------------------------------------------------------- __fastcall TDataParseThread::~TDataParseThread() { CloseHandle( m_hDataEvent ); } //--------------------------------------------------------------------------- void __fastcall TDataParseThread::Reset() { WaitForSingleObject(m_hDataEvent, 5000); m_aData.clear(); SetEvent(m_hDataEvent); } //--------------------------------------------------------------------------- void __fastcall TDataParseThread::ParseData(String sData) { WaitForSingleObject(m_hDataEvent, 5000); m_aData.push_back(sData); SetEvent(m_hDataEvent); Suspended = false; } //--------------------------------------------------------------------------- void __fastcall TDataParseThread::Execute() { SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); //关闭系统休眠 while( !Terminated ){ while(m_aData.size()>0){ String sData = m_aData[0]; // if(sData.Length()<3){ // WaitForSingleObject(m_hDataEvent, 5000); // m_aData.erase(m_aData.begin()); // SetEvent(m_hDataEvent); // continue; // } // DebugPrint(((AnsiString)sData).c_str()); TStringDynArray arr = SplitString( sData, "|" ); if(arr.Length<2){ WaitForSingleObject(m_hDataEvent, 5000); m_aData.erase(m_aData.begin()); SetEvent(m_hDataEvent); continue; } int iType = arr[0].ToInt(); if( iType==0 ){ //连接异常断开 DebugPrint("连接异常断开"); int reason = arr[1].ToInt(); PostMessage( Application->MainFormHandle, UM_WEBDEAD, reason, 0 ); } else if( iType==1 ){ //初始化所有台桌 DebugPrint("!!! init all tables"); g_aGames.Init(arr[1]); PostMessage( Application->MainFormHandle, UM_ADDTABLE, 0, 0 ); } else if( iType==2 ){ //台桌Roadmap if(!g_aGames.empty() && arr[1].Length()){ int iG = Vid2Gid(arr[1]); TGame* pGame = NULL; int ind = g_aGames.FindGame(iG, pGame); if(!pGame && iG>0){ pGame = g_aGames.NewGame(iG, arr[g_iPlatform==PF_PA ? 1 : 2], ind); PostMessage( Application->MainFormHandle, UM_ADDTABLE, ind, (long)pGame ); } if(pGame){ int oldSize = pGame->aRes.size(), newSize = arr[3].Length(); if(oldSize!=newSize && oldSize!=newSize+1){ #ifdef _DEBUG if(newSize && oldSize && (oldSize>newSize || oldSizeaRes[i] + '0'; } res[oldSize] = 0; DebugPrint("!!! %s road size %d -> %d with map: %s -> %s", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), oldSize, newSize, res, ((AnsiString)arr[3]).c_str()); } #endif if(g_bGameOn && pGame->bRun) pGame->AutoBetOff(); if(newSize==oldSize+1){ int wt = arr[3][newSize]-'0'; if(wt==0) wt = 3; pGame->aRes.push_back(wt); pGame->winCount[wt-1]++; pGame->BuildRoadmap(wt); } else{ pGame->ClearResults(); for(int i=1; i<=newSize; i++){ int wt = arr[3][i]-'0'; if(wt==0) wt = 3; pGame->aRes.push_back(wt); pGame->winCount[wt-1]++; pGame->BuildRoadmap(wt); } } bool bUpdateRoad = true; if(pGame->gmstatus==12){ //维护台桌 if(oldSize && !newSize) //新局 pGame->AutoBetOn(); //台桌维护中无法正常处理shuffle状态,调用该接口显示和处理新局 } else{ //正常台桌 pGame->gmstatus = 0; //设置结算状态,避免重复计算 // pGame->gmcode = ""; if(oldSizeHandleResult(oldSize+1==newSize ? 0 : 1); //0=正常处理 1=异常处理 bUpdateRoad = false; } } if(bUpdateRoad && pGame->hTable) PostMessage(pGame->hTable, UM_TAB_UPDATE, UPDATE_ROAD, 0); } } } } else if( iType==3 ){ //台桌状态 // 3 | vid | gmcode | wintype(timeout) if(!g_aGames.empty() && arr.Length>=4){ int iG = Vid2Gid(arr[1]); TGame* pGame = NULL; int ind = g_aGames.FindGame(iG, pGame); if(!pGame && iG>0){ pGame = g_aGames.NewGame(iG, arr[g_iPlatform==PF_PA ? 1 : 2], ind); PostMessage( Application->MainFormHandle, UM_ADDTABLE, ind, (long)pGame ); } if( pGame ){ String gmcode = arr[3]; int status = arr[4].ToInt(); bool bNewStatus = pGame->gmstatus != status, bNewCode = pGame->gmcode != gmcode; if(!bNewCode && bNewStatus || bNewCode && (g_iPlatform!=PF_PA || gmcode=="" || gmcode > pGame->gmcode)){ #ifdef _DEBUG if( bNewCode && status!=1 && status<11 && (g_iPlatform!=PF_AB || status!=0) && pGame->gmcode.Length()){ DebugPrint("!!! %s gmcode %s -> %s with status: %d", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), ((AnsiString)pGame->gmcode).c_str(), ((AnsiString)gmcode).c_str(), status); } #endif if(bNewCode) pGame->gmcode = gmcode; // pGame->timeout = 0; if(bNewStatus && pGame->gmstatus==1){ pGame->ManualBetOff(); if(g_bGameOn && pGame->bRun) pGame->AutoBetOff(); } if(status==0 && !bNewCode){ //结算 #ifdef _DEBUG if(pGame->gmstatus!=2 && (g_iPlatform!=PF_AB || pGame->gmstatus!=11)) DebugPrint("!!! %s status %d -> %d", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), pGame->gmstatus, status); #endif pGame->gmstatus = status; if(arr.Length>=8){ //DB特殊处理 if(arr[6].Length()){ pGame->bcard = UnifyCard(arr[6]); pGame->pcard = UnifyCard(arr[7]); } else pGame->bcard = pGame->pcard = ""; } int wt = 0; if(arr.Length>=6 && arr[5].Length()){ wt = arr[5][1]-'0'; if(wt==0) wt = 3; } if(wt>0){ pGame->aRes.push_back(wt); pGame->winCount[wt-1]++; pGame->BuildRoadmap(wt); pGame->HandleResult(); if(g_bBacData){ char data[128]; sprintf(data, "%s,%d,%s", ((AnsiString)arr[g_iPlatform==PF_PA ? 1 : 2]).c_str(), pGame->aRes.size(), wt==1 ? "庄" : wt==2 ? "闲" : "和"); WriteData( data ); } } } else if(status==1 && bNewStatus){// && pGame->gmstatus!=2){ //开始下注 #ifdef _DEBUG if(pGame->gmstatus!=0 && pGame->gmstatus<11) DebugPrint("!!! %s status %d -> %d", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), pGame->gmstatus, status); #endif if(bNewStatus && bNewCode && pGame->iState==ST_BETTED){ DebugPrint("!!! %s status %d -> %d with betted", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), pGame->gmstatus, status); pGame->HandleResult(2); } pGame->gmstatus = status; pGame->timeout = g_iPlatform==PF_AB ? pGame->countdown : g_iPlatform==PF_DB ? arr[5].ToInt() / 1000 : arr[5].ToInt(); pGame->AutoBetOn(); } else if(status==2 && !bNewCode){// && pGame->gmstatus==1 ){ //开牌中 #ifdef _DEBUG if(pGame->gmstatus!=1) DebugPrint("!!! %s status %d -> %d", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), pGame->gmstatus, status); #endif pGame->gmstatus = status; if(pGame->iState==ST_BETTED) pGame->timeout = -1; //开始计算超时 pGame->bcard = pGame->pcard = ""; } else if((status==11 || status==12) && bNewStatus){ //洗牌/维护 if(pGame->iState==ST_BETTED || pGame->iState==ST_EXPIRED){ //超时 DebugPrint("!!! %s status %d -> %d with betted", ((AnsiString)pGame->vid).c_str(), // ((AnsiString)arr[1]).c_str(), pGame->gmstatus, status); pGame->HandleResult(status==12 ? 3 : 2); } pGame->gmstatus = status; if(status==11){ pGame->Shuffle(); if(g_bBacData){ char data[128]; sprintf(data, "%s,,%s", ((AnsiString)arr[g_iPlatform==PF_PA ? 1 : 2]).c_str(), "洗牌"); WriteData( data ); } } else{ pGame->iState = ST_INIT; #ifdef _DEBUG DebugPrint("!!! %s 台桌维护中", ((AnsiString)pGame->vid).c_str());//, ((AnsiString)arr[1]).c_str()); SendMessage( Application->MainFormHandle, UM_RESTORE, 0, 0 ); #endif } } if(pGame->hTable) PostMessage(pGame->hTable, UM_TAB_UPDATE, UPDATE_STATUS, 0); } } } } else if(iType==4){ //多台状态 //4 | e.payload.vid DebugPrint("Enter HALL: %s", ((AnsiString)arr[1]).c_str()); int tab = 2; if(g_iPlatform==PF_PA){ tab = arr[1]=="LINK" ? 1 : arr[1]=="LOBB" ? 0 : 2; } else if(g_iPlatform==PF_AB){ int hId = arr[1].ToInt(); tab = hId==102 ? 1 : hId==100 ? 0 : 2; } else if(g_iPlatform==PF_DB){ int hId = arr[1].ToInt(); tab = hId==2 ? 1 : hId==0 ? 0 : 2; } PostMessage(Application->MainFormHandle, UM_ENTER_TABLE, tab, 0); } else if(iType==5){ //账户余额 //5 | e.val double amo; if(TryStrToFloat(arr[1], amo)){ if(!(g_bTesting && g_settings.bSimAccOn)){ g_fBalance = amo; PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_BALANCE, 0); } } } else if(iType==6){ //下注反馈 //6 | vid | retCode | gmcode | 庄 | 闲 | 平 if(!g_aGames.empty() && arr[1].Length()){ int iG = Vid2Gid(arr[1]); TGame* pGame = NULL; int ind = g_aGames.FindGame(iG, pGame); if(pGame && pGame->gmcode==arr[3]){ int chips[3] = {0}; chips[0] = arr[4].ToInt(); chips[1] = arr[5].ToInt(); chips[2] = arr[6].ToInt(); int retCode = arr[2].ToInt(); if(retCode!=0){ if(g_iPlatform==PF_AB) //欧博错误码转换 retCode = retCode==101 ? 10 //限红低 : retCode==102 ? 11 //限红高 : retCode==103 || retCode==100015 || retCode==6044 ? 25 //超时 : retCode==10101 || retCode==6035 || retCode==6042 ? 26 //余额不足 : -1; else if(g_iPlatform==PF_DB) //多宝错误码转换 retCode = retCode==210010 ? 10 //限红低 : retCode==220030 ? 11 //限红高 : retCode==220004 || retCode==220006 || retCode==110041 ? 25 //超时 : retCode==10469 || retCode==20126 ? 26 //余额不足 : retCode; } pGame->BetResp(retCode, chips); } } } else if(iType==7){ //限额 //7 | min | max int minBet, maxBet; if(TryStrToInt(arr[1], minBet) && TryStrToInt(arr[2], maxBet)){ if(minBet!=g_MinOnBet || maxBet!=g_MaxOnBet){ g_MinOnBet = minBet; g_MaxOnBet = maxBet; PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_LIMIT, 0); } } } else if(iType==8){ //倒计时 //8 | countdownList ABG专用 if(!g_aGames.empty() && arr[1].Length()){ g_aGames.SetCountDown(arr[1]); } } else if(iType==9){ //翻牌 //9 | gid | gmcode | bcard | pcard if(!g_aGames.empty() && !arr[1].IsEmpty() && (!arr[3].IsEmpty() || !arr[4].IsEmpty())){ int iG = Vid2Gid(arr[1]); TGame* pGame = NULL; int ind = g_aGames.FindGame(iG, pGame); if(pGame && pGame->gmstatus==2 && pGame->gmcode==arr[2]){ pGame->bcard = UnifyCard(arr[3]); pGame->pcard = UnifyCard(arr[4]); if(pGame->hTable) PostMessage(pGame->hTable, UM_TAB_UPDATE, UPDATE_STATUS, 0); if(pGame->iState==ST_BETTED) pGame->timeout = -1; //重新计算超时 } } } // else if(iType==10){ //撤销注单 // //10 | gid | gmcode // if(!g_aGames.empty() && arr[1].Length()){ // int iG = Vid2Gid(arr[1]); // TGame* pGame = NULL; // int ind = g_aGames.FindGame(iG, pGame); // // if(pGame && pGame->gmcode==arr[2]){ // DebugPrint("!!! %s 撤销注单 with status: %d", // ((AnsiString)pGame->vid).c_str(), //// ((AnsiString)arr[1]).c_str(), // pGame->gmstatus); // pGame->gmstatus = 0; // pGame->HandleResult(3); // } // } // } m_aData[0] = ""; if( Terminated ) break; WaitForSingleObject(m_hDataEvent, 5000); m_aData.erase(m_aData.begin()); SetEvent(m_hDataEvent); } // 等待数据 if( !Terminated ) Suspended = true; }; SetThreadExecutionState( ES_CONTINUOUS );//打开系统休眠 } //---------------------------------------------------------------------------