2010-03-17 07:25:19 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2011-12-14 08:40:48 +01:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-17 07:25:19 +01:00
//
// You can redistribute this code 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
// ==============================================================
# include "network_interface.h"
# include <exception>
# include <cassert>
# include "types.h"
# include "conversion.h"
# include "platform_util.h"
2010-03-20 00:26:00 +01:00
# include <fstream>
# include "util.h"
2010-03-17 07:25:19 +01:00
# include "leak_dumper.h"
using namespace Shared : : Platform ;
using namespace Shared : : Util ;
using namespace std ;
namespace Glest { namespace Game {
// =====================================================
// class NetworkInterface
// =====================================================
2010-07-09 17:01:49 +02:00
const int NetworkInterface : : readyWaitTimeout = 180000 ; // 3 minutes
2010-03-17 07:25:19 +01:00
bool NetworkInterface : : allowGameDataSynchCheck = false ;
bool NetworkInterface : : allowDownloadDataSynch = false ;
DisplayMessageFunction NetworkInterface : : pCB_DisplayMessage = NULL ;
void NetworkInterface : : sendMessage ( const NetworkMessage * networkMessage ) {
2011-11-25 10:12:53 +01:00
Socket * socket = getSocket ( false ) ;
2010-03-17 07:25:19 +01:00
networkMessage - > send ( socket ) ;
}
2011-11-27 06:27:50 +01:00
NetworkMessageType NetworkInterface : : getNextMessageType ( )
2010-03-17 07:25:19 +01:00
{
2011-11-25 10:12:53 +01:00
Socket * socket = getSocket ( false ) ;
2010-03-17 07:25:19 +01:00
int8 messageType = nmtInvalid ;
2011-11-27 06:27:50 +01:00
if ( socket ! = NULL & &
socket - > hasDataToRead ( ) = = true ) {
2010-03-17 07:25:19 +01:00
//peek message type
2011-11-25 23:38:25 +01:00
int dataSize = socket - > getDataToRead ( ) ;
if ( dataSize > = sizeof ( messageType ) ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , dataSize ) ;
int iPeek = socket - > peek ( & messageType , sizeof ( messageType ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , iPeek , messageType , sizeof ( messageType ) ) ;
}
2011-11-27 06:27:50 +01:00
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , messageType , sizeof ( messageType ) , dataSize ) ;
}
2010-03-17 07:25:19 +01:00
//sanity check new message type
2010-05-13 09:13:53 +02:00
if ( messageType < 0 | | messageType > = nmtCount ) {
if ( getConnectHasHandshaked ( ) = = true ) {
throw runtime_error ( " Invalid message type: " + intToStr ( messageType ) ) ;
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored) \n " , __FILE__ , __FUNCTION__ , __LINE__ , messageType ) ;
2010-05-13 09:13:53 +02:00
}
2010-03-17 07:25:19 +01:00
}
}
return static_cast < NetworkMessageType > ( messageType ) ;
}
bool NetworkInterface : : receiveMessage ( NetworkMessage * networkMessage ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] \n " , __FILE__ , __FUNCTION__ ) ;
2010-03-17 07:25:19 +01:00
2011-11-25 10:12:53 +01:00
Socket * socket = getSocket ( false ) ;
2010-03-17 07:25:19 +01:00
return networkMessage - > receive ( socket ) ;
}
bool NetworkInterface : : isConnected ( ) {
bool result = ( getSocket ( ) ! = NULL & & getSocket ( ) - > isConnected ( ) ) ;
return result ;
}
void NetworkInterface : : DisplayErrorMessage ( string sErr , bool closeSocket ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] sErr [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , sErr . c_str ( ) ) ;
2010-03-17 14:22:08 +01:00
if ( closeSocket = = true & & getSocket ( ) ! = NULL )
{
close ( ) ;
}
2010-03-17 07:25:19 +01:00
if ( pCB_DisplayMessage ! = NULL ) {
pCB_DisplayMessage ( sErr . c_str ( ) , false ) ;
}
else {
throw runtime_error ( sErr ) ;
}
2010-05-28 16:59:09 +02:00
}
2010-03-17 07:25:19 +01:00
2011-11-25 22:56:36 +01:00
std : : vector < ChatMsgInfo > NetworkInterface : : getChatTextList ( bool clearList ) {
2011-11-25 18:01:35 +01:00
std : : vector < ChatMsgInfo > result ;
2011-11-25 22:56:36 +01:00
if ( chatTextList . empty ( ) = = false ) {
result = chatTextList ;
2011-11-25 18:01:35 +01:00
2011-11-25 22:56:36 +01:00
if ( clearList = = true ) {
chatTextList . clear ( ) ;
}
}
2011-11-25 18:01:35 +01:00
return result ;
}
2010-05-28 16:59:09 +02:00
void NetworkInterface : : clearChatInfo ( ) {
2011-09-01 03:11:23 +02:00
if ( chatTextList . empty ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] chatTextList.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chatTextList . size ( ) ) ;
2010-07-02 18:54:28 +02:00
chatTextList . clear ( ) ;
}
2010-03-17 07:25:19 +01:00
}
2010-06-04 21:42:58 +02:00
std : : string NetworkInterface : : getIpAddress ( ) {
std : : string result = " " ;
2011-11-25 10:12:53 +01:00
Socket * socket = getSocket ( ) ;
if ( socket ! = NULL ) {
result = socket - > getIpAddress ( ) ;
2010-06-04 21:42:58 +02:00
}
return result ;
}
float NetworkInterface : : getThreadedPingMS ( std : : string host ) {
float result = - 1 ;
if ( getSocket ( ) ! = NULL ) {
result = getSocket ( ) - > getThreadedPingMS ( host ) ;
}
return result ;
}
2010-03-17 07:25:19 +01:00
// =====================================================
// class GameNetworkInterface
// =====================================================
GameNetworkInterface : : GameNetworkInterface ( ) {
quit = false ;
}
2010-03-18 22:26:40 +01:00
void GameNetworkInterface : : requestCommand ( const NetworkCommand * networkCommand , bool insertAtStart ) {
2010-05-28 07:31:17 +02:00
assert ( networkCommand ! = NULL ) ;
//Mutex *mutex = getServerSynchAccessor();
2010-05-21 18:36:08 +02:00
2010-03-18 22:26:40 +01:00
if ( insertAtStart = = false ) {
2010-05-28 07:31:17 +02:00
//if(mutex != NULL) mutex->p();
2010-03-18 22:26:40 +01:00
requestedCommands . push_back ( * networkCommand ) ;
2010-05-28 07:31:17 +02:00
//if(mutex != NULL) mutex->v();
2010-03-18 22:26:40 +01:00
}
else {
2010-05-28 07:31:17 +02:00
//if(mutex != NULL) mutex->p();
2010-03-18 22:26:40 +01:00
requestedCommands . insert ( requestedCommands . begin ( ) , * networkCommand ) ;
2010-05-28 07:31:17 +02:00
//if(mutex != NULL) mutex->v();
2010-03-18 22:26:40 +01:00
}
}
2010-03-17 07:25:19 +01:00
// =====================================================
// class FileTransferSocketThread
// =====================================================
const int32 SEND_FILE = 0x20 ;
const int32 ACK = 0x47 ;
FileTransferSocketThread : : FileTransferSocketThread ( FileTransferInfo fileInfo )
{
this - > info = fileInfo ;
this - > info . serverPort + = 100 ;
}
void FileTransferSocketThread : : execute ( )
{
if ( info . hostType = = eServer )
{
ServerSocket serverSocket ;
//serverSocket.setBlock(false);
serverSocket . bind ( this - > info . serverPort ) ;
serverSocket . listen ( 1 ) ;
Socket * clientSocket = serverSocket . accept ( ) ;
char data [ 513 ] = " " ;
memset ( data , 0 , 256 ) ;
2011-04-24 06:22:19 +02:00
clientSocket - > receive ( data , 256 , true ) ;
2010-03-17 07:25:19 +01:00
if ( * data = = SEND_FILE )
{
FileInfo file ;
memcpy ( & file , data + 1 , sizeof ( file ) ) ;
* data = ACK ;
clientSocket - > send ( data , 256 ) ;
Checksum checksum ;
checksum . addFile ( file . fileName ) ;
file . filecrc = checksum . getSum ( ) ;
ifstream infile ( file . fileName . c_str ( ) , ios : : in | ios : : binary | ios : : ate ) ;
if ( infile . is_open ( ) = = true )
{
file . filesize = infile . tellg ( ) ;
infile . seekg ( 0 , ios : : beg ) ;
memset ( data , 0 , 256 ) ;
* data = SEND_FILE ;
memcpy ( data + 1 , & file , sizeof ( file ) ) ;
clientSocket - > send ( data , 256 ) ;
2011-04-24 06:22:19 +02:00
clientSocket - > receive ( data , 256 , true ) ;
2010-05-01 22:14:25 +02:00
if ( * data ! = ACK ) {
//transfer error
}
2010-03-17 07:25:19 +01:00
int remain = file . filesize % 512 ;
int packs = ( file . filesize - remain ) / 512 ;
while ( packs - - )
{
infile . read ( data , 512 ) ;
//if(!ReadFile(file,data,512,&read,NULL))
// ; //read error
//if(written!=pack)
// ; //read error
clientSocket - > send ( data , 512 ) ;
2011-04-24 06:22:19 +02:00
clientSocket - > receive ( data , 256 , true ) ;
2010-05-01 22:14:25 +02:00
if ( * data ! = ACK ) {
//transfer error
}
2010-03-17 07:25:19 +01:00
}
infile . read ( data , remain ) ;
//if(!ReadFile(file,data,remain,&read,NULL))
// ; //read error
//if(written!=pack)
// ; //read error
clientSocket - > send ( data , remain ) ;
2011-04-24 06:22:19 +02:00
clientSocket - > receive ( data , 256 , true ) ;
2010-05-01 22:14:25 +02:00
if ( * data ! = ACK ) {
//transfer error
}
2010-03-17 07:25:19 +01:00
infile . close ( ) ;
}
}
delete clientSocket ;
}
else
{
Ip ip ( this - > info . serverIP ) ;
ClientSocket clientSocket ;
//clientSocket.setBlock(false);
clientSocket . connect ( this - > info . serverIP , this - > info . serverPort ) ;
if ( clientSocket . isConnected ( ) = = true )
{
FileInfo file ;
file . fileName = this - > info . fileName ;
//file.filesize =
//file.filecrc = this->info.
string path = extractDirectoryPathFromFile ( file . fileName ) ;
createDirectoryPaths ( path ) ;
ofstream outFile ( file . fileName . c_str ( ) , ios_base : : binary | ios_base : : out ) ;
if ( outFile . is_open ( ) = = true )
{
char data [ 513 ] = " " ;
memset ( data , 0 , 256 ) ;
* data = SEND_FILE ;
memcpy ( data + 1 , & file , sizeof ( file ) ) ;
clientSocket . send ( data , 256 ) ;
2011-04-24 06:22:19 +02:00
clientSocket . receive ( data , 256 , true ) ;
2010-05-01 22:14:25 +02:00
if ( * data ! = ACK ) {
//transfer error
}
2010-03-17 07:25:19 +01:00
2011-04-24 06:22:19 +02:00
clientSocket . receive ( data , 256 , true ) ;
2010-03-17 07:25:19 +01:00
if ( * data = = SEND_FILE )
{
memcpy ( & file , data + 1 , sizeof ( file ) ) ;
* data = ACK ;
clientSocket . send ( data , 256 ) ;
int remain = file . filesize % 512 ;
int packs = ( file . filesize - remain ) / 512 ;
while ( packs - - )
{
2011-04-24 06:22:19 +02:00
clientSocket . receive ( data , 512 , true ) ;
2010-03-17 07:25:19 +01:00
outFile . write ( data , 512 ) ;
if ( outFile . bad ( ) )
{
2011-09-01 03:11:23 +02:00
//int ii = 0;
2010-03-17 07:25:19 +01:00
}
//if(!WriteFile(file,data,512,&written,NULL))
// ; //write error
//if(written != pack)
// ; //write error
* data = ACK ;
clientSocket . send ( data , 256 ) ;
}
2011-04-24 06:22:19 +02:00
clientSocket . receive ( data , remain , true ) ;
2010-03-17 07:25:19 +01:00
outFile . write ( data , remain ) ;
if ( outFile . bad ( ) )
{
2011-09-01 03:11:23 +02:00
//int ii = 0;
2010-03-17 07:25:19 +01:00
}
//if(!WriteFile(file,data,remain,&written,NULL))
// ; //write error
//if(written!=pack)
// ; //write error
* data = ACK ;
clientSocket . send ( data , 256 ) ;
Checksum checksum ;
checksum . addFile ( file . fileName ) ;
int32 crc = checksum . getSum ( ) ;
if ( file . filecrc ! = crc )
{
2011-09-01 03:11:23 +02:00
//int ii = 0;
2010-03-17 07:25:19 +01:00
}
//if(calc_crc(file)!=info.crc)
// ; //transfeer error
}
outFile . close ( ) ;
}
}
}
}
} } //end namespace