addr relaying fixes, proxy option and privacy patches, detect connect to self, non-final tx locktime changes, fix hide unconfirmed generated
This commit is contained in:
parent
6ccefea62a
commit
cc0b4c3b62
19 changed files with 1216 additions and 346 deletions
12
build.txt
12
build.txt
|
@ -1,4 +1,4 @@
|
||||||
BitCoin v0.1.6 ALPHA
|
BitCoin v0.1.6 BETA
|
||||||
|
|
||||||
Copyright (c) 2009 Satoshi Nakamoto
|
Copyright (c) 2009 Satoshi Nakamoto
|
||||||
Distributed under the MIT/X11 software license, see the accompanying
|
Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
@ -19,10 +19,10 @@ Dependencies
|
||||||
Libraries you need to obtain separately to build:
|
Libraries you need to obtain separately to build:
|
||||||
|
|
||||||
default path download
|
default path download
|
||||||
wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/
|
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
|
||||||
OpenSSL \OpenSSL http://www.openssl.org/source/
|
OpenSSL \openssl http://www.openssl.org/source/
|
||||||
Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||||
Boost \Boost http://www.boost.org/users/download/
|
Boost \boost http://www.boost.org/users/download/
|
||||||
|
|
||||||
Their licenses:
|
Their licenses:
|
||||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||||
|
@ -75,7 +75,7 @@ If you want to use it with MSVC, generate the .lib file
|
||||||
Berkeley DB
|
Berkeley DB
|
||||||
-----------
|
-----------
|
||||||
Using MinGW and MSYS:
|
Using MinGW and MSYS:
|
||||||
cd \DB\build_unix
|
cd \db\build_unix
|
||||||
sh ../dist/configure --enable-mingw --enable-cxx
|
sh ../dist/configure --enable-mingw --enable-cxx
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|
19
db.cpp
19
db.cpp
|
@ -121,10 +121,12 @@ void CDB::Close()
|
||||||
pdb->close(0);
|
pdb->close(0);
|
||||||
delete pdb;
|
delete pdb;
|
||||||
pdb = NULL;
|
pdb = NULL;
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
|
{
|
||||||
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
--mapFileUseCount[strFile];
|
--mapFileUseCount[strFile];
|
||||||
|
}
|
||||||
|
|
||||||
RandAddSeed();
|
RandAddSeed();
|
||||||
}
|
}
|
||||||
|
@ -376,11 +378,11 @@ bool CTxDB::LoadBlockIndex()
|
||||||
{
|
{
|
||||||
if (pindexGenesisBlock == NULL)
|
if (pindexGenesisBlock == NULL)
|
||||||
return true;
|
return true;
|
||||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n");
|
return error("CTxDB::LoadBlockIndex() : hashBestChain not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mapBlockIndex.count(hashBestChain))
|
if (!mapBlockIndex.count(hashBestChain))
|
||||||
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n");
|
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
|
||||||
pindexBest = mapBlockIndex[hashBestChain];
|
pindexBest = mapBlockIndex[hashBestChain];
|
||||||
nBestHeight = pindexBest->nHeight;
|
nBestHeight = pindexBest->nHeight;
|
||||||
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
|
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
|
||||||
|
@ -500,16 +502,15 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
|
||||||
CWalletDB::~CWalletDB()
|
CWalletDB::~CWalletDB()
|
||||||
{
|
{
|
||||||
// Flush whenever all handles to wallet.dat are closed
|
// Flush whenever all handles to wallet.dat are closed
|
||||||
Close();
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
|
Close(); // close includes a txn_checkpoint
|
||||||
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
||||||
if (mi != mapFileUseCount.end())
|
if (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
int nRefCount = (*mi).second;
|
int nRefCount = (*mi).second;
|
||||||
if (nRefCount == 0)
|
if (nRefCount == 0)
|
||||||
{
|
{
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
|
||||||
dbenv.lsn_reset(strFile.c_str(), 0);
|
dbenv.lsn_reset(strFile.c_str(), 0);
|
||||||
mapFileUseCount.erase(mi++);
|
mapFileUseCount.erase(mi++);
|
||||||
}
|
}
|
||||||
|
@ -600,6 +601,9 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
||||||
if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
|
if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
|
||||||
if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
|
if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
|
||||||
if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
|
if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
|
||||||
|
if (strKey == "fUseProxy") ssValue >> fUseProxy;
|
||||||
|
if (strKey == "addrProxy") ssValue >> addrProxy;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -610,6 +614,9 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
||||||
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
|
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
|
||||||
printf("fMinimizeToTray = %d\n", fMinimizeToTray);
|
printf("fMinimizeToTray = %d\n", fMinimizeToTray);
|
||||||
printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
|
printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
|
||||||
|
printf("fUseProxy = %d\n", fUseProxy);
|
||||||
|
printf("addrProxy = %s\n", addrProxy.ToString().c_str());
|
||||||
|
|
||||||
|
|
||||||
// The transaction fee setting won't be needed for many years to come.
|
// The transaction fee setting won't be needed for many years to come.
|
||||||
// Setting it to zero here in case they set it to something in an earlier version.
|
// Setting it to zero here in case they set it to something in an earlier version.
|
||||||
|
@ -639,7 +646,7 @@ bool LoadWallet(bool& fFirstRunRet)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create new keyUser and set as default key
|
// Create new keyUser and set as default key
|
||||||
RandAddSeed(true);
|
RandAddSeedPerfmon();
|
||||||
keyUser.MakeNewKey();
|
keyUser.MakeNewKey();
|
||||||
if (!AddKey(keyUser))
|
if (!AddKey(keyUser))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4786)
|
#pragma warning(disable:4786)
|
||||||
#pragma warning(disable:4804)
|
#pragma warning(disable:4804)
|
||||||
|
#pragma warning(disable:4805)
|
||||||
#pragma warning(disable:4717)
|
#pragma warning(disable:4717)
|
||||||
#endif
|
#endif
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
|
@ -62,6 +63,7 @@ using namespace boost;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "strlcpy.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
10
irc.cpp
10
irc.cpp
|
@ -163,6 +163,9 @@ void ThreadIRCSeed(void* parg)
|
||||||
int nErrorWait = 10;
|
int nErrorWait = 10;
|
||||||
int nRetryWait = 10;
|
int nRetryWait = 10;
|
||||||
|
|
||||||
|
if (fUseProxy && addrProxy.port == htons(9050))
|
||||||
|
return;
|
||||||
|
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
CAddress addrConnect("216.155.130.130:6667");
|
CAddress addrConnect("216.155.130.130:6667");
|
||||||
|
@ -191,9 +194,10 @@ void ThreadIRCSeed(void* parg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string strMyName = EncodeAddress(addrLocalHost);
|
string strMyName;
|
||||||
|
if (addrLocalHost.IsRoutable() && !fUseProxy)
|
||||||
if (!addrLocalHost.IsRoutable())
|
strMyName = EncodeAddress(addrLocalHost);
|
||||||
|
else
|
||||||
strMyName = strprintf("x%u", GetRand(1000000000));
|
strMyName = strprintf("x%u", GetRand(1000000000));
|
||||||
|
|
||||||
|
|
||||||
|
|
2
key.h
2
key.h
|
@ -35,7 +35,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// secure_allocator is defined is serialize.h
|
// secure_allocator is defined in serialize.h
|
||||||
typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
||||||
|
|
||||||
|
|
||||||
|
|
71
main.cpp
71
main.cpp
|
@ -415,6 +415,10 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis
|
||||||
if (!CheckTransaction())
|
if (!CheckTransaction())
|
||||||
return error("AcceptTransaction() : CheckTransaction failed");
|
return error("AcceptTransaction() : CheckTransaction failed");
|
||||||
|
|
||||||
|
// To help v0.1.5 clients who would see it as negative number. please delete this later.
|
||||||
|
if (nLockTime > INT_MAX)
|
||||||
|
return error("AcceptTransaction() : not accepting nLockTime beyond 2038");
|
||||||
|
|
||||||
// Do we already have it?
|
// Do we already have it?
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
CRITICAL_BLOCK(cs_mapTransactions)
|
||||||
|
@ -1214,6 +1218,12 @@ bool CBlock::AcceptBlock()
|
||||||
if (nTime <= pindexPrev->GetMedianTimePast())
|
if (nTime <= pindexPrev->GetMedianTimePast())
|
||||||
return error("AcceptBlock() : block's timestamp is too early");
|
return error("AcceptBlock() : block's timestamp is too early");
|
||||||
|
|
||||||
|
// Check that all transactions are finalized (starting around 30 Nov 2009)
|
||||||
|
if (nBestHeight > 31000) // 25620 + 5320
|
||||||
|
foreach(const CTransaction& tx, vtx)
|
||||||
|
if (!tx.IsFinal(nTime))
|
||||||
|
return error("AcceptBlock() : contains a non-final transaction");
|
||||||
|
|
||||||
// Check proof of work
|
// Check proof of work
|
||||||
if (nBits != GetNextWorkRequired(pindexPrev))
|
if (nBits != GetNextWorkRequired(pindexPrev))
|
||||||
return error("AcceptBlock() : incorrect proof of work");
|
return error("AcceptBlock() : incorrect proof of work");
|
||||||
|
@ -1649,7 +1659,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
CDataStream& vRecv = pfrom->vRecv;
|
CDataStream& vRecv = pfrom->vRecv;
|
||||||
if (vRecv.empty())
|
if (vRecv.empty())
|
||||||
return true;
|
return true;
|
||||||
printf("ProcessMessages(%d bytes)\n", vRecv.size());
|
//printf("ProcessMessages(%d bytes)\n", vRecv.size());
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message format
|
// Message format
|
||||||
|
@ -1692,7 +1702,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
{
|
{
|
||||||
// Rewind and wait for rest of message
|
// Rewind and wait for rest of message
|
||||||
///// need a mechanism to give up waiting for overlong message size error
|
///// need a mechanism to give up waiting for overlong message size error
|
||||||
printf("MESSAGE-BREAK\n");
|
//printf("message-break\n");
|
||||||
vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr));
|
vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr));
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
break;
|
break;
|
||||||
|
@ -1711,7 +1721,20 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
fRet = ProcessMessage(pfrom, strCommand, vMsg);
|
fRet = ProcessMessage(pfrom, strCommand, vMsg);
|
||||||
CheckForShutdown(2);
|
CheckForShutdown(2);
|
||||||
}
|
}
|
||||||
CATCH_PRINT_EXCEPTION("ProcessMessage()")
|
catch (std::ios_base::failure& e) {
|
||||||
|
if (strstr(e.what(), "CDataStream::read() : end of data"))
|
||||||
|
{
|
||||||
|
// Allow exceptions from underlength message on vRecv
|
||||||
|
LogException(&e, "ProcessMessage()");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PrintException(&e, "ProcessMessage()");
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
PrintException(&e, "ProcessMessage()");
|
||||||
|
} catch (...) {
|
||||||
|
PrintException(NULL, "ProcessMessage()");
|
||||||
|
}
|
||||||
|
|
||||||
if (!fRet)
|
if (!fRet)
|
||||||
printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize);
|
printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize);
|
||||||
}
|
}
|
||||||
|
@ -1726,7 +1749,8 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
static map<unsigned int, vector<unsigned char> > mapReuseKey;
|
static map<unsigned int, vector<unsigned char> > mapReuseKey;
|
||||||
printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size());
|
RandAddSeedPerfmon();
|
||||||
|
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
|
||||||
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
|
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
|
||||||
{
|
{
|
||||||
printf("dropmessages DROPPING RECV MESSAGE\n");
|
printf("dropmessages DROPPING RECV MESSAGE\n");
|
||||||
|
@ -1735,18 +1759,32 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (strCommand == "version")
|
if (strCommand == "version")
|
||||||
{
|
{
|
||||||
// Can only do this once
|
// Each connection can only send one version message
|
||||||
if (pfrom->nVersion != 0)
|
if (pfrom->nVersion != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int64 nTime;
|
int64 nTime;
|
||||||
CAddress addrMe;
|
CAddress addrMe;
|
||||||
|
CAddress addrFrom;
|
||||||
|
uint64 nNonce = 1;
|
||||||
vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
|
vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
|
||||||
|
if (pfrom->nVersion >= 106 && !vRecv.empty())
|
||||||
|
vRecv >> addrFrom >> nNonce;
|
||||||
if (pfrom->nVersion == 0)
|
if (pfrom->nVersion == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Disconnect if we connected to ourself
|
||||||
|
if (nNonce == nLocalHostNonce)
|
||||||
|
{
|
||||||
|
pfrom->fDisconnect = true;
|
||||||
|
pfrom->vRecv.clear();
|
||||||
|
pfrom->vSend.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
|
pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
|
||||||
pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
|
pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
|
||||||
|
|
||||||
|
@ -1767,6 +1805,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));
|
pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pfrom->fSuccessfullyConnected = true;
|
||||||
|
|
||||||
printf("version message: version %d\n", pfrom->nVersion);
|
printf("version message: version %d\n", pfrom->nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,16 +1840,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return true;
|
return true;
|
||||||
AddAddress(addrdb, addr);
|
AddAddress(addrdb, addr);
|
||||||
if (addr.IsRoutable() && addr.ip != addrLocalHost.ip)
|
pfrom->AddAddressKnown(addr);
|
||||||
|
if (!pfrom->fGetAddr && addr.IsRoutable())
|
||||||
{
|
{
|
||||||
// Put on lists to send to other nodes
|
// Put on lists to send to other nodes
|
||||||
pfrom->setAddrKnown.insert(addr);
|
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
foreach(CNode* pnode, vNodes)
|
foreach(CNode* pnode, vNodes)
|
||||||
if (!pnode->setAddrKnown.count(addr))
|
pnode->PushAddress(addr);
|
||||||
pnode->vAddrToSend.push_back(addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pfrom->fGetAddr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2009,7 +2049,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
return true;
|
return true;
|
||||||
const CAddress& addr = item.second;
|
const CAddress& addr = item.second;
|
||||||
if (addr.nTime > nSince)
|
if (addr.nTime > nSince)
|
||||||
pfrom->vAddrToSend.push_back(addr);
|
pfrom->PushAddress(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2108,8 +2148,11 @@ bool SendMessages(CNode* pto)
|
||||||
vector<CAddress> vAddrToSend;
|
vector<CAddress> vAddrToSend;
|
||||||
vAddrToSend.reserve(pto->vAddrToSend.size());
|
vAddrToSend.reserve(pto->vAddrToSend.size());
|
||||||
foreach(const CAddress& addr, pto->vAddrToSend)
|
foreach(const CAddress& addr, pto->vAddrToSend)
|
||||||
if (!pto->setAddrKnown.count(addr))
|
{
|
||||||
|
// returns true if wasn't already contained in the set
|
||||||
|
if (pto->setAddrKnown.insert(addr).second)
|
||||||
vAddrToSend.push_back(addr);
|
vAddrToSend.push_back(addr);
|
||||||
|
}
|
||||||
pto->vAddrToSend.clear();
|
pto->vAddrToSend.clear();
|
||||||
if (!vAddrToSend.empty())
|
if (!vAddrToSend.empty())
|
||||||
pto->PushMessage("addr", vAddrToSend);
|
pto->PushMessage("addr", vAddrToSend);
|
||||||
|
@ -2193,7 +2236,7 @@ void GenerateBitcoins(bool fGenerate)
|
||||||
if (fLimitProcessors && nProcessors > nLimitProcessors)
|
if (fLimitProcessors && nProcessors > nLimitProcessors)
|
||||||
nProcessors = nLimitProcessors;
|
nProcessors = nLimitProcessors;
|
||||||
int nAddThreads = nProcessors - vnThreadsRunning[3];
|
int nAddThreads = nProcessors - vnThreadsRunning[3];
|
||||||
printf("starting %d bitcoinminer threads\n", nAddThreads);
|
printf("Starting %d BitcoinMiner threads\n", nAddThreads);
|
||||||
for (int i = 0; i < nAddThreads; i++)
|
for (int i = 0; i < nAddThreads; i++)
|
||||||
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
|
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
|
||||||
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
|
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
|
||||||
|
@ -2207,7 +2250,7 @@ void ThreadBitcoinMiner(void* parg)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool fRet = BitcoinMiner();
|
bool fRet = BitcoinMiner();
|
||||||
printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");
|
printf("BitcoinMiner returned %s\n", fRet ? "true" : "false");
|
||||||
vnThreadsRunning[3]--;
|
vnThreadsRunning[3]--;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
|
@ -2737,7 +2780,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
|
||||||
else
|
else
|
||||||
strError = "Error: Transaction creation failed ";
|
strError = "Error: Transaction creation failed ";
|
||||||
wxMessageBox(strError, "Sending...");
|
wxMessageBox(strError, "Sending...");
|
||||||
return error("SendMoney() : %s\n", strError.c_str());
|
return error("SendMoney() : %s", strError.c_str());
|
||||||
}
|
}
|
||||||
if (!CommitTransactionSpent(wtxNew, key))
|
if (!CommitTransactionSpent(wtxNew, key))
|
||||||
{
|
{
|
||||||
|
|
16
main.h
16
main.h
|
@ -366,7 +366,7 @@ public:
|
||||||
int nVersion;
|
int nVersion;
|
||||||
vector<CTxIn> vin;
|
vector<CTxIn> vin;
|
||||||
vector<CTxOut> vout;
|
vector<CTxOut> vout;
|
||||||
int nLockTime;
|
unsigned int nLockTime;
|
||||||
|
|
||||||
|
|
||||||
CTransaction()
|
CTransaction()
|
||||||
|
@ -401,9 +401,15 @@ public:
|
||||||
return SerializeHash(*this);
|
return SerializeHash(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFinal() const
|
bool IsFinal(int64 nBlockTime=0) const
|
||||||
{
|
{
|
||||||
if (nLockTime == 0 || nLockTime < nBestHeight)
|
// Time based nLockTime implemented in 0.1.6,
|
||||||
|
// do not use time based until most 0.1.5 nodes have upgraded.
|
||||||
|
if (nBlockTime == 0)
|
||||||
|
nBlockTime = GetAdjustedTime();
|
||||||
|
if (nLockTime == 0)
|
||||||
|
return true;
|
||||||
|
if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime))
|
||||||
return true;
|
return true;
|
||||||
foreach(const CTxIn& txin, vin)
|
foreach(const CTxIn& txin, vin)
|
||||||
if (!txin.IsFinal())
|
if (!txin.IsFinal())
|
||||||
|
@ -686,8 +692,9 @@ public:
|
||||||
char fSpent;
|
char fSpent;
|
||||||
//// probably need to sign the order info so know it came from payer
|
//// probably need to sign the order info so know it came from payer
|
||||||
|
|
||||||
// memory only
|
// memory only UI hints
|
||||||
mutable unsigned int nTimeDisplayed;
|
mutable unsigned int nTimeDisplayed;
|
||||||
|
mutable int nLinesDisplayed;
|
||||||
|
|
||||||
|
|
||||||
CWalletTx()
|
CWalletTx()
|
||||||
|
@ -712,6 +719,7 @@ public:
|
||||||
fFromMe = false;
|
fFromMe = false;
|
||||||
fSpent = false;
|
fSpent = false;
|
||||||
nTimeDisplayed = 0;
|
nTimeDisplayed = 0;
|
||||||
|
nLinesDisplayed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
|
|
4
makefile
4
makefile
|
@ -17,8 +17,8 @@ endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include"
|
INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include"
|
||||||
LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib"
|
LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib"
|
||||||
LIBS= \
|
LIBS= \
|
||||||
-l db_cxx \
|
-l db_cxx \
|
||||||
-l eay32 \
|
-l eay32 \
|
||||||
|
|
181
net.cpp
181
net.cpp
|
@ -8,6 +8,7 @@
|
||||||
void ThreadMessageHandler2(void* parg);
|
void ThreadMessageHandler2(void* parg);
|
||||||
void ThreadSocketHandler2(void* parg);
|
void ThreadSocketHandler2(void* parg);
|
||||||
void ThreadOpenConnections2(void* parg);
|
void ThreadOpenConnections2(void* parg);
|
||||||
|
bool OpenNetworkConnection(const CAddress& addrConnect);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +23,10 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
||||||
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
||||||
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
||||||
CNode* pnodeLocalHost = &nodeLocalHost;
|
CNode* pnodeLocalHost = &nodeLocalHost;
|
||||||
|
uint64 nLocalHostNonce = 0;
|
||||||
bool fShutdown = false;
|
bool fShutdown = false;
|
||||||
array<int, 10> vnThreadsRunning;
|
array<int, 10> vnThreadsRunning;
|
||||||
|
SOCKET hListenSocket = INVALID_SOCKET;
|
||||||
|
|
||||||
vector<CNode*> vNodes;
|
vector<CNode*> vNodes;
|
||||||
CCriticalSection cs_vNodes;
|
CCriticalSection cs_vNodes;
|
||||||
|
@ -34,9 +37,11 @@ deque<pair<int64, CInv> > vRelayExpiration;
|
||||||
CCriticalSection cs_mapRelay;
|
CCriticalSection cs_mapRelay;
|
||||||
map<CInv, int64> mapAlreadyAskedFor;
|
map<CInv, int64> mapAlreadyAskedFor;
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
int fUseProxy = false;
|
||||||
|
CAddress addrProxy("127.0.0.1:9050");
|
||||||
|
|
||||||
|
|
||||||
CAddress addrProxy;
|
|
||||||
|
|
||||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
|
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +52,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
|
bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
|
||||||
bool fProxy = (addrProxy.ip && fRoutable);
|
bool fProxy = (fUseProxy && fRoutable);
|
||||||
struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
|
struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
|
||||||
|
|
||||||
if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
|
if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
|
||||||
|
@ -69,18 +74,18 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
|
||||||
if (ret != nSize)
|
if (ret != nSize)
|
||||||
{
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return error("Error sending to proxy\n");
|
return error("Error sending to proxy");
|
||||||
}
|
}
|
||||||
char pchRet[8];
|
char pchRet[8];
|
||||||
if (recv(hSocket, pchRet, 8, 0) != 8)
|
if (recv(hSocket, pchRet, 8, 0) != 8)
|
||||||
{
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return error("Error reading proxy response\n");
|
return error("Error reading proxy response");
|
||||||
}
|
}
|
||||||
if (pchRet[1] != 0x5a)
|
if (pchRet[1] != 0x5a)
|
||||||
{
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return error("Proxy returned error %d\n", pchRet[1]);
|
return error("Proxy returned error %d", pchRet[1]);
|
||||||
}
|
}
|
||||||
printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str());
|
printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str());
|
||||||
}
|
}
|
||||||
|
@ -95,7 +100,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
||||||
{
|
{
|
||||||
SOCKET hSocket;
|
SOCKET hSocket;
|
||||||
if (!ConnectSocket(addrConnect, hSocket))
|
if (!ConnectSocket(addrConnect, hSocket))
|
||||||
return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str());
|
return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
|
||||||
|
|
||||||
send(hSocket, pszGet, strlen(pszGet), 0);
|
send(hSocket, pszGet, strlen(pszGet), 0);
|
||||||
|
|
||||||
|
@ -131,7 +136,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return error("GetMyExternalIP() : connection closed\n");
|
return error("GetMyExternalIP() : connection closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,6 +146,9 @@ bool GetMyExternalIP(unsigned int& ipRet)
|
||||||
char* pszGet;
|
char* pszGet;
|
||||||
char* pszKeyword;
|
char* pszKeyword;
|
||||||
|
|
||||||
|
if (fUseProxy)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (int nLookup = 0; nLookup <= 1; nLookup++)
|
for (int nLookup = 0; nLookup <= 1; nLookup++)
|
||||||
for (int nHost = 1; nHost <= 2; nHost++)
|
for (int nHost = 1; nHost <= 2; nHost++)
|
||||||
{
|
{
|
||||||
|
@ -416,14 +424,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNode::Disconnect()
|
void CNode::DoDisconnect()
|
||||||
{
|
{
|
||||||
printf("disconnecting node %s\n", addr.ToStringLog().c_str());
|
printf("disconnecting node %s\n", addr.ToStringLog().c_str());
|
||||||
|
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
|
||||||
// If outbound and never got version message, mark address as failed
|
// If outbound and never got version message, mark address as failed
|
||||||
if (!fInbound && nVersion == 0)
|
if (!fInbound && !fSuccessfullyConnected)
|
||||||
CRITICAL_BLOCK(cs_mapAddresses)
|
CRITICAL_BLOCK(cs_mapAddresses)
|
||||||
mapAddresses[addr.GetKey()].nLastFailed = GetTime();
|
mapAddresses[addr.GetKey()].nLastFailed = GetTime();
|
||||||
|
|
||||||
|
@ -458,18 +466,18 @@ void ThreadSocketHandler(void* parg)
|
||||||
|
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
vnThreadsRunning[0] = true;
|
vnThreadsRunning[0]++;
|
||||||
CheckForShutdown(0);
|
CheckForShutdown(0);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ThreadSocketHandler2(parg);
|
ThreadSocketHandler2(parg);
|
||||||
vnThreadsRunning[0] = false;
|
vnThreadsRunning[0]--;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
vnThreadsRunning[0] = false;
|
vnThreadsRunning[0]--;
|
||||||
PrintException(&e, "ThreadSocketHandler()");
|
PrintException(&e, "ThreadSocketHandler()");
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
vnThreadsRunning[0] = false;
|
vnThreadsRunning[0]--;
|
||||||
PrintException(NULL, "ThreadSocketHandler()");
|
PrintException(NULL, "ThreadSocketHandler()");
|
||||||
}
|
}
|
||||||
Sleep(5000);
|
Sleep(5000);
|
||||||
|
@ -479,7 +487,6 @@ void ThreadSocketHandler(void* parg)
|
||||||
void ThreadSocketHandler2(void* parg)
|
void ThreadSocketHandler2(void* parg)
|
||||||
{
|
{
|
||||||
printf("ThreadSocketHandler started\n");
|
printf("ThreadSocketHandler started\n");
|
||||||
SOCKET hListenSocket = *(SOCKET*)parg;
|
|
||||||
list<CNode*> vNodesDisconnected;
|
list<CNode*> vNodesDisconnected;
|
||||||
int nPrevNodeCount = 0;
|
int nPrevNodeCount = 0;
|
||||||
|
|
||||||
|
@ -498,7 +505,7 @@ void ThreadSocketHandler2(void* parg)
|
||||||
{
|
{
|
||||||
// remove from vNodes
|
// remove from vNodes
|
||||||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||||
pnode->Disconnect();
|
pnode->DoDisconnect();
|
||||||
|
|
||||||
// hold in disconnected pool until all refs are released
|
// hold in disconnected pool until all refs are released
|
||||||
pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
|
pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
|
||||||
|
@ -562,9 +569,9 @@ void ThreadSocketHandler2(void* parg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vnThreadsRunning[0] = false;
|
vnThreadsRunning[0]--;
|
||||||
int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
|
int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
|
||||||
vnThreadsRunning[0] = true;
|
vnThreadsRunning[0]++;
|
||||||
CheckForShutdown(0);
|
CheckForShutdown(0);
|
||||||
if (nSelect == SOCKET_ERROR)
|
if (nSelect == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
|
@ -577,7 +584,6 @@ void ThreadSocketHandler2(void* parg)
|
||||||
}
|
}
|
||||||
Sleep(timeout.tv_usec/1000);
|
Sleep(timeout.tv_usec/1000);
|
||||||
}
|
}
|
||||||
RandAddSeed();
|
|
||||||
|
|
||||||
//// debug print
|
//// debug print
|
||||||
//foreach(CNode* pnode, vNodes)
|
//foreach(CNode* pnode, vNodes)
|
||||||
|
@ -711,18 +717,18 @@ void ThreadOpenConnections(void* parg)
|
||||||
|
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
vnThreadsRunning[1] = true;
|
vnThreadsRunning[1]++;
|
||||||
CheckForShutdown(1);
|
CheckForShutdown(1);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ThreadOpenConnections2(parg);
|
ThreadOpenConnections2(parg);
|
||||||
vnThreadsRunning[1] = false;
|
vnThreadsRunning[1]--;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
vnThreadsRunning[1] = false;
|
vnThreadsRunning[1]--;
|
||||||
PrintException(&e, "ThreadOpenConnections()");
|
PrintException(&e, "ThreadOpenConnections()");
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
vnThreadsRunning[1] = false;
|
vnThreadsRunning[1]--;
|
||||||
PrintException(NULL, "ThreadOpenConnections()");
|
PrintException(NULL, "ThreadOpenConnections()");
|
||||||
}
|
}
|
||||||
Sleep(5000);
|
Sleep(5000);
|
||||||
|
@ -733,6 +739,13 @@ void ThreadOpenConnections2(void* parg)
|
||||||
{
|
{
|
||||||
printf("ThreadOpenConnections started\n");
|
printf("ThreadOpenConnections started\n");
|
||||||
|
|
||||||
|
// Connect to one specified address
|
||||||
|
while (mapArgs.count("/connect"))
|
||||||
|
{
|
||||||
|
OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str()));
|
||||||
|
Sleep(10000);
|
||||||
|
}
|
||||||
|
|
||||||
// Initiate network connections
|
// Initiate network connections
|
||||||
int nTry = 0;
|
int nTry = 0;
|
||||||
bool fIRCOnly = false;
|
bool fIRCOnly = false;
|
||||||
|
@ -740,14 +753,14 @@ void ThreadOpenConnections2(void* parg)
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
// Wait
|
// Wait
|
||||||
vnThreadsRunning[1] = false;
|
vnThreadsRunning[1]--;
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
|
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
|
||||||
{
|
{
|
||||||
CheckForShutdown(1);
|
CheckForShutdown(1);
|
||||||
Sleep(2000);
|
Sleep(2000);
|
||||||
}
|
}
|
||||||
vnThreadsRunning[1] = true;
|
vnThreadsRunning[1]++;
|
||||||
CheckForShutdown(1);
|
CheckForShutdown(1);
|
||||||
|
|
||||||
|
|
||||||
|
@ -835,45 +848,50 @@ void ThreadOpenConnections2(void* parg)
|
||||||
|
|
||||||
// Once we've chosen an IP, we'll try every given port before moving on
|
// Once we've chosen an IP, we'll try every given port before moving on
|
||||||
foreach(const CAddress& addrConnect, (*mi).second)
|
foreach(const CAddress& addrConnect, (*mi).second)
|
||||||
{
|
if (OpenNetworkConnection(addrConnect))
|
||||||
//
|
break;
|
||||||
// Initiate outbound network connection
|
|
||||||
//
|
|
||||||
CheckForShutdown(1);
|
|
||||||
if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vnThreadsRunning[1] = false;
|
|
||||||
CNode* pnode = ConnectNode(addrConnect);
|
|
||||||
vnThreadsRunning[1] = true;
|
|
||||||
CheckForShutdown(1);
|
|
||||||
if (!pnode)
|
|
||||||
continue;
|
|
||||||
pnode->fNetworkNode = true;
|
|
||||||
|
|
||||||
if (addrLocalHost.IsRoutable())
|
|
||||||
{
|
|
||||||
// Advertise our address
|
|
||||||
vector<CAddress> vAddrToSend;
|
|
||||||
vAddrToSend.push_back(addrLocalHost);
|
|
||||||
pnode->PushMessage("addr", vAddrToSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get as many addresses as we can
|
|
||||||
pnode->PushMessage("getaddr");
|
|
||||||
|
|
||||||
////// should the one on the receiving end do this too?
|
|
||||||
// Subscribe our local subscription list
|
|
||||||
const unsigned int nHops = 0;
|
|
||||||
for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
|
|
||||||
if (pnodeLocalHost->vfSubscribe[nChannel])
|
|
||||||
pnode->PushMessage("subscribe", nChannel, nHops);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Initiate outbound network connection
|
||||||
|
//
|
||||||
|
CheckForShutdown(1);
|
||||||
|
if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vnThreadsRunning[1]--;
|
||||||
|
CNode* pnode = ConnectNode(addrConnect);
|
||||||
|
vnThreadsRunning[1]++;
|
||||||
|
CheckForShutdown(1);
|
||||||
|
if (!pnode)
|
||||||
|
return false;
|
||||||
|
pnode->fNetworkNode = true;
|
||||||
|
|
||||||
|
if (addrLocalHost.IsRoutable() && !fUseProxy)
|
||||||
|
{
|
||||||
|
// Advertise our address
|
||||||
|
vector<CAddress> vAddrToSend;
|
||||||
|
vAddrToSend.push_back(addrLocalHost);
|
||||||
|
pnode->PushMessage("addr", vAddrToSend);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get as many addresses as we can
|
||||||
|
pnode->PushMessage("getaddr");
|
||||||
|
pnode->fGetAddr = true; // don't relay the results of the getaddr
|
||||||
|
|
||||||
|
////// should the one on the receiving end do this too?
|
||||||
|
// Subscribe our local subscription list
|
||||||
|
const unsigned int nHops = 0;
|
||||||
|
for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
|
||||||
|
if (pnodeLocalHost->vfSubscribe[nChannel])
|
||||||
|
pnode->PushMessage("subscribe", nChannel, nHops);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -887,18 +905,18 @@ void ThreadMessageHandler(void* parg)
|
||||||
|
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
vnThreadsRunning[2] = true;
|
vnThreadsRunning[2]++;
|
||||||
CheckForShutdown(2);
|
CheckForShutdown(2);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ThreadMessageHandler2(parg);
|
ThreadMessageHandler2(parg);
|
||||||
vnThreadsRunning[2] = false;
|
vnThreadsRunning[2]--;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
vnThreadsRunning[2] = false;
|
vnThreadsRunning[2]--;
|
||||||
PrintException(&e, "ThreadMessageHandler()");
|
PrintException(&e, "ThreadMessageHandler()");
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
vnThreadsRunning[2] = false;
|
vnThreadsRunning[2]--;
|
||||||
PrintException(NULL, "ThreadMessageHandler()");
|
PrintException(NULL, "ThreadMessageHandler()");
|
||||||
}
|
}
|
||||||
Sleep(5000);
|
Sleep(5000);
|
||||||
|
@ -931,9 +949,9 @@ void ThreadMessageHandler2(void* parg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait and allow messages to bunch up
|
// Wait and allow messages to bunch up
|
||||||
vnThreadsRunning[2] = false;
|
vnThreadsRunning[2]--;
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
vnThreadsRunning[2] = true;
|
vnThreadsRunning[2]++;
|
||||||
CheckForShutdown(2);
|
CheckForShutdown(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -982,7 +1000,7 @@ bool StartNode(string& strError)
|
||||||
printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
|
printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
|
||||||
|
|
||||||
// Create socket for listening for incoming connections
|
// Create socket for listening for incoming connections
|
||||||
SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (hListenSocket == INVALID_SOCKET)
|
if (hListenSocket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
||||||
|
@ -1024,13 +1042,21 @@ bool StartNode(string& strError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get our external IP address for incoming connections
|
// Get our external IP address for incoming connections
|
||||||
if (addrIncoming.ip)
|
if (fUseProxy)
|
||||||
addrLocalHost.ip = addrIncoming.ip;
|
|
||||||
|
|
||||||
if (GetMyExternalIP(addrLocalHost.ip))
|
|
||||||
{
|
{
|
||||||
addrIncoming = addrLocalHost;
|
// Proxies can't take incoming connections
|
||||||
CWalletDB().WriteSetting("addrIncoming", addrIncoming);
|
addrLocalHost.ip = CAddress("0.0.0.0").ip;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addrIncoming.ip)
|
||||||
|
addrLocalHost.ip = addrIncoming.ip;
|
||||||
|
|
||||||
|
if (GetMyExternalIP(addrLocalHost.ip))
|
||||||
|
{
|
||||||
|
addrIncoming = addrLocalHost;
|
||||||
|
CWalletDB().WriteSetting("addrIncoming", addrIncoming);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get addresses from IRC and advertise ours
|
// Get addresses from IRC and advertise ours
|
||||||
|
@ -1040,7 +1066,7 @@ bool StartNode(string& strError)
|
||||||
//
|
//
|
||||||
// Start threads
|
// Start threads
|
||||||
//
|
//
|
||||||
if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1)
|
if (_beginthread(ThreadSocketHandler, 0, NULL) == -1)
|
||||||
{
|
{
|
||||||
strError = "Error: _beginthread(ThreadSocketHandler) failed";
|
strError = "Error: _beginthread(ThreadSocketHandler) failed";
|
||||||
printf("%s\n", strError.c_str());
|
printf("%s\n", strError.c_str());
|
||||||
|
@ -1094,10 +1120,15 @@ void CheckForShutdown(int n)
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
{
|
{
|
||||||
if (n != -1)
|
if (n != -1)
|
||||||
vnThreadsRunning[n] = false;
|
if (--vnThreadsRunning[n] < 0)
|
||||||
|
vnThreadsRunning[n] = 0;
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
{
|
||||||
foreach(CNode* pnode, vNodes)
|
foreach(CNode* pnode, vNodes)
|
||||||
closesocket(pnode->hSocket);
|
closesocket(pnode->hSocket);
|
||||||
|
closesocket(hListenSocket);
|
||||||
|
}
|
||||||
|
printf("Thread %d exiting\n", n);
|
||||||
_endthread();
|
_endthread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
131
net.h
131
net.h
|
@ -174,7 +174,7 @@ public:
|
||||||
{
|
{
|
||||||
nServices = nServicesIn;
|
nServices = nServicesIn;
|
||||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||||
ip = 0;
|
ip = INADDR_NONE;
|
||||||
port = DEFAULT_PORT;
|
port = DEFAULT_PORT;
|
||||||
nTime = GetAdjustedTime();
|
nTime = GetAdjustedTime();
|
||||||
nLastFailed = 0;
|
nLastFailed = 0;
|
||||||
|
@ -183,7 +183,7 @@ public:
|
||||||
if (strlen(pszIn) > ARRAYLEN(psz)-1)
|
if (strlen(pszIn) > ARRAYLEN(psz)-1)
|
||||||
return;
|
return;
|
||||||
strcpy(psz, pszIn);
|
strcpy(psz, pszIn);
|
||||||
unsigned int a, b, c, d, e;
|
unsigned int a=0, b=0, c=0, d=0, e=0;
|
||||||
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
|
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
|
||||||
return;
|
return;
|
||||||
char* pszPort = strchr(psz, ':');
|
char* pszPort = strchr(psz, ':');
|
||||||
|
@ -191,6 +191,10 @@ public:
|
||||||
{
|
{
|
||||||
*pszPort++ = '\0';
|
*pszPort++ = '\0';
|
||||||
port = htons(atoi(pszPort));
|
port = htons(atoi(pszPort));
|
||||||
|
if (atoi(pszPort) > USHRT_MAX)
|
||||||
|
port = htons(USHRT_MAX);
|
||||||
|
if (atoi(pszPort) < 0)
|
||||||
|
port = htons(0);
|
||||||
}
|
}
|
||||||
ip = inet_addr(psz);
|
ip = inet_addr(psz);
|
||||||
}
|
}
|
||||||
|
@ -215,6 +219,11 @@ public:
|
||||||
a.port == b.port);
|
a.port == b.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend inline bool operator!=(const CAddress& a, const CAddress& b)
|
||||||
|
{
|
||||||
|
return (!(a == b));
|
||||||
|
}
|
||||||
|
|
||||||
friend inline bool operator<(const CAddress& a, const CAddress& b)
|
friend inline bool operator<(const CAddress& a, const CAddress& b)
|
||||||
{
|
{
|
||||||
int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
|
int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
|
||||||
|
@ -277,6 +286,11 @@ public:
|
||||||
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
|
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ToStringPort() const
|
||||||
|
{
|
||||||
|
return strprintf("%u", ntohs(port));
|
||||||
|
}
|
||||||
|
|
||||||
string ToStringLog() const
|
string ToStringLog() const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
@ -416,6 +430,7 @@ extern bool fClient;
|
||||||
extern uint64 nLocalServices;
|
extern uint64 nLocalServices;
|
||||||
extern CAddress addrLocalHost;
|
extern CAddress addrLocalHost;
|
||||||
extern CNode* pnodeLocalHost;
|
extern CNode* pnodeLocalHost;
|
||||||
|
extern uint64 nLocalHostNonce;
|
||||||
extern bool fShutdown;
|
extern bool fShutdown;
|
||||||
extern array<int, 10> vnThreadsRunning;
|
extern array<int, 10> vnThreadsRunning;
|
||||||
extern vector<CNode*> vNodes;
|
extern vector<CNode*> vNodes;
|
||||||
|
@ -426,6 +441,9 @@ extern map<CInv, CDataStream> mapRelay;
|
||||||
extern deque<pair<int64, CInv> > vRelayExpiration;
|
extern deque<pair<int64, CInv> > vRelayExpiration;
|
||||||
extern CCriticalSection cs_mapRelay;
|
extern CCriticalSection cs_mapRelay;
|
||||||
extern map<CInv, int64> mapAlreadyAskedFor;
|
extern map<CInv, int64> mapAlreadyAskedFor;
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
extern int fUseProxy;
|
||||||
extern CAddress addrProxy;
|
extern CAddress addrProxy;
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,6 +466,7 @@ public:
|
||||||
bool fClient;
|
bool fClient;
|
||||||
bool fInbound;
|
bool fInbound;
|
||||||
bool fNetworkNode;
|
bool fNetworkNode;
|
||||||
|
bool fSuccessfullyConnected;
|
||||||
bool fDisconnect;
|
bool fDisconnect;
|
||||||
protected:
|
protected:
|
||||||
int nRefCount;
|
int nRefCount;
|
||||||
|
@ -459,6 +478,7 @@ public:
|
||||||
// flood
|
// flood
|
||||||
vector<CAddress> vAddrToSend;
|
vector<CAddress> vAddrToSend;
|
||||||
set<CAddress> setAddrKnown;
|
set<CAddress> setAddrKnown;
|
||||||
|
bool fGetAddr;
|
||||||
|
|
||||||
// inventory based relay
|
// inventory based relay
|
||||||
set<CInv> setInventoryKnown;
|
set<CInv> setInventoryKnown;
|
||||||
|
@ -483,15 +503,20 @@ public:
|
||||||
fClient = false; // set by version message
|
fClient = false; // set by version message
|
||||||
fInbound = fInboundIn;
|
fInbound = fInboundIn;
|
||||||
fNetworkNode = false;
|
fNetworkNode = false;
|
||||||
|
fSuccessfullyConnected = false;
|
||||||
fDisconnect = false;
|
fDisconnect = false;
|
||||||
nRefCount = 0;
|
nRefCount = 0;
|
||||||
nReleaseTime = 0;
|
nReleaseTime = 0;
|
||||||
|
fGetAddr = false;
|
||||||
vfSubscribe.assign(256, false);
|
vfSubscribe.assign(256, false);
|
||||||
|
|
||||||
// Push a version message
|
// Push a version message
|
||||||
/// when NTP implemented, change to just nTime = GetAdjustedTime()
|
/// when NTP implemented, change to just nTime = GetAdjustedTime()
|
||||||
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
||||||
PushMessage("version", VERSION, nLocalServices, nTime, addr);
|
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
|
||||||
|
CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
|
||||||
|
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||||
|
PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CNode()
|
~CNode()
|
||||||
|
@ -531,6 +556,21 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AddAddressKnown(const CAddress& addr)
|
||||||
|
{
|
||||||
|
setAddrKnown.insert(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushAddress(const CAddress& addr)
|
||||||
|
{
|
||||||
|
// Known checking here is only to save space from duplicates.
|
||||||
|
// SendMessages will filter it again for knowns that were added
|
||||||
|
// after addresses were pushed.
|
||||||
|
if (!setAddrKnown.count(addr))
|
||||||
|
vAddrToSend.push_back(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddInventoryKnown(const CInv& inv)
|
void AddInventoryKnown(const CInv& inv)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_inventory)
|
CRITICAL_BLOCK(cs_inventory)
|
||||||
|
@ -562,7 +602,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void BeginMessage(const char* pszCommand)
|
void BeginMessage(const char* pszCommand)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&cs_vSend);
|
EnterCriticalSection(&cs_vSend);
|
||||||
|
@ -570,7 +609,7 @@ public:
|
||||||
AbortMessage();
|
AbortMessage();
|
||||||
nPushPos = vSend.size();
|
nPushPos = vSend.size();
|
||||||
vSend << CMessageHeader(pszCommand, 0);
|
vSend << CMessageHeader(pszCommand, 0);
|
||||||
printf("sending: %-12s ", pszCommand);
|
printf("sending: %s ", pszCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbortMessage()
|
void AbortMessage()
|
||||||
|
@ -706,6 +745,86 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginMessage(pszCommand);
|
||||||
|
vSend << a1 << a2 << a3 << a4 << a5;
|
||||||
|
EndMessage();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AbortMessage();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||||
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginMessage(pszCommand);
|
||||||
|
vSend << a1 << a2 << a3 << a4 << a5 << a6;
|
||||||
|
EndMessage();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AbortMessage();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||||
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginMessage(pszCommand);
|
||||||
|
vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
|
||||||
|
EndMessage();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AbortMessage();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||||
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginMessage(pszCommand);
|
||||||
|
vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
|
||||||
|
EndMessage();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AbortMessage();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||||
|
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginMessage(pszCommand);
|
||||||
|
vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
|
||||||
|
EndMessage();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AbortMessage();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PushRequest(const char* pszCommand,
|
void PushRequest(const char* pszCommand,
|
||||||
void (*fn)(void*, CDataStream&), void* param1)
|
void (*fn)(void*, CDataStream&), void* param1)
|
||||||
|
@ -750,7 +869,7 @@ public:
|
||||||
bool IsSubscribed(unsigned int nChannel);
|
bool IsSubscribed(unsigned int nChannel);
|
||||||
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
|
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
|
||||||
void CancelSubscribe(unsigned int nChannel);
|
void CancelSubscribe(unsigned int nChannel);
|
||||||
void Disconnect();
|
void DoDisconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ class CScript;
|
||||||
class CDataStream;
|
class CDataStream;
|
||||||
class CAutoFile;
|
class CAutoFile;
|
||||||
|
|
||||||
static const int VERSION = 105;
|
static const int VERSION = 106;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
84
strlcpy.h
Normal file
84
strlcpy.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy src to string dst of size siz. At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz == 0).
|
||||||
|
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
inline size_t strlcpy(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
|
||||||
|
/* Copy as many bytes as will fit */
|
||||||
|
if (n != 0)
|
||||||
|
{
|
||||||
|
while (--n != 0)
|
||||||
|
{
|
||||||
|
if ((*d++ = *s++) == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
if (siz != 0)
|
||||||
|
*d = '\0'; /* NUL-terminate dst */
|
||||||
|
while (*s++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(s - src - 1); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||||
|
* full size of dst, not space left). At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||||
|
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||||
|
* If retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
inline size_t strlcat(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||||
|
while (n-- != 0 && *d != '\0')
|
||||||
|
d++;
|
||||||
|
dlen = d - dst;
|
||||||
|
n = siz - dlen;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return(dlen + strlen(s));
|
||||||
|
while (*s != '\0')
|
||||||
|
{
|
||||||
|
if (n != 1)
|
||||||
|
{
|
||||||
|
*d++ = *s;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*d = '\0';
|
||||||
|
|
||||||
|
return(dlen + (s - src)); /* count does not include NUL */
|
||||||
|
}
|
223
ui.cpp
223
ui.cpp
|
@ -497,7 +497,7 @@ string SingleLine(const string& strIn)
|
||||||
return strOut;
|
return strOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
{
|
{
|
||||||
int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
|
int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
|
||||||
int64 nCredit = wtx.GetCredit();
|
int64 nCredit = wtx.GetCredit();
|
||||||
|
@ -506,14 +506,11 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
uint256 hash = wtx.GetHash();
|
uint256 hash = wtx.GetHash();
|
||||||
string strStatus = FormatTxStatus(wtx);
|
string strStatus = FormatTxStatus(wtx);
|
||||||
map<string, string> mapValue = wtx.mapValue;
|
map<string, string> mapValue = wtx.mapValue;
|
||||||
|
wtx.nLinesDisplayed = 1;
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
if (wtx.IsCoinBase())
|
if (wtx.IsCoinBase())
|
||||||
{
|
{
|
||||||
// View->Show Generated
|
|
||||||
if (!fShowGenerated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Don't show generated coin until confirmed by at least one block after it
|
// Don't show generated coin until confirmed by at least one block after it
|
||||||
// so we don't get the user's hopes up until it looks like it's probably accepted.
|
// so we don't get the user's hopes up until it looks like it's probably accepted.
|
||||||
//
|
//
|
||||||
|
@ -527,10 +524,13 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
//
|
//
|
||||||
if (wtx.GetDepthInMainChain() < 2)
|
if (wtx.GetDepthInMainChain() < 2)
|
||||||
{
|
{
|
||||||
// In case it was previously displayed
|
wtx.nLinesDisplayed = 0;
|
||||||
DeleteLine(hash);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// View->Show Generated
|
||||||
|
if (!fShowGenerated)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the block the tx is in
|
// Find the block the tx is in
|
||||||
|
@ -644,6 +644,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
// Debit
|
// Debit
|
||||||
//
|
//
|
||||||
int64 nTxFee = nDebit - wtx.GetValueOut();
|
int64 nTxFee = nDebit - wtx.GetValueOut();
|
||||||
|
wtx.nLinesDisplayed = 0;
|
||||||
for (int nOut = 0; nOut < wtx.vout.size(); nOut++)
|
for (int nOut = 0; nOut < wtx.vout.size(); nOut++)
|
||||||
{
|
{
|
||||||
const CTxOut& txout = wtx.vout[nOut];
|
const CTxOut& txout = wtx.vout[nOut];
|
||||||
|
@ -685,6 +686,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
SingleLine(strDescription),
|
SingleLine(strDescription),
|
||||||
FormatMoney(-nValue, true),
|
FormatMoney(-nValue, true),
|
||||||
"");
|
"");
|
||||||
|
wtx.nLinesDisplayed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -706,12 +708,14 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMainFrame::RefreshStatus()
|
void CMainFrame::RefreshStatus()
|
||||||
{
|
{
|
||||||
static int nLastTop;
|
static int nLastTop;
|
||||||
int nTop = m_listCtrl->GetTopItem();
|
int nTop = max((int)m_listCtrl->GetTopItem(), 0);
|
||||||
if (nTop == nLastTop && pindexBestLast == pindexBest)
|
if (nTop == nLastTop && pindexBestLast == pindexBest)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -729,7 +733,7 @@ void CMainFrame::RefreshStatus()
|
||||||
nLastTop = nTop;
|
nLastTop = nTop;
|
||||||
pindexBestLast = pindexBest;
|
pindexBestLast = pindexBest;
|
||||||
|
|
||||||
for (int nIndex = nStart; nIndex < nEnd; nIndex++)
|
for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++)
|
||||||
{
|
{
|
||||||
uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
|
uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
||||||
|
@ -738,9 +742,12 @@ void CMainFrame::RefreshStatus()
|
||||||
printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n");
|
printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const CWalletTx& wtx = (*mi).second;
|
CWalletTx& wtx = (*mi).second;
|
||||||
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
|
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
|
||||||
InsertTransaction(wtx, false, nIndex);
|
{
|
||||||
|
if (!InsertTransaction(wtx, false, nIndex))
|
||||||
|
m_listCtrl->DeleteItem(nIndex--);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
|
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
|
||||||
}
|
}
|
||||||
|
@ -801,6 +808,9 @@ void CMainFrame::OnIdle(wxIdleEvent& event)
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("RefreshListCtrl done\n");
|
printf("RefreshListCtrl done\n");
|
||||||
|
|
||||||
|
// Update transaction total display
|
||||||
|
MainFrameRepaint();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -834,31 +844,54 @@ void DelayedRepaint(void* parg)
|
||||||
return;
|
return;
|
||||||
fOneThread = true;
|
fOneThread = true;
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
|
printf("DelayedRepaint()\n");
|
||||||
MainFrameRepaint();
|
MainFrameRepaint();
|
||||||
fOneThread = false;
|
fOneThread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
|
if (ptaskbaricon)
|
||||||
|
ptaskbaricon->UpdateTooltip();
|
||||||
|
|
||||||
// Update listctrl contents
|
// Update listctrl contents
|
||||||
if (!vWalletUpdated.empty())
|
if (!vWalletUpdated.empty())
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
||||||
{
|
{
|
||||||
|
bool fInserted = false;
|
||||||
foreach(uint256 hash, vWalletUpdated)
|
foreach(uint256 hash, vWalletUpdated)
|
||||||
{
|
{
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
||||||
if (mi != mapWallet.end())
|
if (mi != mapWallet.end())
|
||||||
InsertTransaction((*mi).second, false);
|
fInserted |= InsertTransaction((*mi).second, false);
|
||||||
}
|
}
|
||||||
m_listCtrl->ScrollList(0, INT_MAX);
|
|
||||||
vWalletUpdated.clear();
|
vWalletUpdated.clear();
|
||||||
|
if (fInserted)
|
||||||
|
m_listCtrl->ScrollList(0, INT_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update status column of visible items only
|
// Update status column of visible items only
|
||||||
RefreshStatus();
|
RefreshStatus();
|
||||||
|
|
||||||
|
// Balance total
|
||||||
|
bool fRefreshed = false;
|
||||||
|
static int nTransactionCount;
|
||||||
|
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
{
|
||||||
|
fRefreshed = true;
|
||||||
|
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
||||||
|
|
||||||
|
// Count hidden and multi-line transactions
|
||||||
|
nTransactionCount = 0;
|
||||||
|
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
|
{
|
||||||
|
CWalletTx& wtx = (*it).second;
|
||||||
|
nTransactionCount += wtx.nLinesDisplayed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update status bar
|
// Update status bar
|
||||||
string strGen = "";
|
string strGen = "";
|
||||||
if (fGenerateBitcoins)
|
if (fGenerateBitcoins)
|
||||||
|
@ -867,17 +900,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
||||||
strGen = "(not connected)";
|
strGen = "(not connected)";
|
||||||
m_statusBar->SetStatusText(strGen, 1);
|
m_statusBar->SetStatusText(strGen, 1);
|
||||||
|
|
||||||
string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount());
|
string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount);
|
||||||
m_statusBar->SetStatusText(strStatus, 2);
|
m_statusBar->SetStatusText(strStatus, 2);
|
||||||
|
|
||||||
// Balance total
|
|
||||||
bool fRefreshed = false;
|
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
|
||||||
{
|
|
||||||
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
|
||||||
fRefreshed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mapWallet was locked, try again later
|
// mapWallet was locked, try again later
|
||||||
if (!vWalletUpdated.empty() || !fRefreshed)
|
if (!vWalletUpdated.empty() || !fRefreshed)
|
||||||
_beginthread(DelayedRepaint, 0, NULL);
|
_beginthread(DelayedRepaint, 0, NULL);
|
||||||
|
@ -1350,6 +1375,14 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
|
||||||
m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray);
|
m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray);
|
||||||
m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose);
|
m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose);
|
||||||
fTmpMinimizeOnClose = fMinimizeOnClose;
|
fTmpMinimizeOnClose = fMinimizeOnClose;
|
||||||
|
m_checkBoxUseProxy->SetValue(fUseProxy);
|
||||||
|
m_textCtrlProxyIP->Enable(fUseProxy);
|
||||||
|
m_textCtrlProxyPort->Enable(fUseProxy);
|
||||||
|
m_staticTextProxyIP->Enable(fUseProxy);
|
||||||
|
m_staticTextProxyPort->Enable(fUseProxy);
|
||||||
|
m_textCtrlProxyIP->SetValue(addrProxy.ToStringIP());
|
||||||
|
m_textCtrlProxyPort->SetValue(addrProxy.ToStringPort());
|
||||||
|
|
||||||
m_buttonOK->SetFocus();
|
m_buttonOK->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1395,6 +1428,34 @@ void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
m_textCtrlProxyIP->Enable(event.IsChecked());
|
||||||
|
m_textCtrlProxyPort->Enable(event.IsChecked());
|
||||||
|
m_staticTextProxyIP->Enable(event.IsChecked());
|
||||||
|
m_staticTextProxyPort->Enable(event.IsChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
CAddress COptionsDialog::GetProxyAddr()
|
||||||
|
{
|
||||||
|
// Be careful about byte order, addr.ip and addr.port are big endian
|
||||||
|
CAddress addr(m_textCtrlProxyIP->GetValue() + ":" + m_textCtrlProxyPort->GetValue());
|
||||||
|
if (addr.ip == INADDR_NONE)
|
||||||
|
addr.ip = addrProxy.ip;
|
||||||
|
int nPort = atoi(m_textCtrlProxyPort->GetValue());
|
||||||
|
addr.port = htons(nPort);
|
||||||
|
if (nPort <= 0 || nPort > USHRT_MAX)
|
||||||
|
addr.port = addrProxy.port;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event)
|
||||||
|
{
|
||||||
|
m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP());
|
||||||
|
m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void COptionsDialog::OnButtonOK(wxCommandEvent& event)
|
void COptionsDialog::OnButtonOK(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
OnButtonApply(event);
|
OnButtonApply(event);
|
||||||
|
@ -1446,6 +1507,18 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
|
||||||
fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose);
|
fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose);
|
||||||
walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
|
walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fUseProxy != m_checkBoxUseProxy->GetValue())
|
||||||
|
{
|
||||||
|
fUseProxy = m_checkBoxUseProxy->GetValue();
|
||||||
|
walletdb.WriteSetting("fUseProxy", fUseProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrProxy != GetProxyAddr())
|
||||||
|
{
|
||||||
|
addrProxy = GetProxyAddr();
|
||||||
|
walletdb.WriteSetting("addrProxy", addrProxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1657,7 +1730,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n
|
||||||
nPrice = nPriceIn;
|
nPrice = nPriceIn;
|
||||||
wtx = wtxIn;
|
wtx = wtxIn;
|
||||||
start = wxDateTime::UNow();
|
start = wxDateTime::UNow();
|
||||||
strStatus = "";
|
memset(pszStatus, 0, sizeof(pszStatus));
|
||||||
fCanCancel = true;
|
fCanCancel = true;
|
||||||
fAbort = false;
|
fAbort = false;
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
|
@ -1721,10 +1794,10 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event)
|
||||||
|
|
||||||
void CSendingDialog::OnPaint(wxPaintEvent& event)
|
void CSendingDialog::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
if (strStatus.size() > 130)
|
if (strlen(pszStatus) > 130)
|
||||||
m_textCtrlStatus->SetValue(string("\n") + strStatus);
|
m_textCtrlStatus->SetValue(string("\n") + pszStatus);
|
||||||
else
|
else
|
||||||
m_textCtrlStatus->SetValue(string("\n\n") + strStatus);
|
m_textCtrlStatus->SetValue(string("\n\n") + pszStatus);
|
||||||
m_staticTextSending->SetFocus();
|
m_staticTextSending->SetFocus();
|
||||||
if (!fCanCancel)
|
if (!fCanCancel)
|
||||||
m_buttonCancel->Enable(false);
|
m_buttonCancel->Enable(false);
|
||||||
|
@ -1736,7 +1809,7 @@ void CSendingDialog::OnPaint(wxPaintEvent& event)
|
||||||
}
|
}
|
||||||
if (fAbort && fCanCancel && IsShown())
|
if (fAbort && fCanCancel && IsShown())
|
||||||
{
|
{
|
||||||
strStatus = "CANCELLED";
|
strcpy(pszStatus, "CANCELLED");
|
||||||
m_buttonOK->Enable(true);
|
m_buttonOK->Enable(true);
|
||||||
m_buttonOK->SetFocus();
|
m_buttonOK->SetFocus();
|
||||||
m_buttonCancel->Enable(false);
|
m_buttonCancel->Enable(false);
|
||||||
|
@ -1777,7 +1850,8 @@ bool CSendingDialog::Status()
|
||||||
}
|
}
|
||||||
if (fAbort && fCanCancel)
|
if (fAbort && fCanCancel)
|
||||||
{
|
{
|
||||||
strStatus = "CANCELLED";
|
memset(pszStatus, 0, 10);
|
||||||
|
strcpy(pszStatus, "CANCELLED");
|
||||||
Repaint();
|
Repaint();
|
||||||
fWorkDone = true;
|
fWorkDone = true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1789,7 +1863,12 @@ bool CSendingDialog::Status(const string& str)
|
||||||
{
|
{
|
||||||
if (!Status())
|
if (!Status())
|
||||||
return false;
|
return false;
|
||||||
strStatus = str;
|
|
||||||
|
// This can be read by the UI thread at any time,
|
||||||
|
// so copy in a way that can be read cleanly at all times.
|
||||||
|
memset(pszStatus, 0, min(str.size()+1, sizeof(pszStatus)));
|
||||||
|
strlcpy(pszStatus, str.c_str(), sizeof(pszStatus));
|
||||||
|
|
||||||
Repaint();
|
Repaint();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1950,8 +2029,8 @@ void CSendingDialog::OnReply3(CDataStream& vRecv)
|
||||||
if (nRet > 0)
|
if (nRet > 0)
|
||||||
{
|
{
|
||||||
Error("The payment was sent, but the recipient was unable to verify it.\n"
|
Error("The payment was sent, but the recipient was unable to verify it.\n"
|
||||||
"The transaction is recorded and will credit to the recipient if it is valid,\n"
|
"The transaction is recorded and will credit to the recipient,\n"
|
||||||
"but without comment information.");
|
"but the comment information will be blank.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3092,6 +3171,7 @@ END_EVENT_TABLE()
|
||||||
|
|
||||||
void CMyTaskBarIcon::Show(bool fShow)
|
void CMyTaskBarIcon::Show(bool fShow)
|
||||||
{
|
{
|
||||||
|
static char pszPrevTip[200];
|
||||||
if (fShow)
|
if (fShow)
|
||||||
{
|
{
|
||||||
string strTooltip = "Bitcoin";
|
string strTooltip = "Bitcoin";
|
||||||
|
@ -3099,10 +3179,17 @@ void CMyTaskBarIcon::Show(bool fShow)
|
||||||
strTooltip = "Bitcoin - Generating";
|
strTooltip = "Bitcoin - Generating";
|
||||||
if (fGenerateBitcoins && vNodes.empty())
|
if (fGenerateBitcoins && vNodes.empty())
|
||||||
strTooltip = "Bitcoin - (not connected)";
|
strTooltip = "Bitcoin - (not connected)";
|
||||||
SetIcon(wxICON(bitcoin), strTooltip);
|
|
||||||
|
// Optimization, only update when changed, using char array to be reentrant
|
||||||
|
if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0)
|
||||||
|
{
|
||||||
|
strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip));
|
||||||
|
SetIcon(wxICON(bitcoin), strTooltip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
strlcpy(pszPrevTip, "", sizeof(pszPrevTip));
|
||||||
RemoveIcon();
|
RemoveIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3301,12 +3388,12 @@ bool CMyApp::OnInit2()
|
||||||
if (mapArgs.count("/datadir"))
|
if (mapArgs.count("/datadir"))
|
||||||
strSetDataDir = mapArgs["/datadir"];
|
strSetDataDir = mapArgs["/datadir"];
|
||||||
|
|
||||||
if (mapArgs.count("/proxy"))
|
|
||||||
addrProxy = CAddress(mapArgs["/proxy"].c_str());
|
|
||||||
|
|
||||||
if (mapArgs.count("/debug"))
|
if (mapArgs.count("/debug"))
|
||||||
fDebug = true;
|
fDebug = true;
|
||||||
|
|
||||||
|
if (mapArgs.count("/printtodebugger"))
|
||||||
|
fPrintToDebugger = true;
|
||||||
|
|
||||||
if (mapArgs.count("/dropmessages"))
|
if (mapArgs.count("/dropmessages"))
|
||||||
{
|
{
|
||||||
nDropMessagesTest = atoi(mapArgs["/dropmessages"]);
|
nDropMessagesTest = atoi(mapArgs["/dropmessages"]);
|
||||||
|
@ -3380,6 +3467,20 @@ bool CMyApp::OnInit2()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("/proxy"))
|
||||||
|
{
|
||||||
|
fUseProxy = true;
|
||||||
|
addrProxy = CAddress(mapArgs["/proxy"].c_str());
|
||||||
|
if (addrProxy.ip == INADDR_NONE)
|
||||||
|
{
|
||||||
|
wxMessageBox("Invalid /proxy address", "Bitcoin");
|
||||||
|
OnExit();
|
||||||
|
}
|
||||||
|
CWalletDB walletdb;
|
||||||
|
walletdb.WriteSetting("fUseProxy", fUseProxy);
|
||||||
|
walletdb.WriteSetting("addrProxy", addrProxy);
|
||||||
|
}
|
||||||
|
|
||||||
if (mapArgs.count("/gen"))
|
if (mapArgs.count("/gen"))
|
||||||
{
|
{
|
||||||
if (mapArgs["/gen"].empty())
|
if (mapArgs["/gen"].empty())
|
||||||
|
@ -3404,7 +3505,7 @@ bool CMyApp::OnInit2()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//RandAddSeedPerfmon();
|
RandAddSeedPerfmon();
|
||||||
|
|
||||||
if (!StartNode(strErrors))
|
if (!StartNode(strErrors))
|
||||||
wxMessageBox(strErrors, "Bitcoin");
|
wxMessageBox(strErrors, "Bitcoin");
|
||||||
|
@ -3514,7 +3615,7 @@ void CMyApp::OnFatalException()
|
||||||
|
|
||||||
void MainFrameRepaint()
|
void MainFrameRepaint()
|
||||||
{
|
{
|
||||||
// This is called by network code that shouldn't access pframeMain and ptaskbaricon
|
// This is called by network code that shouldn't access pframeMain
|
||||||
// directly because it could still be running after the UI is closed.
|
// directly because it could still be running after the UI is closed.
|
||||||
if (pframeMain)
|
if (pframeMain)
|
||||||
{
|
{
|
||||||
|
@ -3523,20 +3624,47 @@ void MainFrameRepaint()
|
||||||
pframeMain->Refresh();
|
pframeMain->Refresh();
|
||||||
pframeMain->AddPendingEvent(event);
|
pframeMain->AddPendingEvent(event);
|
||||||
}
|
}
|
||||||
if (ptaskbaricon)
|
|
||||||
ptaskbaricon->UpdateTooltip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||||
|
|
||||||
|
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
|
||||||
|
{
|
||||||
|
char pszPath[MAX_PATH+100] = "";
|
||||||
|
|
||||||
|
// SHGetSpecialFolderPath is not usually available on NT 4.0
|
||||||
|
HMODULE hShell32 = LoadLibrary("shell32.dll");
|
||||||
|
if (hShell32)
|
||||||
|
{
|
||||||
|
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
|
||||||
|
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
|
||||||
|
if (pSHGetSpecialFolderPath)
|
||||||
|
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
|
||||||
|
FreeModule(hShell32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup option
|
||||||
|
if (pszPath[0] == '\0')
|
||||||
|
{
|
||||||
|
if (nFolder == CSIDL_STARTUP)
|
||||||
|
{
|
||||||
|
strcpy(pszPath, getenv("USERPROFILE"));
|
||||||
|
strcat(pszPath, "\\Start Menu\\Programs\\Startup");
|
||||||
|
}
|
||||||
|
else if (nFolder == CSIDL_APPDATA)
|
||||||
|
{
|
||||||
|
strcpy(pszPath, getenv("APPDATA"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pszPath;
|
||||||
|
}
|
||||||
|
|
||||||
string StartupShortcutPath()
|
string StartupShortcutPath()
|
||||||
{
|
{
|
||||||
// Get the startup folder shortcut path
|
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
|
||||||
char pszLinkPath[MAX_PATH+100];
|
|
||||||
pszLinkPath[0] = '\0';
|
|
||||||
SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0);
|
|
||||||
strcat(pszLinkPath, "\\Bitcoin.lnk");
|
|
||||||
return pszLinkPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetStartOnSystemStartup()
|
bool GetStartOnSystemStartup()
|
||||||
|
@ -3630,7 +3758,8 @@ void ThreadRandSendTest(void* parg)
|
||||||
if (GetBalance() < nValue)
|
if (GetBalance() < nValue)
|
||||||
{
|
{
|
||||||
wxMessageBox("Out of money ");
|
wxMessageBox("Out of money ");
|
||||||
return;
|
while (GetBalance() < 1000)
|
||||||
|
Sleep(1000);
|
||||||
}
|
}
|
||||||
nValue += (nRep % 100) * CENT;
|
nValue += (nRep % 100) * CENT;
|
||||||
|
|
||||||
|
|
8
ui.h
8
ui.h
|
@ -89,7 +89,7 @@ public:
|
||||||
void OnCrossThreadCall(wxCommandEvent& event);
|
void OnCrossThreadCall(wxCommandEvent& event);
|
||||||
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
||||||
bool DeleteLine(uint256 hashKey);
|
bool DeleteLine(uint256 hashKey);
|
||||||
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
||||||
void RefreshListCtrl();
|
void RefreshListCtrl();
|
||||||
void RefreshStatus();
|
void RefreshStatus();
|
||||||
};
|
};
|
||||||
|
@ -121,6 +121,9 @@ protected:
|
||||||
void OnKillFocusTransactionFee(wxFocusEvent& event);
|
void OnKillFocusTransactionFee(wxFocusEvent& event);
|
||||||
void OnCheckBoxLimitProcessors(wxCommandEvent& event);
|
void OnCheckBoxLimitProcessors(wxCommandEvent& event);
|
||||||
void OnCheckBoxMinimizeToTray(wxCommandEvent& event);
|
void OnCheckBoxMinimizeToTray(wxCommandEvent& event);
|
||||||
|
void OnCheckBoxUseProxy(wxCommandEvent& event);
|
||||||
|
void OnKillFocusProxy(wxFocusEvent& event);
|
||||||
|
|
||||||
void OnButtonOK(wxCommandEvent& event);
|
void OnButtonOK(wxCommandEvent& event);
|
||||||
void OnButtonCancel(wxCommandEvent& event);
|
void OnButtonCancel(wxCommandEvent& event);
|
||||||
void OnButtonApply(wxCommandEvent& event);
|
void OnButtonApply(wxCommandEvent& event);
|
||||||
|
@ -133,6 +136,7 @@ public:
|
||||||
bool fTmpStartOnSystemStartup;
|
bool fTmpStartOnSystemStartup;
|
||||||
bool fTmpMinimizeOnClose;
|
bool fTmpMinimizeOnClose;
|
||||||
void SelectPage(int nPage);
|
void SelectPage(int nPage);
|
||||||
|
CAddress GetProxyAddr();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,7 +197,7 @@ public:
|
||||||
int64 nPrice;
|
int64 nPrice;
|
||||||
CWalletTx wtx;
|
CWalletTx wtx;
|
||||||
wxDateTime start;
|
wxDateTime start;
|
||||||
string strStatus;
|
char pszStatus[10000];
|
||||||
bool fCanCancel;
|
bool fCanCancel;
|
||||||
bool fAbort;
|
bool fAbort;
|
||||||
bool fSuccess;
|
bool fSuccess;
|
||||||
|
|
51
uibase.cpp
51
uibase.cpp
|
@ -380,7 +380,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||||
bSizer69 = new wxBoxSizer( wxVERTICAL );
|
bSizer69 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
|
||||||
bSizer69->Add( 0, 14, 0, wxEXPAND, 5 );
|
bSizer69->Add( 0, 16, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
|
m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_staticText32->Wrap( -1 );
|
m_staticText32->Wrap( -1 );
|
||||||
|
@ -412,7 +412,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||||
bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 );
|
m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 );
|
||||||
bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 );
|
bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_staticText35->Wrap( -1 );
|
m_staticText35->Wrap( -1 );
|
||||||
|
@ -434,12 +434,45 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||||
|
|
||||||
bSizer101->Add( 16, 0, 0, 0, 5 );
|
bSizer101->Add( 16, 0, 0, 0, 5 );
|
||||||
|
|
||||||
m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("Mi&nimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
|
||||||
bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 );
|
bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
bSizer69->Add( bSizer101, 1, wxEXPAND, 5 );
|
bSizer69->Add( bSizer101, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxBoxSizer* bSizer102;
|
||||||
|
bSizer102 = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
|
m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
|
||||||
|
bSizer102->Add( m_checkBoxUseProxy, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
bSizer69->Add( bSizer102, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxBoxSizer* bSizer103;
|
||||||
|
bSizer103 = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer103->Add( 18, 0, 0, 0, 5 );
|
||||||
|
|
||||||
|
m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, wxT("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticTextProxyIP->Wrap( -1 );
|
||||||
|
bSizer103->Add( m_staticTextProxyIP, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_textCtrlProxyIP = new wxTextCtrl( m_panelMain, wxID_PROXYIP, wxEmptyString, wxDefaultPosition, wxSize( 140,-1 ), 0 );
|
||||||
|
m_textCtrlProxyIP->SetMaxLength( 15 );
|
||||||
|
bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, wxT(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticTextProxyPort->Wrap( -1 );
|
||||||
|
bSizer103->Add( m_staticTextProxyPort, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_textCtrlProxyPort = new wxTextCtrl( m_panelMain, wxID_PROXYPORT, wxEmptyString, wxDefaultPosition, wxSize( 55,-1 ), 0 );
|
||||||
|
m_textCtrlProxyPort->SetMaxLength( 5 );
|
||||||
|
bSizer103->Add( m_textCtrlProxyPort, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
bSizer69->Add( bSizer103, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
m_panelMain->SetSizer( bSizer69 );
|
m_panelMain->SetSizer( bSizer69 );
|
||||||
m_panelMain->Layout();
|
m_panelMain->Layout();
|
||||||
bSizer69->Fit( m_panelMain );
|
bSizer69->Fit( m_panelMain );
|
||||||
|
@ -450,13 +483,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||||
bSizer64 = new wxBoxSizer( wxVERTICAL );
|
bSizer64 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
|
||||||
bSizer64->Add( 0, 14, 0, wxEXPAND, 5 );
|
bSizer64->Add( 0, 16, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_staticText321->Wrap( -1 );
|
m_staticText321->Wrap( -1 );
|
||||||
bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_staticText69->Wrap( -1 );
|
m_staticText69->Wrap( -1 );
|
||||||
bSizer64->Add( m_staticText69, 0, wxALL, 5 );
|
bSizer64->Add( m_staticText69, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
@ -506,6 +539,9 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||||
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||||
m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
||||||
m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
||||||
|
m_checkBoxUseProxy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
|
||||||
|
m_textCtrlProxyIP->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||||
|
m_textCtrlProxyPort->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||||
m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
||||||
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
||||||
m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
||||||
|
@ -518,6 +554,9 @@ COptionsDialogBase::~COptionsDialogBase()
|
||||||
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||||
m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
||||||
m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
||||||
|
m_checkBoxUseProxy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
|
||||||
|
m_textCtrlProxyIP->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||||
|
m_textCtrlProxyPort->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||||
m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
||||||
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
||||||
m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
||||||
|
|
98
uibase.h
98
uibase.h
|
@ -50,50 +50,52 @@
|
||||||
#define wxID_BUTTONCOPY 1006
|
#define wxID_BUTTONCOPY 1006
|
||||||
#define wxID_BUTTONCHANGE 1007
|
#define wxID_BUTTONCHANGE 1007
|
||||||
#define wxID_TRANSACTIONFEE 1008
|
#define wxID_TRANSACTIONFEE 1008
|
||||||
#define wxID_TEXTCTRLPAYTO 1009
|
#define wxID_PROXYIP 1009
|
||||||
#define wxID_BUTTONPASTE 1010
|
#define wxID_PROXYPORT 1010
|
||||||
#define wxID_BUTTONADDRESSBOOK 1011
|
#define wxID_TEXTCTRLPAYTO 1011
|
||||||
#define wxID_TEXTCTRLAMOUNT 1012
|
#define wxID_BUTTONPASTE 1012
|
||||||
#define wxID_CHOICETRANSFERTYPE 1013
|
#define wxID_BUTTONADDRESSBOOK 1013
|
||||||
#define wxID_LISTCTRL 1014
|
#define wxID_TEXTCTRLAMOUNT 1014
|
||||||
#define wxID_BUTTONRENAME 1015
|
#define wxID_CHOICETRANSFERTYPE 1015
|
||||||
#define wxID_BUTTONNEW 1016
|
#define wxID_LISTCTRL 1016
|
||||||
#define wxID_BUTTONEDIT 1017
|
#define wxID_BUTTONRENAME 1017
|
||||||
#define wxID_BUTTONDELETE 1018
|
#define wxID_BUTTONNEW 1018
|
||||||
#define wxID_DEL0 1019
|
#define wxID_BUTTONEDIT 1019
|
||||||
#define wxID_DEL1 1020
|
#define wxID_BUTTONDELETE 1020
|
||||||
#define wxID_DEL2 1021
|
#define wxID_DEL0 1021
|
||||||
#define wxID_DEL3 1022
|
#define wxID_DEL1 1022
|
||||||
#define wxID_DEL4 1023
|
#define wxID_DEL2 1023
|
||||||
#define wxID_DEL5 1024
|
#define wxID_DEL3 1024
|
||||||
#define wxID_DEL6 1025
|
#define wxID_DEL4 1025
|
||||||
#define wxID_DEL7 1026
|
#define wxID_DEL5 1026
|
||||||
#define wxID_DEL8 1027
|
#define wxID_DEL6 1027
|
||||||
#define wxID_DEL9 1028
|
#define wxID_DEL7 1028
|
||||||
#define wxID_DEL10 1029
|
#define wxID_DEL8 1029
|
||||||
#define wxID_DEL11 1030
|
#define wxID_DEL9 1030
|
||||||
#define wxID_DEL12 1031
|
#define wxID_DEL10 1031
|
||||||
#define wxID_DEL13 1032
|
#define wxID_DEL11 1032
|
||||||
#define wxID_DEL14 1033
|
#define wxID_DEL12 1033
|
||||||
#define wxID_DEL15 1034
|
#define wxID_DEL13 1034
|
||||||
#define wxID_DEL16 1035
|
#define wxID_DEL14 1035
|
||||||
#define wxID_DEL17 1036
|
#define wxID_DEL15 1036
|
||||||
#define wxID_DEL18 1037
|
#define wxID_DEL16 1037
|
||||||
#define wxID_DEL19 1038
|
#define wxID_DEL17 1038
|
||||||
#define wxID_BUTTONPREVIEW 1039
|
#define wxID_DEL18 1039
|
||||||
#define wxID_BUTTONSAMPLE 1040
|
#define wxID_DEL19 1040
|
||||||
#define wxID_CANCEL2 1041
|
#define wxID_BUTTONPREVIEW 1041
|
||||||
#define wxID_BUTTONBACK 1042
|
#define wxID_BUTTONSAMPLE 1042
|
||||||
#define wxID_BUTTONNEXT 1043
|
#define wxID_CANCEL2 1043
|
||||||
#define wxID_SUBMIT 1044
|
#define wxID_BUTTONBACK 1044
|
||||||
#define wxID_OPENNEWTABLE 1045
|
#define wxID_BUTTONNEXT 1045
|
||||||
#define wxID_DEALHAND 1046
|
#define wxID_SUBMIT 1046
|
||||||
#define wxID_FOLD 1047
|
#define wxID_OPENNEWTABLE 1047
|
||||||
#define wxID_CALL 1048
|
#define wxID_DEALHAND 1048
|
||||||
#define wxID_RAISE 1049
|
#define wxID_FOLD 1049
|
||||||
#define wxID_LEAVETABLE 1050
|
#define wxID_CALL 1050
|
||||||
#define wxID_DITCHPLAYER 1051
|
#define wxID_RAISE 1051
|
||||||
#define wxID_TEXTCTRL 1052
|
#define wxID_LEAVETABLE 1052
|
||||||
|
#define wxID_DITCHPLAYER 1053
|
||||||
|
#define wxID_TEXTCTRL 1054
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
/// Class CMainFrameBase
|
/// Class CMainFrameBase
|
||||||
|
@ -211,6 +213,12 @@ class COptionsDialogBase : public wxDialog
|
||||||
wxCheckBox* m_checkBoxMinimizeToTray;
|
wxCheckBox* m_checkBoxMinimizeToTray;
|
||||||
|
|
||||||
wxCheckBox* m_checkBoxMinimizeOnClose;
|
wxCheckBox* m_checkBoxMinimizeOnClose;
|
||||||
|
wxCheckBox* m_checkBoxUseProxy;
|
||||||
|
|
||||||
|
wxStaticText* m_staticTextProxyIP;
|
||||||
|
wxTextCtrl* m_textCtrlProxyIP;
|
||||||
|
wxStaticText* m_staticTextProxyPort;
|
||||||
|
wxTextCtrl* m_textCtrlProxyPort;
|
||||||
wxPanel* m_panelTest2;
|
wxPanel* m_panelTest2;
|
||||||
|
|
||||||
wxStaticText* m_staticText321;
|
wxStaticText* m_staticText321;
|
||||||
|
@ -226,6 +234,8 @@ class COptionsDialogBase : public wxDialog
|
||||||
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
|
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
|
||||||
virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); }
|
virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); }
|
||||||
virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); }
|
virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); }
|
||||||
|
virtual void OnCheckBoxUseProxy( wxCommandEvent& event ){ event.Skip(); }
|
||||||
|
virtual void OnKillFocusProxy( wxFocusEvent& event ){ event.Skip(); }
|
||||||
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
|
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
|
||||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||||
virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
|
virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
|
||||||
|
|
308
uiproject.fbp
308
uiproject.fbp
|
@ -1912,7 +1912,7 @@
|
||||||
<property name="flag">wxEXPAND</property>
|
<property name="flag">wxEXPAND</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="spacer" expanded="1">
|
<object class="spacer" expanded="1">
|
||||||
<property name="height">14</property>
|
<property name="height">16</property>
|
||||||
<property name="permission">protected</property>
|
<property name="permission">protected</property>
|
||||||
<property name="width">0</property>
|
<property name="width">0</property>
|
||||||
</object>
|
</object>
|
||||||
|
@ -2148,7 +2148,7 @@
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxTOP|wxBOTTOM</property>
|
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="wxSpinCtrl" expanded="1">
|
<object class="wxSpinCtrl" expanded="1">
|
||||||
<property name="bg"></property>
|
<property name="bg"></property>
|
||||||
|
@ -2379,7 +2379,7 @@
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL</property>
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="wxCheckBox" expanded="1">
|
<object class="wxCheckBox" expanded="1">
|
||||||
<property name="bg"></property>
|
<property name="bg"></property>
|
||||||
|
@ -2390,7 +2390,7 @@
|
||||||
<property name="font"></property>
|
<property name="font"></property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="label">M&inimize to system tray on close</property>
|
<property name="label">Mi&nimize to system tray on close</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">m_checkBoxMinimizeOnClose</property>
|
<property name="name">m_checkBoxMinimizeOnClose</property>
|
||||||
|
@ -2431,6 +2431,302 @@
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxBoxSizer" expanded="1">
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">bSizer102</property>
|
||||||
|
<property name="orient">wxHORIZONTAL</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxCheckBox" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="checked">0</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">&Connect through socks4 proxy: </property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">m_checkBoxUseProxy</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnCheckBox">OnCheckBoxUseProxy</event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxBoxSizer" expanded="1">
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">bSizer103</property>
|
||||||
|
<property name="orient">wxHORIZONTAL</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag"></property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="spacer" expanded="1">
|
||||||
|
<property name="height">0</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="width">18</property>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Proxy &IP:</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">m_staticTextProxyIP</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxTextCtrl" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_PROXYIP</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="maxlength">15</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">m_textCtrlProxyIP</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size">140,-1</property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="value"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus">OnKillFocusProxy</event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnText"></event>
|
||||||
|
<event name="OnTextEnter"></event>
|
||||||
|
<event name="OnTextMaxLen"></event>
|
||||||
|
<event name="OnTextURL"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label"> &Port:</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">m_staticTextProxyPort</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxTextCtrl" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_PROXYPORT</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="maxlength">5</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">m_textCtrlProxyPort</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size">55,-1</property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="value"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus">OnKillFocusProxy</event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnText"></event>
|
||||||
|
<event name="OnTextEnter"></event>
|
||||||
|
<event name="OnTextMaxLen"></event>
|
||||||
|
<event name="OnTextURL"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
@ -2490,7 +2786,7 @@
|
||||||
<property name="flag">wxEXPAND</property>
|
<property name="flag">wxEXPAND</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="spacer" expanded="1">
|
<object class="spacer" expanded="1">
|
||||||
<property name="height">14</property>
|
<property name="height">16</property>
|
||||||
<property name="permission">protected</property>
|
<property name="permission">protected</property>
|
||||||
<property name="width">0</property>
|
<property name="width">0</property>
|
||||||
</object>
|
</object>
|
||||||
|
@ -2558,7 +2854,7 @@
|
||||||
<property name="font"></property>
|
<property name="font"></property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="label">MyLabel</property>
|
<property name="label">Let's not start multiple pages until the first page is filled up</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">m_staticText69</property>
|
<property name="name">m_staticText69</property>
|
||||||
|
|
176
util.cpp
176
util.cpp
|
@ -5,8 +5,9 @@
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool fDebug = false;
|
bool fDebug = false;
|
||||||
|
bool fPrintToDebugger = false;
|
||||||
|
bool fPrintToConsole = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,8 +38,8 @@ public:
|
||||||
// Seed random number generator with screen scrape and other hardware sources
|
// Seed random number generator with screen scrape and other hardware sources
|
||||||
RAND_screen();
|
RAND_screen();
|
||||||
|
|
||||||
// Seed random number generator with perfmon data
|
// Seed random number generator with performance counter
|
||||||
RandAddSeed(true);
|
RandAddSeed();
|
||||||
}
|
}
|
||||||
~CInit()
|
~CInit()
|
||||||
{
|
{
|
||||||
|
@ -54,43 +55,45 @@ instance_of_cinit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RandAddSeed(bool fPerfmon)
|
void RandAddSeed()
|
||||||
{
|
{
|
||||||
// Seed with CPU performance counter
|
// Seed with CPU performance counter
|
||||||
LARGE_INTEGER PerformanceCount;
|
LARGE_INTEGER PerformanceCount;
|
||||||
QueryPerformanceCounter(&PerformanceCount);
|
QueryPerformanceCounter(&PerformanceCount);
|
||||||
RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5);
|
RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5);
|
||||||
memset(&PerformanceCount, 0, sizeof(PerformanceCount));
|
memset(&PerformanceCount, 0, sizeof(PerformanceCount));
|
||||||
|
|
||||||
static int64 nLastPerfmon;
|
|
||||||
if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60)
|
|
||||||
{
|
|
||||||
nLastPerfmon = GetTime();
|
|
||||||
|
|
||||||
// Seed with the entire set of perfmon data
|
|
||||||
unsigned char pdata[250000];
|
|
||||||
memset(pdata, 0, sizeof(pdata));
|
|
||||||
unsigned long nSize = sizeof(pdata);
|
|
||||||
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
|
||||||
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
|
||||||
if (ret == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
uint256 hash;
|
|
||||||
SHA256(pdata, nSize, (unsigned char*)&hash);
|
|
||||||
RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
|
|
||||||
hash = 0;
|
|
||||||
memset(pdata, 0, nSize);
|
|
||||||
|
|
||||||
time_t nTime;
|
|
||||||
time(&nTime);
|
|
||||||
struct tm* ptmTime = gmtime(&nTime);
|
|
||||||
char pszTime[200];
|
|
||||||
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
|
|
||||||
printf("%s RandAddSeed() %d bytes\n", pszTime, nSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RandAddSeedPerfmon()
|
||||||
|
{
|
||||||
|
// This can take up to 2 seconds, so only do it every 10 minutes
|
||||||
|
static int64 nLastPerfmon;
|
||||||
|
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||||
|
return;
|
||||||
|
nLastPerfmon = GetTime();
|
||||||
|
|
||||||
|
// Seed with the entire set of perfmon data
|
||||||
|
unsigned char pdata[250000];
|
||||||
|
memset(pdata, 0, sizeof(pdata));
|
||||||
|
unsigned long nSize = sizeof(pdata);
|
||||||
|
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
||||||
|
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
||||||
|
if (ret == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
uint256 hash;
|
||||||
|
SHA256(pdata, nSize, (unsigned char*)&hash);
|
||||||
|
RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
|
||||||
|
hash = 0;
|
||||||
|
memset(pdata, 0, nSize);
|
||||||
|
|
||||||
|
time_t nTime;
|
||||||
|
time(&nTime);
|
||||||
|
struct tm* ptmTime = gmtime(&nTime);
|
||||||
|
char pszTime[200];
|
||||||
|
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
|
||||||
|
printf("%s RandAddSeed() %d bytes\n", pszTime, nSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,27 +175,6 @@ bool error(const char* format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintException(std::exception* pex, const char* pszThread)
|
|
||||||
{
|
|
||||||
char pszModule[MAX_PATH];
|
|
||||||
pszModule[0] = '\0';
|
|
||||||
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
|
|
||||||
_strlwr(pszModule);
|
|
||||||
char pszMessage[1000];
|
|
||||||
if (pex)
|
|
||||||
snprintf(pszMessage, sizeof(pszMessage),
|
|
||||||
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
|
|
||||||
else
|
|
||||||
snprintf(pszMessage, sizeof(pszMessage),
|
|
||||||
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
|
|
||||||
printf("\n\n************************\n%s", pszMessage);
|
|
||||||
if (wxTheApp)
|
|
||||||
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
|
||||||
throw;
|
|
||||||
//DebugBreak();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ParseString(const string& str, char c, vector<string>& v)
|
void ParseString(const string& str, char c, vector<string>& v)
|
||||||
{
|
{
|
||||||
unsigned int i1 = 0;
|
unsigned int i1 = 0;
|
||||||
|
@ -268,6 +250,92 @@ bool ParseMoney(const char* pszIn, int64& nRet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<unsigned char> ParseHex(const char* psz)
|
||||||
|
{
|
||||||
|
vector<unsigned char> vch;
|
||||||
|
while (isspace(*psz))
|
||||||
|
psz++;
|
||||||
|
vch.reserve((strlen(psz)+1)/3);
|
||||||
|
|
||||||
|
static char phexdigit[256] =
|
||||||
|
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
|
||||||
|
|
||||||
|
while (*psz)
|
||||||
|
{
|
||||||
|
char c = phexdigit[(unsigned char)*psz++];
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
unsigned char n = (c << 4);
|
||||||
|
if (*psz)
|
||||||
|
{
|
||||||
|
char c = phexdigit[(unsigned char)*psz++];
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
n |= c;
|
||||||
|
vch.push_back(n);
|
||||||
|
}
|
||||||
|
while (isspace(*psz))
|
||||||
|
psz++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vch;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<unsigned char> ParseHex(const std::string& str)
|
||||||
|
{
|
||||||
|
return ParseHex(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
|
||||||
|
{
|
||||||
|
char pszModule[MAX_PATH];
|
||||||
|
pszModule[0] = '\0';
|
||||||
|
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
|
||||||
|
if (pex)
|
||||||
|
snprintf(pszMessage, 1000,
|
||||||
|
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
|
||||||
|
else
|
||||||
|
snprintf(pszMessage, 1000,
|
||||||
|
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogException(std::exception* pex, const char* pszThread)
|
||||||
|
{
|
||||||
|
char pszMessage[1000];
|
||||||
|
FormatException(pszMessage, pex, pszThread);
|
||||||
|
printf("\n%s", pszMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintException(std::exception* pex, const char* pszThread)
|
||||||
|
{
|
||||||
|
char pszMessage[1000];
|
||||||
|
FormatException(pszMessage, pex, pszThread);
|
||||||
|
printf("\n\n************************\n%s\n", pszMessage);
|
||||||
|
if (wxTheApp)
|
||||||
|
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
||||||
|
throw;
|
||||||
|
//DebugBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,7 +431,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
|
||||||
if (vTimeOffsets.empty())
|
if (vTimeOffsets.empty())
|
||||||
vTimeOffsets.push_back(0);
|
vTimeOffsets.push_back(0);
|
||||||
vTimeOffsets.push_back(nOffsetSample);
|
vTimeOffsets.push_back(nOffsetSample);
|
||||||
printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60);
|
printf("Added time data, samples %d, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
|
||||||
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
|
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
|
||||||
{
|
{
|
||||||
sort(vTimeOffsets.begin(), vTimeOffsets.end());
|
sort(vTimeOffsets.begin(), vTimeOffsets.end());
|
||||||
|
|
164
util.h
164
util.h
|
@ -67,15 +67,22 @@ inline T& REF(const T& val)
|
||||||
|
|
||||||
|
|
||||||
extern bool fDebug;
|
extern bool fDebug;
|
||||||
|
extern bool fPrintToDebugger;
|
||||||
|
extern bool fPrintToConsole;
|
||||||
|
extern map<string, string> mapArgs;
|
||||||
|
|
||||||
void RandAddSeed(bool fPerfmon=false);
|
void RandAddSeed();
|
||||||
|
void RandAddSeedPerfmon();
|
||||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
||||||
string strprintf(const char* format, ...);
|
string strprintf(const char* format, ...);
|
||||||
bool error(const char* format, ...);
|
bool error(const char* format, ...);
|
||||||
void PrintException(std::exception* pex, const char* pszThread);
|
void PrintException(std::exception* pex, const char* pszThread);
|
||||||
|
void LogException(std::exception* pex, const char* pszThread);
|
||||||
void ParseString(const string& str, char c, vector<string>& v);
|
void ParseString(const string& str, char c, vector<string>& v);
|
||||||
string FormatMoney(int64 n, bool fPlus=false);
|
string FormatMoney(int64 n, bool fPlus=false);
|
||||||
bool ParseMoney(const char* pszIn, int64& nRet);
|
bool ParseMoney(const char* pszIn, int64& nRet);
|
||||||
|
vector<unsigned char> ParseHex(const char* psz);
|
||||||
|
vector<unsigned char> ParseHex(const std::string& str);
|
||||||
bool FileExists(const char* psz);
|
bool FileExists(const char* psz);
|
||||||
int GetFilesize(FILE* file);
|
int GetFilesize(FILE* file);
|
||||||
uint64 GetRand(uint64 nMax);
|
uint64 GetRand(uint64 nMax);
|
||||||
|
@ -94,6 +101,7 @@ void AddTimeData(unsigned int ip, int64 nTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Wrapper to automatically initialize critical section
|
// Wrapper to automatically initialize critical section
|
||||||
// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection
|
// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection
|
||||||
class CCriticalSection
|
class CCriticalSection
|
||||||
|
@ -156,6 +164,85 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
if (!fPrintToConsole)
|
||||||
|
{
|
||||||
|
// print to debug.log
|
||||||
|
FILE* fileout = fopen("debug.log", "a");
|
||||||
|
if (fileout)
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
va_start(arg_ptr, pszFormat);
|
||||||
|
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||||
|
va_end(arg_ptr);
|
||||||
|
fclose(fileout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fPrintToDebugger)
|
||||||
|
{
|
||||||
|
// accumulate a line at a time
|
||||||
|
static CCriticalSection cs_OutputDebugStringF;
|
||||||
|
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
||||||
|
{
|
||||||
|
static char pszBuffer[50000];
|
||||||
|
static char* pend;
|
||||||
|
if (pend == NULL)
|
||||||
|
pend = pszBuffer;
|
||||||
|
va_list arg_ptr;
|
||||||
|
va_start(arg_ptr, pszFormat);
|
||||||
|
int limit = END(pszBuffer) - pend - 2;
|
||||||
|
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
|
||||||
|
va_end(arg_ptr);
|
||||||
|
if (ret < 0 || ret >= limit)
|
||||||
|
{
|
||||||
|
pend = END(pszBuffer) - 2;
|
||||||
|
*pend++ = '\n';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pend += ret;
|
||||||
|
*pend = '\0';
|
||||||
|
char* p1 = pszBuffer;
|
||||||
|
char* p2;
|
||||||
|
while (p2 = strchr(p1, '\n'))
|
||||||
|
{
|
||||||
|
p2++;
|
||||||
|
char c = *p2;
|
||||||
|
*p2 = '\0';
|
||||||
|
OutputDebugString(p1);
|
||||||
|
*p2 = c;
|
||||||
|
p1 = p2;
|
||||||
|
}
|
||||||
|
if (p1 != pszBuffer)
|
||||||
|
memmove(pszBuffer, p1, pend - p1 + 1);
|
||||||
|
pend -= (p1 - pszBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fPrintToConsole)
|
||||||
|
{
|
||||||
|
// print to console
|
||||||
|
va_list arg_ptr;
|
||||||
|
va_start(arg_ptr, pszFormat);
|
||||||
|
ret = vprintf(pszFormat, arg_ptr);
|
||||||
|
va_end(arg_ptr);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline string i64tostr(int64 n)
|
inline string i64tostr(int64 n)
|
||||||
{
|
{
|
||||||
return strprintf("%"PRId64, n);
|
return strprintf("%"PRId64, n);
|
||||||
|
@ -205,6 +292,11 @@ string HexStr(const T itbegin, const T itend, bool fSpaces=true)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline string HexStr(vector<unsigned char> vch, bool fSpaces=true)
|
||||||
|
{
|
||||||
|
return HexStr(vch.begin(), vch.end(), fSpaces);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
string HexNumStr(const T itbegin, const T itend, bool f0x=true)
|
string HexNumStr(const T itbegin, const T itend, bool f0x=true)
|
||||||
{
|
{
|
||||||
|
@ -222,75 +314,9 @@ void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSp
|
||||||
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
|
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline int OutputDebugStringF(const char* pszFormat, ...)
|
|
||||||
{
|
{
|
||||||
#ifdef __WXDEBUG__
|
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
||||||
// log file
|
|
||||||
FILE* fileout = fopen("debug.log", "a");
|
|
||||||
if (fileout)
|
|
||||||
{
|
|
||||||
va_list arg_ptr;
|
|
||||||
va_start(arg_ptr, pszFormat);
|
|
||||||
vfprintf(fileout, pszFormat, arg_ptr);
|
|
||||||
va_end(arg_ptr);
|
|
||||||
fclose(fileout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// accumulate a line at a time
|
|
||||||
static CCriticalSection cs_OutputDebugStringF;
|
|
||||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
|
||||||
{
|
|
||||||
static char pszBuffer[50000];
|
|
||||||
static char* pend;
|
|
||||||
if (pend == NULL)
|
|
||||||
pend = pszBuffer;
|
|
||||||
va_list arg_ptr;
|
|
||||||
va_start(arg_ptr, pszFormat);
|
|
||||||
int limit = END(pszBuffer) - pend - 2;
|
|
||||||
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
|
|
||||||
va_end(arg_ptr);
|
|
||||||
if (ret < 0 || ret >= limit)
|
|
||||||
{
|
|
||||||
pend = END(pszBuffer) - 2;
|
|
||||||
*pend++ = '\n';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pend += ret;
|
|
||||||
*pend = '\0';
|
|
||||||
char* p1 = pszBuffer;
|
|
||||||
char* p2;
|
|
||||||
while (p2 = strchr(p1, '\n'))
|
|
||||||
{
|
|
||||||
p2++;
|
|
||||||
char c = *p2;
|
|
||||||
*p2 = '\0';
|
|
||||||
OutputDebugString(p1);
|
|
||||||
*p2 = c;
|
|
||||||
p1 = p2;
|
|
||||||
}
|
|
||||||
if (p1 != pszBuffer)
|
|
||||||
memmove(pszBuffer, p1, pend - p1 + 1);
|
|
||||||
pend -= (p1 - pszBuffer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!wxTheApp)
|
|
||||||
{
|
|
||||||
// print to console
|
|
||||||
va_list arg_ptr;
|
|
||||||
va_start(arg_ptr, pszFormat);
|
|
||||||
vprintf(pszFormat, arg_ptr);
|
|
||||||
va_end(arg_ptr);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue