496 lines
14 KiB
C++
496 lines
14 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#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 || oldSize<newSize-1)){
|
|
char res[128];
|
|
for(int i=0; i<oldSize; i++){
|
|
res[i] = pGame->aRes[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(oldSize<newSize){
|
|
pGame->HandleResult(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 );//打开系统休眠
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|