2007-06-06 22:29:40 +03:00
// CMT.cpp : Defines the entry point for the console application.
//
2008-08-04 18:56:36 +03:00
# include "stdafx.h"
2007-06-06 22:29:40 +03:00
# include <cmath>
2007-06-20 15:00:18 +03:00
# include <string>
2007-06-06 22:29:40 +03:00
# include <vector>
2008-07-27 20:07:37 +03:00
# include <queue>
2007-06-06 22:29:40 +03:00
# include <cmath>
2008-09-17 13:18:22 +03:00
# include <boost/algorithm/string.hpp>
# include "boost/filesystem/operations.hpp"
2008-09-12 11:51:46 +03:00
# include <boost/interprocess/mapped_region.hpp>
# include <boost/interprocess/shared_memory_object.hpp>
2008-07-25 20:28:28 +03:00
# include <boost/thread.hpp>
2008-08-04 12:05:52 +03:00
# include "SDL_ttf.h"
2008-07-25 20:28:28 +03:00
# include "SDL_mixer.h"
# include "SDL_Extensions.h"
2008-08-04 18:56:36 +03:00
# include "SDL_framerate.h"
# include "CGameInfo.h"
2007-07-07 19:04:15 +03:00
# include "mapHandler.h"
# include "global.h"
2008-08-04 18:56:36 +03:00
# include "CPreGame.h"
2008-09-17 13:18:22 +03:00
# include "CCastleInterface.h"
2007-08-15 18:13:11 +03:00
# include "CConsoleHandler.h"
2007-08-21 16:48:18 +03:00
# include "CCursorHandler.h"
2007-08-29 15:18:31 +03:00
# include "CPathfinder.h"
# include "CGameState.h"
2007-09-14 16:11:10 +03:00
# include "CCallback.h"
2007-11-19 00:58:28 +02:00
# include "CPlayerInterface.h"
2007-10-14 15:11:18 +03:00
# include "CLuaHandler.h"
2007-12-06 20:55:58 +02:00
# include "CAdvmapInterface.h"
2008-07-25 20:28:28 +03:00
# include "hch/CBuildingHandler.h"
# include "hch/CVideoHandler.h"
# include "hch/CAbilityHandler.h"
# include "hch/CHeroHandler.h"
# include "hch/CCreatureHandler.h"
# include "hch/CSpellHandler.h"
# include "hch/CMusicHandler.h"
# include "hch/CLodHandler.h"
# include "hch/CDefHandler.h"
# include "hch/CAmbarCendamo.h"
# include "hch/CGeneralTextHandler.h"
2008-07-01 11:01:02 +03:00
# include "client/Graphics.h"
2008-08-04 12:05:52 +03:00
# include "client/Client.h"
2008-11-09 00:29:19 +02:00
# include "client/CConfigHandler.h"
2008-07-03 18:03:32 +03:00
# include "lib/Connection.h"
2008-09-12 11:51:46 +03:00
# include "lib/Interprocess.h"
2008-07-25 20:28:28 +03:00
# include "lib/VCMI_Lib.h"
2008-06-30 03:06:41 +03:00
std : : string NAME = NAME_VER + std : : string ( " (client) " ) ;
2008-06-13 00:08:04 +03:00
DLL_EXPORT void initDLL ( CLodHandler * b ) ;
2008-04-25 12:25:59 +03:00
SDL_Surface * screen , * screen2 ;
2008-08-04 18:56:36 +03:00
extern SDL_Surface * CSDL_Ext : : std32bppSurface ;
2008-07-27 20:07:37 +03:00
std : : queue < SDL_Event > events ;
2008-08-04 18:56:36 +03:00
boost : : mutex eventsM ;
TTF_Font * TNRB16 , * TNR , * GEOR13 , * GEORXX , * GEORM , * GEOR16 ;
2008-09-12 11:51:46 +03:00
namespace intpr = boost : : interprocess ;
2008-10-19 02:20:48 +03:00
void processCommand ( const std : : string & message , CClient * & client ) ;
2008-08-04 12:05:52 +03:00
# ifndef __GNUC__
2008-06-30 03:06:41 +03:00
int _tmain ( int argc , _TCHAR * argv [ ] )
2008-08-04 18:56:36 +03:00
# else
2008-09-10 00:10:24 +03:00
int main ( int argc , char * * argv )
2008-08-04 18:56:36 +03:00
# endif
2008-07-01 11:01:02 +03:00
{
2008-11-09 00:29:19 +02:00
tlog0 < < " Starting... " < < std : : endl ;
THC timeHandler tmh , total , pomtime ;
2008-10-19 02:20:48 +03:00
CClient * client = NULL ;
2008-09-17 13:18:22 +03:00
boost : : thread * console = NULL ;
2008-11-09 00:29:19 +02:00
2008-07-27 20:07:37 +03:00
std : : cout . flags ( ios : : unitbuf ) ;
2008-11-09 00:29:19 +02:00
logfile = new std : : ofstream ( " VCMI_Client_log.txt " ) ;
: : console = new CConsoleHandler ;
* : : console - > cb = boost : : bind ( processCommand , _1 , boost : : ref ( client ) ) ;
console = new boost : : thread ( boost : : bind ( & CConsoleHandler : : run , : : console ) ) ;
tlog0 < < " Creating console and logfile: " < < pomtime . getDif ( ) < < std : : endl ;
conf . init ( ) ;
tlog0 < < " Loading settings: " < < pomtime . getDif ( ) < < std : : endl ;
2008-09-19 11:16:19 +03:00
tlog0 < < NAME < < std : : endl ;
2008-11-09 00:29:19 +02:00
2008-06-16 13:51:14 +03:00
srand ( time ( NULL ) ) ;
CPG = NULL ;
atexit ( SDL_Quit ) ;
CGameInfo * cgi = CGI = new CGameInfo ; //contains all global informations about game (texts, lodHandlers, map handler itp.)
2008-11-09 00:29:19 +02:00
2008-09-17 13:18:22 +03:00
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO ) = = 0 )
2007-06-06 22:29:40 +03:00
{
2008-11-09 00:29:19 +02:00
screen = SDL_SetVideoMode ( conf . cc . resx , conf . cc . resy , conf . cc . bpp , SDL_SWSURFACE | SDL_DOUBLEBUF | ( conf . cc . fullscreen ? SDL_FULLSCREEN : 0 ) ) ; //initializing important global surface
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Initializing screen: " < < pomtime . getDif ( ) ;
tlog0 < < std : : endl ;
2008-06-30 03:06:41 +03:00
SDL_WM_SetCaption ( NAME . c_str ( ) , " " ) ; //set window title
2008-06-16 13:51:14 +03:00
# if SDL_BYTEORDER == SDL_BIG_ENDIAN
int rmask = 0xff000000 ; int gmask = 0x00ff0000 ; int bmask = 0x0000ff00 ; int amask = 0x000000ff ;
# else
int rmask = 0x000000ff ; int gmask = 0x0000ff00 ; int bmask = 0x00ff0000 ; int amask = 0xff000000 ;
2008-08-04 18:56:36 +03:00
# endif
2008-02-06 15:50:40 +02:00
CSDL_Ext : : std32bppSurface = SDL_CreateRGBSurface ( SDL_SWSURFACE , 1 , 1 , 32 , rmask , gmask , bmask , amask ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Initializing minors: " < < pomtime . getDif ( ) < < std : : endl ;
2007-06-12 12:33:20 +03:00
TTF_Init ( ) ;
2008-08-17 22:15:31 +03:00
TNRB16 = TTF_OpenFont ( " Fonts " PATHSEPARATOR " tnrb.ttf " , 16 ) ;
GEOR13 = TTF_OpenFont ( " Fonts " PATHSEPARATOR " georgia.ttf " , 13 ) ;
GEOR16 = TTF_OpenFont ( " Fonts " PATHSEPARATOR " georgia.ttf " , 16 ) ;
GEORXX = TTF_OpenFont ( " Fonts " PATHSEPARATOR " tnrb.ttf " , 22 ) ;
GEORM = TTF_OpenFont ( " Fonts " PATHSEPARATOR " georgia.ttf " , 10 ) ;
2008-06-16 13:51:14 +03:00
atexit ( TTF_Quit ) ;
2008-09-19 11:16:19 +03:00
THC tlog0 < < " \t Initializing fonts: " < < pomtime . getDif ( ) < < std : : endl ;
2007-09-18 16:30:26 +03:00
CMusicHandler * mush = new CMusicHandler ; //initializing audio
2007-06-20 15:00:18 +03:00
mush - > initMusics ( ) ;
2008-08-04 18:56:36 +03:00
//audio initialized
2007-07-09 08:57:30 +03:00
cgi - > mush = mush ;
2008-11-09 00:29:19 +02:00
tlog0 < < " \t Initializing sound: " < < pomtime . getDif ( ) < < std : : endl ;
tlog0 < < " Initializing screen, fonts and sound handling: " < < tmh . getDif ( ) < < std : : endl ;
2008-06-14 13:20:18 +03:00
CDefHandler : : Spriteh = cgi - > spriteh = new CLodHandler ( ) ;
2008-08-17 22:15:31 +03:00
cgi - > spriteh - > init ( " Data " PATHSEPARATOR " H3sprite.lod " , " Sprites " ) ;
2008-06-12 09:45:51 +03:00
BitmapHandler : : bitmaph = cgi - > bitmaph = new CLodHandler ;
2008-08-17 22:15:31 +03:00
cgi - > bitmaph - > init ( " Data " PATHSEPARATOR " H3bitmap.lod " , " Data " ) ;
2008-11-09 00:29:19 +02:00
tlog0 < < " Loading .lod files: " < < tmh . getDif ( ) < < std : : endl ;
2008-09-17 13:18:22 +03:00
initDLL ( cgi - > bitmaph , : : console , logfile ) ;
2008-07-25 20:28:28 +03:00
CGI - > arth = VLC - > arth ;
2008-07-27 23:00:41 +03:00
CGI - > creh = VLC - > creh ;
2008-07-25 20:28:28 +03:00
CGI - > townh = VLC - > townh ;
CGI - > heroh = VLC - > heroh ;
CGI - > objh = VLC - > objh ;
2008-08-20 09:57:53 +03:00
CGI - > spellh = VLC - > spellh ;
2008-07-25 20:28:28 +03:00
CGI - > dobjinfo = VLC - > dobjinfo ;
2008-08-04 18:56:36 +03:00
CGI - > buildh = VLC - > buildh ;
2008-09-19 11:16:19 +03:00
tlog0 < < " Initializing VCMI_Lib: " < < tmh . getDif ( ) < < std : : endl ;
2008-06-14 13:20:18 +03:00
pomtime . getDif ( ) ;
2008-08-01 21:13:33 +03:00
cgi - > curh = new CCursorHandler ;
cgi - > curh - > initCursor ( ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Screen handler: " < < pomtime . getDif ( ) < < std : : endl ;
2008-06-14 13:20:18 +03:00
CAbilityHandler * abilh = new CAbilityHandler ;
abilh - > loadAbilities ( ) ;
cgi - > abilh = abilh ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Ability handler: " < < pomtime . getDif ( ) < < std : : endl ;
tlog0 < < " Preparing first handlers: " < < tmh . getDif ( ) < < std : : endl ;
2008-06-16 13:51:14 +03:00
pomtime . getDif ( ) ;
2008-06-14 13:20:18 +03:00
graphics = new Graphics ( ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Main graphics: " < < tmh . getDif ( ) < < std : : endl ;
2008-06-16 13:51:14 +03:00
std : : vector < CDefHandler * * > animacje ;
for ( std : : vector < CHeroClass * > : : iterator i = cgi - > heroh - > heroClasses . begin ( ) ; i ! = cgi - > heroh - > heroClasses . end ( ) ; i + + )
animacje . push_back ( & ( ( * i ) - > * ( & CHeroClass : : moveAnim ) ) ) ;
graphics - > loadHeroAnim ( animacje ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Hero animations: " < < tmh . getDif ( ) < < std : : endl ;
tlog0 < < " Initializing game graphics: " < < tmh . getDif ( ) < < std : : endl ;
2007-10-13 23:31:50 +03:00
CMessage : : init ( ) ;
2007-08-24 11:27:32 +03:00
cgi - > generaltexth = new CGeneralTextHandler ;
cgi - > generaltexth - > load ( ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " Preparing more handlers: " < < tmh . getDif ( ) < < std : : endl ;
2007-07-09 14:40:39 +03:00
CPreGame * cpg = new CPreGame ( ) ; //main menu and submenus
2008-09-19 11:16:19 +03:00
tlog0 < < " Initialization CPreGame (together): " < < tmh . getDif ( ) < < std : : endl ;
tlog0 < < " Initialization of VCMI (togeter): " < < total . getDif ( ) < < std : : endl ;
2007-06-20 15:00:18 +03:00
cpg - > mush = mush ;
2008-09-12 11:51:46 +03:00
2008-06-30 03:06:41 +03:00
StartInfo * options = new StartInfo ( cpg - > runLoop ( ) ) ;
2008-09-12 11:51:46 +03:00
tmh . getDif ( ) ;
////////////////////////SERVER STARTING/////////////////////////////////////////////////
2008-11-09 00:29:19 +02:00
char portc [ 10 ] ; SDL_itoa ( conf . cc . port , portc , 10 ) ;
2008-09-12 11:51:46 +03:00
intpr : : shared_memory_object smo ( intpr : : open_or_create , " vcmi_memory " , intpr : : read_write ) ;
smo . truncate ( sizeof ( ServerReady ) ) ;
intpr : : mapped_region mr ( smo , intpr : : read_write ) ;
ServerReady * sr = new ( mr . get_address ( ) ) ServerReady ( ) ;
2008-09-09 04:40:43 +03:00
std : : string comm = std : : string ( SERVER_NAME ) + " " + portc + " > server_log.txt " ;
2008-09-12 11:51:46 +03:00
boost : : thread servthr ( boost : : bind ( system , comm . c_str ( ) ) ) ; //runs server executable; //TODO: will it work on non-windows platforms?
2008-09-19 11:16:19 +03:00
tlog0 < < " Preparing shared memory and starting server: " < < tmh . getDif ( ) < < std : : endl ;
2008-09-12 11:51:46 +03:00
///////////////////////////////////////////////////////////////////////////////////////
2008-09-17 13:18:22 +03:00
tmh . getDif ( ) ; pomtime . getDif ( ) ; //reset timers
2007-08-17 20:42:21 +03:00
cgi - > pathf = new CPathfinder ( ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \t Pathfinder: " < < pomtime . getDif ( ) < < std : : endl ;
tlog0 < < " Handlers initialization (together): " < < tmh . getDif ( ) < < std : : endl ;
2008-10-18 14:41:24 +03:00
std : : ofstream logs ( " client_log.txt " ) ;
2008-08-09 02:02:32 +03:00
CConnection * c = NULL ;
2008-09-12 11:51:46 +03:00
//wait until server is ready
2008-09-19 11:16:19 +03:00
tlog0 < < " Waiting for server... " ;
2008-09-12 11:51:46 +03:00
{
intpr : : scoped_lock < intpr : : interprocess_mutex > slock ( sr - > mutex ) ;
while ( ! sr - > ready )
{
sr - > cond . wait ( slock ) ;
}
}
intpr : : shared_memory_object : : remove ( " vcmi_memory " ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < tmh . getDif ( ) < < std : : endl ;
2008-08-09 02:02:32 +03:00
while ( ! c )
{
try
{
2008-09-19 11:16:19 +03:00
tlog0 < < " Establishing connection... \n " ;
2008-11-09 00:29:19 +02:00
c = new CConnection ( conf . cc . server , portc , NAME , logs ) ;
2008-08-09 02:02:32 +03:00
}
catch ( . . . )
{
2008-09-19 11:16:19 +03:00
tlog1 < < " \n Cannot establish connection! Retrying within 2 seconds " < < std : : endl ;
2008-09-17 13:18:22 +03:00
SDL_Delay ( 2000 ) ;
2008-08-09 02:02:32 +03:00
}
}
2008-09-19 11:16:19 +03:00
THC tlog0 < < " \t Connecting to the server: " < < tmh . getDif ( ) < < std : : endl ;
2008-08-04 12:05:52 +03:00
CClient cl ( c , options ) ;
2008-10-19 02:20:48 +03:00
client = & cl ;
2008-08-04 18:56:36 +03:00
boost : : thread t ( boost : : bind ( & CClient : : run , & cl ) ) ;
2008-07-27 20:07:37 +03:00
SDL_Event ev ;
while ( 1 ) //main SDL events loop
{
SDL_WaitEvent ( & ev ) ;
2008-09-20 21:30:37 +03:00
if ( ( ev . type = = SDL_QUIT ) | | ( ev . type = = SDL_KEYDOWN & & ev . key . keysym . sym = = SDLK_F4 & & ( ev . key . keysym . mod & KMOD_ALT ) ) )
2008-07-27 20:07:37 +03:00
{
2008-08-25 13:25:16 +03:00
cl . close ( ) ;
2008-09-18 23:24:53 +03:00
# ifndef __unix__
2008-09-17 13:18:22 +03:00
: : console - > killConsole ( console - > native_handle ( ) ) ;
2008-09-18 23:24:53 +03:00
# endif
2008-10-26 22:58:34 +02:00
LOCPLINT - > pim - > lock ( ) ;
2008-08-25 13:25:16 +03:00
SDL_Delay ( 750 ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " Ending... \n " ;
2008-07-27 20:07:37 +03:00
exit ( 0 ) ;
}
eventsM . lock ( ) ;
events . push ( ev ) ;
eventsM . unlock ( ) ;
2008-08-04 18:56:36 +03:00
}
2007-06-06 22:29:40 +03:00
}
else
{
2008-09-19 11:16:19 +03:00
tlog1 < < " Something was wrong: " < < SDL_GetError ( ) < < std : : endl ;
2007-06-06 22:29:40 +03:00
return - 1 ;
}
2007-06-07 20:45:56 +03:00
}
2008-09-17 13:18:22 +03:00
2008-10-19 02:20:48 +03:00
void processCommand ( const std : : string & message , CClient * & client )
2008-09-17 13:18:22 +03:00
{
std : : istringstream readed ;
readed . str ( message ) ;
std : : string cn ; //command name
readed > > cn ;
int3 src , dst ;
int heronum ;
int3 dest ;
if ( message = = std : : string ( " die, fool " ) )
exit ( 0 ) ;
else if ( cn = = std : : string ( " activate " ) )
{
int what ;
readed > > what ;
switch ( what )
{
case 0 :
LOCPLINT - > curint - > activate ( ) ;
break ;
case 1 :
LOCPLINT - > adventureInt - > activate ( ) ;
break ;
case 2 :
LOCPLINT - > castleInt - > activate ( ) ;
break ;
}
}
else if ( message = = " get txt " )
{
boost : : filesystem : : create_directory ( " Extracted_txts " ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " Command accepted. Opening .lod file... \t " ;
2008-09-17 13:18:22 +03:00
CLodHandler * txth = new CLodHandler ;
2008-11-01 00:41:22 +02:00
txth - > init ( std : : string ( DATA_DIR " Data " PATHSEPARATOR " H3bitmap.lod " ) , " " ) ;
2008-09-19 11:16:19 +03:00
tlog0 < < " done. \n Scanning .lod file \n " ;
2008-09-17 13:18:22 +03:00
int curp = 0 ;
2008-10-18 14:41:24 +03:00
std : : string pattern = " .TXT " , pom ;
2008-09-17 13:18:22 +03:00
for ( int i = 0 ; i < txth - > entries . size ( ) ; i + + )
{
2008-10-18 14:41:24 +03:00
pom = txth - > entries [ i ] . nameStr ;
2008-09-17 13:18:22 +03:00
if ( boost : : algorithm : : find_last ( pom , pattern ) )
{
txth - > extractFile ( std : : string ( " Extracted_txts \\ " ) + pom , pom ) ;
}
if ( i % 8 ) continue ;
int p2 = ( ( float ) i / ( float ) txth - > entries . size ( ) ) * ( float ) 100 ;
if ( p2 ! = curp )
{
curp = p2 ;
2008-09-19 11:16:19 +03:00
tlog0 < < " \r " < < curp < < " % " ;
2008-09-17 13:18:22 +03:00
}
}
2008-09-19 11:16:19 +03:00
tlog0 < < " \r Extracting done :) \n " ;
2008-09-17 13:18:22 +03:00
}
2008-10-19 02:20:48 +03:00
else if ( client & & client - > serv & & client - > serv - > connected ) //send to server
{
* client - > serv < < ui16 ( 513 ) < < message ;
}
2008-09-18 23:24:53 +03:00
}