From 7e62e6472abecf920a5f8a3a18a54178b00b77e2 Mon Sep 17 00:00:00 2001 From: lotodore Date: Fri, 14 Jan 2011 21:33:36 +0000 Subject: [PATCH] Adding new connectivity test program. --- connectivity.pro | 97 +++++++++++++++ src/connectivity.cpp | 272 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 369 insertions(+) create mode 100644 connectivity.pro create mode 100644 src/connectivity.cpp diff --git a/connectivity.pro b/connectivity.pro new file mode 100644 index 00000000..a67a872f --- /dev/null +++ b/connectivity.pro @@ -0,0 +1,97 @@ +# QMake pro-file for the PokerTH dedicated server + +isEmpty( PREFIX ){ + PREFIX =/usr +} + +TEMPLATE = app +CODECFORSRC = UTF-8 + +CONFIG += thread console embed_manifest_exe exceptions rtti stl warn_on + +UI_DIR = uics +TARGET = bin/connectivity +MOC_DIR = mocs +OBJECTS_DIR = obj +DEFINES += PREFIX=\"$${PREFIX}\" +QT -= core gui +QMAKE_CXXFLAGS += -std=gnu++0x +#PRECOMPILED_HEADER = src/pch_lib.h + +INCLUDEPATH += . \ + src \ + src/third_party/asn1 + +DEPENDPATH += . \ + src \ + src/third_party/asn1 + +# Input +HEADERS += \ + src/game_defs.h + +SOURCES += \ + src/connectivity.cpp + +LIBS += -lpokerth_protocol + +unix : !mac { + + ##### My release static build options + #QMAKE_CXXFLAGS += -ffunction-sections -fdata-sections + #QMAKE_LFLAGS += -Wl,--gc-sections + + QMAKE_LIBDIR += lib $${PREFIX}/lib /opt/gsasl/lib + INCLUDEPATH += $${PREFIX}/include + LIB_DIRS = $${PREFIX}/lib $${PREFIX}/lib64 + BOOST_PROGRAM_OPTIONS = boost_program_options boost_program_options-mt + BOOST_SYS = boost_system boost_system-mt + + + # + # searching in $PREFIX/lib and $PREFIX/lib64 + # to override the default '/usr' pass PREFIX + # variable to qmake. + # + for(dir, LIB_DIRS){ + exists($$dir){ + for(lib, BOOST_PROGRAM_OPTIONS):exists($${dir}/lib$${lib}.so*) { + message("Found $$lib") + BOOST_PROGRAM_OPTIONS = -l$$lib + } + for(lib, BOOST_PROGRAM_OPTIONS):exists($${dir}/lib$${lib}.a) { + message("Found $$lib") + BOOST_PROGRAM_OPTIONS = -l$$lib + } + for(lib, BOOST_SYS):exists($${dir}/lib$${lib}.so*) { + message("Found $$lib") + BOOST_SYS = -l$$lib + } + for(lib, BOOST_SYS):exists($${dir}/lib$${lib}.a) { + message("Found $$lib") + BOOST_SYS = -l$$lib + } + } + } + BOOST_LIBS = $$BOOST_PROGRAM_OPTIONS $$BOOST_SYS + !count(BOOST_LIBS, 2){ + error("Unable to find boost libraries in PREFIX=$${PREFIX}") + } + + UNAME = $$system(uname -s) + BSD = $$find(UNAME, "BSD") + kFreeBSD = $$find(UNAME, "kFreeBSD") + + LIBS += $$BOOST_LIBS + LIBS += -lgsasl + + POST_TARGETDEPS += ./lib/libpokerth_protocol.a + + #### INSTALL #### + + binary.path += $${PREFIX}/bin/ + binary.files += connectivity + + INSTALLS += binary +} + diff --git a/src/connectivity.cpp b/src/connectivity.cpp new file mode 100644 index 00000000..ebf6c74f --- /dev/null +++ b/src/connectivity.cpp @@ -0,0 +1,272 @@ +/*************************************************************************** + * Copyright (C) 2011 by Lothar May * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +// Connectivity test program for PokerTH + +#include +#include +#include +#include + +#include + +using namespace std; +using boost::asio::ip::tcp; +namespace po = boost::program_options; + +// Global receive buffer +boost::array recBuf; +size_t recBufPos = 0; +boost::array sendBuf; + +static int +net_packet_print_to_string(const void *buffer, size_t size, void *packetStr) +{ + string *tmpString = (string *)packetStr; + *tmpString += string((const char *)buffer, size); + return 0; +} + +PokerTHMessage_t * +receiveMessage(tcp::socket &socket, bool recursed = false) +{ + PokerTHMessage_t *msg = NULL; + asn_dec_rval_t retVal = ber_decode(0, &asn_DEF_PokerTHMessage, (void **)&msg, recBuf.data(), recBufPos); + if(retVal.code == RC_OK) + { + if (retVal.consumed < recBufPos) + { + recBufPos -= retVal.consumed; + memmove(recBuf.c_array(), recBuf.c_array() + retVal.consumed, recBufPos); + } + else + { + recBufPos = 0; + } + } + else + { + // Free the partially decoded message (if applicable). + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + if (!recursed) + { + recBufPos += socket.receive(boost::asio::buffer(recBuf.c_array() + recBufPos, 512 - recBufPos)); + return receiveMessage(socket, true); + } + else + return msg = NULL; + } + return msg; +} + +bool +sendMessage(tcp::socket &socket, PokerTHMessage_t *msg) +{ + bool retVal = false; + if (msg) + { + asn_enc_rval_t e = der_encode_to_buffer(&asn_DEF_PokerTHMessage, msg, sendBuf.data(), 512); + if (e.encoded != -1) + { + socket.send(boost::asio::buffer(sendBuf.data(), e.encoded)); + retVal = true; + } + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + } + return retVal; +} + +int +main(int argc, char *argv[]) +{ + // Check command line options. + po::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("server,s", po::value(), "PokerTH server name") + ("port,o", po::value(), "PokerTH server port") + ("mode,m", po::value(), "set mode (0=connection test, 1=lag test)") + ("username,u", po::value(), "user name used for test") + ("password,p", "password used for test") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + cout << desc << endl; + return 1; + } + if (!vm.count("server") || !vm.count("port") || !vm.count("mode") || !vm.count("username")) + { + cout << "Missing option!" << endl << desc << endl; + return 1; + } + + string server(vm["server"].as()); + string port = vm["port"].as(); + int mode = vm["mode"].as(); + string username(vm["username"].as()); + string password; + /*if (vm.count("password")) + { + password = vm["password"].as(); + }*/ + + // Connect to the PokerTH server. + boost::timers::portable::microsec_timer perfTimer; + boost::asio::io_service io_service; + tcp::resolver resolver(io_service); + tcp::resolver::query query(server, port); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + tcp::resolver::iterator end; + tcp::socket socket(io_service); + boost::system::error_code error = boost::asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + socket.close(); + socket.connect(*endpoint_iterator++, error); + } + if (error) + { + cout << "Connect failed" << endl; + return 1; + } + if (mode == 1) + { + cout << "Connect.value " << perfTimer.elapsed().total_milliseconds() << endl; + } + perfTimer.restart(); + + // Receive server information + PokerTHMessage_t *msg = receiveMessage(socket); + if (!msg || msg->present != PokerTHMessage_PR_announceMessage) + { + cout << "Announce failed" << endl; + return 1; + } + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + + // Send init + msg = (PokerTHMessage_t *)calloc(1, sizeof(PokerTHMessage_t)); + msg->present = PokerTHMessage_PR_initMessage; + InitMessage_t *netInit = &msg->choice.initMessage; + netInit->requestedVersion.major = 1; + netInit->requestedVersion.minor = 0; + if (password.empty()) + { + netInit->login.present = login_PR_guestLogin; + GuestLogin_t *guestLogin = &netInit->login.choice.guestLogin; + OCTET_STRING_fromBuf(&guestLogin->nickName, + username.c_str(), + username.length()); + } + if (!sendMessage(socket, msg)) + { + cout << "Init failed" << endl; + return 1; + } + + // Receive init ack + msg = receiveMessage(socket); + if (!msg || msg->present != PokerTHMessage_PR_initAckMessage) + { + cout << "Init ack failed" << endl; + return 1; + } + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + + if (mode == 1) + { + cout << "Init.value " << perfTimer.elapsed().total_milliseconds() << endl; + } + perfTimer.restart(); + + // Send create game + msg = (PokerTHMessage_t *)calloc(1, sizeof(PokerTHMessage_t)); + msg->present = PokerTHMessage_PR_joinGameRequestMessage; + JoinGameRequestMessage_t *netJoinGame = &msg->choice.joinGameRequestMessage; + string tmpGamePassword("blah123"); + netJoinGame->password = OCTET_STRING_new_fromBuf( + &asn_DEF_UTF8String, + tmpGamePassword.c_str(), + tmpGamePassword.length()); + netJoinGame->joinGameAction.present = joinGameAction_PR_joinNewGame; + JoinNewGame_t *joinNew = &netJoinGame->joinGameAction.choice.joinNewGame; + string tmpGameName("_perftest_do_not_join_" + username); + joinNew->gameInfo.netGameType = netGameType_normalGame; + joinNew->gameInfo.maxNumPlayers = 10; + joinNew->gameInfo.raiseIntervalMode.present = raiseIntervalMode_PR_raiseEveryHands; + joinNew->gameInfo.raiseIntervalMode.choice.raiseEveryHands = 5; + joinNew->gameInfo.endRaiseMode = endRaiseMode_keepLastBlind; + joinNew->gameInfo.proposedGuiSpeed = 5; + joinNew->gameInfo.delayBetweenHands = 6; + joinNew->gameInfo.playerActionTimeout = 10; + joinNew->gameInfo.endRaiseSmallBlindValue = 0; + joinNew->gameInfo.firstSmallBlind = 50; + joinNew->gameInfo.startMoney = 2000; + OCTET_STRING_fromBuf(&joinNew->gameInfo.gameName, + tmpGameName.c_str(), + tmpGameName.length()); + if (!sendMessage(socket, msg)) + { + cout << "Create game failed" << endl; + return 1; + } + msg = NULL; + // Receive join game ack + do + { + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + msg = receiveMessage(socket); + if (!msg) + { + cout << "Receive in lobby failed" << endl; + return 1; + } + if (msg->present == PokerTHMessage_PR_errorMessage) + { + cout << "Received error" << endl; + return 1; + } + } while (msg->present != PokerTHMessage_PR_joinGameReplyMessage); + if (msg->choice.joinGameReplyMessage.joinGameResult.present != joinGameResult_PR_joinGameAck) + { + cout << "Join game ack failed" << endl; + string packetString; + xer_encode(&asn_DEF_PokerTHMessage, msg, XER_F_BASIC, &net_packet_print_to_string, &packetString); + cout << packetString << endl; + return 1; + } + ASN_STRUCT_FREE(asn_DEF_PokerTHMessage, msg); + + if (mode == 1) + { + cout << "CreateGame.value " << perfTimer.elapsed().total_milliseconds() << endl; + } + else + { + cout << "Success" << endl; + } + perfTimer.restart(); + return 0; +} +