2014-03-10 19:33:57 +08:00
/****************************************************************************
Copyright ( c ) 2013 cocos2d - x . org
http : //www.cocos2d-x.org
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-05-30 13:53:49 +08:00
# include "Runtime.h"
2014-03-10 19:33:57 +08:00
# include "lua_debugger.h"
# include "CCLuaEngine.h"
# include "cocos2d.h"
2014-03-26 14:48:04 +08:00
# include "json/document.h"
# include "json/filestream.h"
# include "json/stringbuffer.h"
# include "json/writer.h"
2014-05-05 21:04:04 +08:00
# include "LuaBasicConversions.h"
2014-05-08 13:47:41 +08:00
# include "VisibleRect.h"
2014-05-09 14:06:20 +08:00
# include "ConfigParser.h"
2014-03-10 19:33:57 +08:00
# ifdef _WIN32
# include <direct.h>
# else
# include <sys/stat.h>
# endif
# include <vector>
# include <string>
using namespace std ;
using namespace cocos2d ;
2014-03-18 18:24:58 +08:00
std : : string g_resourcePath ;
2014-04-11 10:41:35 +08:00
static rapidjson : : Document g_filecfgjson ;
2014-05-27 01:21:57 +08:00
static string s_strFile ;
static std : : mutex s_FileNameMutex ;
2014-03-10 19:33:57 +08:00
extern string getIPAddress ( ) ;
2014-03-28 11:37:17 +08:00
const char * getRuntimeVersion ( )
2014-03-11 16:52:06 +08:00
{
2014-05-05 21:04:04 +08:00
return " 1.1 " ;
2014-03-11 16:52:06 +08:00
}
2014-05-08 13:47:41 +08:00
2014-03-10 19:33:57 +08:00
void startScript ( string strDebugArg )
{
// register lua engine
auto engine = LuaEngine : : getInstance ( ) ;
2014-04-10 15:37:59 +08:00
if ( ! strDebugArg . empty ( ) )
{
engine - > executeString ( strDebugArg . c_str ( ) ) ;
}
cocos2d : : log ( " debug args = %s " , strDebugArg . c_str ( ) ) ;
2014-05-09 14:06:20 +08:00
engine - > executeScriptFile ( ConfigParser : : getInstance ( ) - > getEntryFile ( ) . c_str ( ) ) ;
2014-03-10 19:33:57 +08:00
}
2014-03-28 11:37:17 +08:00
bool reloadScript ( const string & modulefile )
2014-03-10 19:33:57 +08:00
{
2014-04-10 15:37:59 +08:00
string strfile = modulefile ;
if ( strfile . empty ( ) )
{
2014-05-09 14:06:20 +08:00
strfile = ConfigParser : : getInstance ( ) - > getEntryFile ( ) . c_str ( ) ;
2014-04-10 15:37:59 +08:00
}
2014-03-31 16:49:12 +08:00
2014-04-10 15:37:59 +08:00
auto director = Director : : getInstance ( ) ;
FontFNT : : purgeCachedData ( ) ;
if ( director - > getOpenGLView ( ) )
{
SpriteFrameCache : : getInstance ( ) - > removeSpriteFrames ( ) ;
director - > getTextureCache ( ) - > removeAllTextures ( ) ;
}
FileUtils : : getInstance ( ) - > purgeCachedEntries ( ) ;
2014-03-31 16:49:12 +08:00
2014-04-10 15:37:59 +08:00
director - > getScheduler ( ) - > unscheduleAll ( ) ;
director - > getScheduler ( ) - > scheduleUpdate ( director - > getActionManager ( ) , Scheduler : : PRIORITY_SYSTEM , false ) ;
2014-03-31 16:49:12 +08:00
2014-03-28 11:37:17 +08:00
return ( LuaEngine : : getInstance ( ) - > reload ( strfile . c_str ( ) ) = = 0 ) ;
2014-03-10 19:33:57 +08:00
}
class ConnectWaitLayer : public Layer
{
2014-05-16 15:59:09 +08:00
private :
2014-05-22 11:51:56 +08:00
Label * _labelUploadFile ;
2014-03-10 19:33:57 +08:00
public :
2014-04-10 15:37:59 +08:00
ConnectWaitLayer ( )
{
2014-05-30 13:53:49 +08:00
# include "ResData.h"
2014-05-22 11:51:56 +08:00
int designWidth = 1280 ;
int designHeight = 800 ;
Director : : getInstance ( ) - > getOpenGLView ( ) - > setDesignResolutionSize ( designWidth , designHeight , ResolutionPolicy : : EXACT_FIT ) ;
2014-05-30 10:50:24 +08:00
Image * imagebg = new Image ( ) ;
imagebg - > initWithImageData ( __landscapePngData , sizeof ( __landscapePngData ) ) ;
2014-05-22 11:51:56 +08:00
if ( ! ConfigParser : : getInstance ( ) - > isLanscape ( ) )
{
2014-05-30 10:50:24 +08:00
imagebg - > initWithImageData ( __portraitPngData , sizeof ( __portraitPngData ) ) ;
2014-05-22 11:51:56 +08:00
Director : : getInstance ( ) - > getOpenGLView ( ) - > setDesignResolutionSize ( designHeight , designWidth , ResolutionPolicy : : EXACT_FIT ) ;
}
2014-05-30 10:50:24 +08:00
Texture2D * texturebg = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imagebg , " play_background " ) ;
auto background = Sprite : : createWithTexture ( texturebg ) ;
2014-05-22 11:51:56 +08:00
if ( background )
{
background - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
addChild ( background , 9999 ) ;
}
2014-05-30 10:50:24 +08:00
Image * imageplay = new Image ( ) ;
imageplay - > initWithImageData ( __playEnablePngData , sizeof ( __playEnablePngData ) ) ;
Texture2D * textureplay = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imageplay , " play_enable " ) ;
auto playSprite = Sprite : : createWithTexture ( textureplay ) ;
2014-05-22 11:51:56 +08:00
if ( playSprite )
{
playSprite - > setPosition ( Vec2 ( 902 , 400 ) ) ;
addChild ( playSprite , 9999 ) ;
} else
{
auto labelPlay = LabelTTF : : create ( " play " , " Arial " , 108 ) ;
auto menuItem = MenuItemLabel : : create ( labelPlay , CC_CALLBACK_1 ( ConnectWaitLayer : : playerCallback , this ) ) ;
auto menu = Menu : : create ( menuItem , NULL ) ;
menu - > setPosition ( Point : : ZERO ) ;
menuItem - > setPosition ( Vec2 ( 902 , 400 ) ) ;
if ( ! ConfigParser : : getInstance ( ) - > isLanscape ( ) ) menuItem - > setPosition ( Vec2 ( 400 , 500 ) ) ;
addChild ( menu , 1 ) ;
}
2014-05-30 10:50:24 +08:00
Image * imageShine = new Image ( ) ;
imageShine - > initWithImageData ( __shinePngData , sizeof ( __shinePngData ) ) ;
Texture2D * textureShine = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imageShine , " play_enable " ) ;
auto shineSprite = Sprite : : createWithTexture ( textureShine ) ;
2014-05-22 11:51:56 +08:00
if ( shineSprite )
{
shineSprite - > setPosition ( Vec2 ( 902 , 400 ) ) ;
2014-05-30 10:50:24 +08:00
shineSprite - > runAction ( RepeatForever : : create ( Sequence : : createWithTwoActions ( FadeIn : : create ( 0.6f ) , FadeOut : : create ( 0.8f ) ) ) ) ;
2014-05-22 11:51:56 +08:00
addChild ( shineSprite , 9999 ) ;
}
2014-03-10 19:33:57 +08:00
string strip = getIPAddress ( ) ;
char szIPAddress [ 512 ] = { 0 } ;
2014-05-23 18:26:36 +08:00
sprintf ( szIPAddress , " IP: %s " , strip . c_str ( ) ) ;
auto IPlabel = Label : : create ( szIPAddress , " Arial " , 72 ) ;
2014-05-22 11:51:56 +08:00
IPlabel - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
2014-05-23 18:26:36 +08:00
int spaceSizex = 72 ;
int spaceSizey = 200 ;
IPlabel - > setPosition ( Point ( VisibleRect : : leftTop ( ) . x + spaceSizex , VisibleRect : : top ( ) . y - spaceSizey ) ) ;
2014-05-22 11:51:56 +08:00
addChild ( IPlabel , 9999 ) ;
2014-05-30 10:50:24 +08:00
s_strFile = " waiting for file transfer ... " ;
2014-04-10 15:37:59 +08:00
if ( CC_PLATFORM_WIN32 = = CC_TARGET_PLATFORM | | CC_PLATFORM_MAC = = CC_TARGET_PLATFORM )
{
2014-05-30 10:50:24 +08:00
s_strFile = " waiting for debugger to connect ... " ;
2014-05-22 11:51:56 +08:00
}
2014-05-30 10:50:24 +08:00
_labelUploadFile = Label : : create ( s_strFile . c_str ( ) , " Arial " , 36 ) ;
2014-05-22 11:51:56 +08:00
_labelUploadFile - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
2014-05-23 18:26:36 +08:00
_labelUploadFile - > setPosition ( Point ( VisibleRect : : leftTop ( ) . x + spaceSizex , IPlabel - > getPositionY ( ) - spaceSizex ) ) ;
2014-05-22 11:51:56 +08:00
_labelUploadFile - > setAlignment ( TextHAlignment : : LEFT ) ;
addChild ( _labelUploadFile , 10000 ) ;
if ( ! ConfigParser : : getInstance ( ) - > isLanscape ( ) )
2014-04-10 15:37:59 +08:00
{
2014-05-22 11:51:56 +08:00
if ( playSprite ) playSprite - > setPosition ( 400 , 500 ) ;
if ( shineSprite ) shineSprite - > setPosition ( 400 , 500 ) ;
_labelUploadFile - > setAlignment ( TextHAlignment : : LEFT ) ;
}
if ( playSprite )
{
auto listener = EventListenerTouchOneByOne : : create ( ) ;
listener - > onTouchBegan = [ ] ( Touch * touch , Event * event ) - > bool {
auto target = static_cast < Sprite * > ( event - > getCurrentTarget ( ) ) ;
Vec2 point = target - > convertToNodeSpace ( Director : : getInstance ( ) - > convertToGL ( touch - > getLocationInView ( ) ) ) ;
auto rect = Rect ( 0 , 0 , target - > getContentSize ( ) . width , target - > getContentSize ( ) . height ) ;
if ( ! rect . containsPoint ( point ) ) return false ;
target - > stopAllActions ( ) ;
target - > runAction ( Sequence : : createWithTwoActions ( ScaleBy : : create ( 0.05f , 0.9f ) , ScaleTo : : create ( 0.125f , 1 ) ) ) ;
return true ;
} ;
listener - > onTouchEnded = [ ] ( Touch * touch , Event * event ) {
auto target = static_cast < Sprite * > ( event - > getCurrentTarget ( ) ) ;
Vec2 point = target - > convertToNodeSpace ( Director : : getInstance ( ) - > convertToGL ( touch - > getLocationInView ( ) ) ) ;
auto rect = Rect ( 0 , 0 , target - > getContentSize ( ) . width , target - > getContentSize ( ) . height ) ;
if ( ! rect . containsPoint ( point ) ) return ;
startScript ( " " ) ;
} ;
_eventDispatcher - > addEventListenerWithSceneGraphPriority ( listener , playSprite ) ;
}
2014-05-27 01:21:57 +08:00
this - > scheduleUpdate ( ) ;
2014-04-10 15:37:59 +08:00
}
2014-05-22 11:51:56 +08:00
2014-03-10 19:33:57 +08:00
void playerCallback ( Object * sender )
{
startScript ( " " ) ;
}
2014-05-27 01:21:57 +08:00
void update ( float fDelta )
{
s_FileNameMutex . lock ( ) ;
2014-05-27 02:26:47 +08:00
if ( s_strFile . length ( ) < 1 )
{
return ;
}
2014-05-27 01:21:57 +08:00
_labelUploadFile - > setString ( s_strFile ) ;
s_FileNameMutex . unlock ( ) ;
}
} ;
2014-03-10 19:33:57 +08:00
# if defined(_MSC_VER) || defined(__MINGW32__)
# include <io.h>
# include <WS2tcpip.h>
# define bzero(a, b) memset(a, 0, b);
# else
# include <netdb.h>
# include <unistd.h>
# include <arpa/inet.h>
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/un.h>
# endif
class FileServer
{
public :
FileServer ( )
{
_listenfd = - 1 ;
_running = false ;
_endThread = false ;
}
2014-04-10 15:37:59 +08:00
bool listenOnTCP ( int port ) ;
2014-03-10 19:33:57 +08:00
void stop ( ) ;
private :
2014-04-10 18:15:07 +08:00
bool receiveFile ( int fd ) ;
2014-03-10 19:33:57 +08:00
void addClient ( ) ;
void loop ( ) ;
// file descriptor: socket, console, etc.
int _listenfd ;
int _maxfd ;
std : : vector < int > _fds ;
std : : thread _thread ;
fd_set _read_set ;
bool _running ;
bool _endThread ;
} ;
bool FileServer : : listenOnTCP ( int port )
{
2014-04-10 15:37:59 +08:00
int listenfd , n ;
const int on = 1 ;
struct addrinfo hints , * res , * ressave ;
char serv [ 30 ] ;
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
snprintf ( serv , sizeof ( serv ) - 1 , " %d " , port ) ;
serv [ sizeof ( serv ) - 1 ] = 0 ;
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
bzero ( & hints , sizeof ( struct addrinfo ) ) ;
hints . ai_flags = AI_PASSIVE ;
hints . ai_family = AF_INET ; // AF_UNSPEC: Do we need IPv6 ?
hints . ai_socktype = SOCK_STREAM ;
2014-03-10 19:33:57 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-04-10 15:37:59 +08:00
WSADATA wsaData ;
n = WSAStartup ( MAKEWORD ( 2 , 2 ) , & wsaData ) ;
2014-03-10 19:33:57 +08:00
# endif
2014-04-10 15:37:59 +08:00
if ( ( n = getaddrinfo ( NULL , serv , & hints , & res ) ) ! = 0 ) {
fprintf ( stderr , " net_listen error for %s: %s " , serv , gai_strerror ( n ) ) ;
return false ;
}
ressave = res ;
do {
listenfd = socket ( res - > ai_family , res - > ai_socktype , res - > ai_protocol ) ;
if ( listenfd < 0 )
continue ; /* error, try next one */
setsockopt ( listenfd , SOL_SOCKET , SO_REUSEADDR , ( const char * ) & on , sizeof ( on ) ) ;
if ( : : bind ( listenfd , res - > ai_addr , res - > ai_addrlen ) = = 0 )
break ; /* success */
close ( listenfd ) ; /* bind error, close and try next one */
} while ( ( res = res - > ai_next ) ! = NULL ) ;
if ( res = = NULL ) {
perror ( " net_listen: " ) ;
freeaddrinfo ( ressave ) ;
return false ;
}
listen ( listenfd , 1 ) ;
if ( res - > ai_family = = AF_INET )
{
char buf [ INET_ADDRSTRLEN ] = " " ;
struct sockaddr_in * sin = ( struct sockaddr_in * ) res - > ai_addr ;
if ( inet_ntop ( res - > ai_family , & sin - > sin_addr , buf , sizeof ( buf ) ) ! = NULL )
cocos2d : : log ( " Console: listening on %s : %d " , buf , ntohs ( sin - > sin_port ) ) ;
else
perror ( " inet_ntop " ) ;
} else if ( res - > ai_family = = AF_INET6 )
{
char buf [ INET6_ADDRSTRLEN ] = " " ;
struct sockaddr_in6 * sin = ( struct sockaddr_in6 * ) res - > ai_addr ;
if ( inet_ntop ( res - > ai_family , & sin - > sin6_addr , buf , sizeof ( buf ) ) ! = NULL )
cocos2d : : log ( " Console: listening on %s : %d " , buf , ntohs ( sin - > sin6_port ) ) ;
else
perror ( " inet_ntop " ) ;
}
freeaddrinfo ( ressave ) ;
_listenfd = listenfd ;
_thread = std : : thread ( std : : bind ( & FileServer : : loop , this ) ) ;
return true ;
2014-03-10 19:33:57 +08:00
}
2014-04-10 15:37:59 +08:00
2014-03-10 19:33:57 +08:00
void FileServer : : stop ( )
{
2014-04-10 15:37:59 +08:00
if ( _running ) {
_endThread = true ;
_thread . join ( ) ;
}
2014-03-10 19:33:57 +08:00
}
2014-03-18 18:24:58 +08:00
string & replaceAll ( string & str , const string & old_value , const string & new_value )
2014-03-10 19:33:57 +08:00
{
2014-04-10 15:37:59 +08:00
while ( true )
{
int pos = 0 ;
if ( ( pos = str . find ( old_value , 0 ) ) ! = string : : npos )
str . replace ( pos , old_value . length ( ) , new_value ) ;
else break ;
}
return str ;
2014-03-10 19:33:57 +08:00
}
bool CreateDir ( const char * sPathName )
{
2014-04-10 15:37:59 +08:00
char DirName [ 256 ] = { 0 } ;
strcpy ( DirName , sPathName ) ;
int i , len = strlen ( DirName ) ;
if ( DirName [ len - 1 ] ! = ' / ' )
strcat ( DirName , " / " ) ;
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
len = strlen ( DirName ) ;
for ( i = 1 ; i < len ; i + + )
{
if ( DirName [ i ] = = ' / ' )
{
DirName [ i ] = 0 ;
if ( access ( DirName , NULL ) ! = 0 )
{
2014-03-10 19:33:57 +08:00
# ifdef _WIN32
2014-04-10 15:37:59 +08:00
if ( mkdir ( DirName /*, 0755*/ ) = = - 1 )
2014-03-10 19:33:57 +08:00
# else
if ( mkdir ( DirName , 0755 ) = = - 1 )
# endif
{
perror ( " mkdir error " ) ;
return false ;
}
2014-04-10 15:37:59 +08:00
}
DirName [ i ] = ' / ' ;
}
}
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
return true ;
2014-03-10 19:33:57 +08:00
}
2014-04-10 15:37:59 +08:00
static bool updateResFileInfo ( )
2014-03-26 14:48:04 +08:00
{
2014-04-10 15:37:59 +08:00
rapidjson : : StringBuffer buffer ;
rapidjson : : Writer < rapidjson : : StringBuffer > writer ( buffer ) ;
g_filecfgjson . Accept ( writer ) ;
const char * str = buffer . GetString ( ) ;
2014-03-26 14:48:04 +08:00
2014-04-10 15:37:59 +08:00
string filecfg = g_resourcePath ;
filecfg . append ( " / " ) ;
filecfg . append ( " fileinfo_debug.json " ) ;
FILE * pFile = fopen ( filecfg . c_str ( ) , " w " ) ;
if ( ! pFile )
return false ;
fwrite ( str , sizeof ( char ) , strlen ( str ) , pFile ) ;
fclose ( pFile ) ;
2014-03-31 11:18:41 +08:00
2014-04-10 15:37:59 +08:00
return true ;
2014-03-26 14:48:04 +08:00
}
2014-04-10 15:37:59 +08:00
static void readResFileFinfo ( )
{
string filecfg = g_resourcePath ;
filecfg . append ( " / " ) ;
filecfg . append ( " fileinfo_debug.json " ) ;
FILE * pFile = fopen ( filecfg . c_str ( ) , " r " ) ;
if ( pFile )
{
rapidjson : : FileStream inputStream ( pFile ) ;
g_filecfgjson . ParseStream < 0 > ( inputStream ) ;
fclose ( pFile ) ;
}
if ( ! g_filecfgjson . IsObject ( ) )
{
g_filecfgjson . SetObject ( ) ;
}
2014-03-26 14:48:04 +08:00
}
2014-04-10 18:15:07 +08:00
bool FileServer : : receiveFile ( int fd )
2014-03-10 19:33:57 +08:00
{
2014-03-26 14:48:04 +08:00
char headlen [ 5 ] = { 0 } ;
2014-04-10 15:37:59 +08:00
if ( recv ( fd , headlen , 4 , 0 ) < = 0 ) {
return false ;
}
char * headSeg = new char [ atoi ( headlen ) + 1 ] ;
if ( ! headSeg )
{
return false ;
}
memset ( headSeg , 0 , atoi ( headlen ) + 1 ) ;
if ( recv ( fd , headSeg , atoi ( headlen ) , 0 ) < = 0 ) {
return false ;
}
2014-03-31 11:18:41 +08:00
rapidjson : : Document headjson ;
2014-04-10 15:37:59 +08:00
headjson . Parse < 0 > ( headSeg ) ;
if ( headjson . HasMember ( " filename " ) )
{
string filename = headjson [ " filename " ] . GetString ( ) ;
char fullfilename [ 1024 ] = { 0 } ;
sprintf ( fullfilename , " %s%s " , g_resourcePath . c_str ( ) , filename . c_str ( ) ) ;
string file ( fullfilename ) ;
file = replaceAll ( file , " \\ " , " / " ) ;
sprintf ( fullfilename , " %s " , file . c_str ( ) ) ;
2014-05-27 01:21:57 +08:00
s_FileNameMutex . lock ( ) ;
s_strFile = filename ;
s_FileNameMutex . unlock ( ) ;
2014-04-10 15:37:59 +08:00
cocos2d : : log ( " recv fullfilename = %s " , fullfilename ) ;
CreateDir ( file . substr ( 0 , file . find_last_of ( " / " ) ) . c_str ( ) ) ;
FILE * fp = fopen ( fullfilename , " wb " ) ;
int length = 0 ;
while ( ( length = recv ( fd , fullfilename , sizeof ( fullfilename ) , 0 ) ) > 0 ) {
fwrite ( fullfilename , sizeof ( char ) , length , fp ) ;
}
fclose ( fp ) ;
if ( headjson . HasMember ( " lastmodifytime " ) )
{
string filemodifytime = headjson [ " lastmodifytime " ] . GetString ( ) ;
if ( g_filecfgjson . HasMember ( filename . c_str ( ) ) )
{
g_filecfgjson . RemoveMember ( filename . c_str ( ) ) ;
}
rapidjson : : Value filetimeValue ( rapidjson : : kStringType ) ;
filetimeValue . SetString ( filemodifytime . c_str ( ) , g_filecfgjson . GetAllocator ( ) ) ;
rapidjson : : Value filenameValue ( rapidjson : : kStringType ) ;
filenameValue . SetString ( filename . c_str ( ) , g_filecfgjson . GetAllocator ( ) ) ;
g_filecfgjson . AddMember ( filenameValue . GetString ( ) , filetimeValue , g_filecfgjson . GetAllocator ( ) ) ;
updateResFileInfo ( ) ;
}
}
if ( headSeg )
{
delete [ ] headSeg ;
headSeg = nullptr ;
}
2014-03-16 17:32:08 +08:00
string finish ( " finish \n " ) ;
send ( fd , finish . c_str ( ) , finish . size ( ) , 0 ) ;
2014-04-10 15:37:59 +08:00
return true ;
2014-03-10 19:33:57 +08:00
}
void FileServer : : addClient ( )
{
2014-04-10 15:37:59 +08:00
struct sockaddr client ;
socklen_t client_len ;
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
/* new client */
client_len = sizeof ( client ) ;
int fd = accept ( _listenfd , ( struct sockaddr * ) & client , & client_len ) ;
2014-03-10 19:33:57 +08:00
2014-04-10 15:37:59 +08:00
// add fd to list of FD
if ( fd ! = - 1 ) {
FD_SET ( fd , & _read_set ) ;
_fds . push_back ( fd ) ;
_maxfd = std : : max ( _maxfd , fd ) ;
}
2014-03-10 19:33:57 +08:00
}
void FileServer : : loop ( )
{
2014-04-10 15:37:59 +08:00
fd_set copy_set ;
struct timeval timeout , timeout_copy ;
_running = true ;
FD_ZERO ( & _read_set ) ;
FD_SET ( _listenfd , & _read_set ) ;
_maxfd = _listenfd ;
timeout . tv_sec = 0 ;
/* 0.016 seconds. Wake up once per frame at 60PFS */
timeout . tv_usec = 16000 ;
while ( ! _endThread ) {
copy_set = _read_set ;
timeout_copy = timeout ;
int nready = select ( _maxfd + 1 , & copy_set , NULL , NULL , & timeout_copy ) ;
if ( nready = = - 1 )
{
/* error */
if ( errno ! = EINTR )
log ( " Abnormal error in select() \n " ) ;
continue ;
}
else if ( nready = = 0 )
{
/* timeout. do somethig ? */
}
else
{
/* new client */
if ( FD_ISSET ( _listenfd , & copy_set ) ) {
addClient ( ) ;
if ( - - nready < = 0 )
continue ;
}
/* data from client */
std : : vector < int > to_remove ;
for ( const auto & fd : _fds ) {
if ( FD_ISSET ( fd , & copy_set ) ) {
2014-04-10 18:15:07 +08:00
if ( ! receiveFile ( fd ) ) {
2014-04-10 15:37:59 +08:00
to_remove . push_back ( fd ) ;
}
if ( - - nready < = 0 )
break ;
}
}
/* remove closed conections */
for ( int fd : to_remove ) {
FD_CLR ( fd , & _read_set ) ;
_fds . erase ( std : : remove ( _fds . begin ( ) , _fds . end ( ) , fd ) , _fds . end ( ) ) ;
}
}
}
// clean up: ignore stdin, stdout and stderr
for ( const auto & fd : _fds )
{
2014-03-11 16:52:06 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-04-10 15:37:59 +08:00
closesocket ( fd ) ;
2014-03-11 16:52:06 +08:00
# else
2014-04-10 15:37:59 +08:00
close ( fd ) ;
2014-03-11 16:52:06 +08:00
# endif
2014-04-10 15:37:59 +08:00
}
2014-03-10 19:33:57 +08:00
2014-03-11 16:52:06 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-04-10 15:37:59 +08:00
closesocket ( _listenfd ) ;
WSACleanup ( ) ;
2014-03-11 16:52:06 +08:00
# else
2014-04-10 15:37:59 +08:00
close ( _listenfd ) ;
2014-03-11 16:52:06 +08:00
# endif
2014-04-10 15:37:59 +08:00
_running = false ;
2014-03-10 19:33:57 +08:00
}
class ConsoleCustomCommand
{
public :
ConsoleCustomCommand ( ) : _fileserver ( nullptr )
{
cocos2d : : Console * _console = Director : : getInstance ( ) - > getConsole ( ) ;
static struct Console : : Command commands [ ] = {
2014-04-10 15:37:59 +08:00
{ " sendrequest " , " send command to runtime.Args[json format] " , std : : bind ( & ConsoleCustomCommand : : onSendCommand , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) } ,
} ;
2014-03-10 19:33:57 +08:00
for ( int i = 0 ; i < sizeof ( commands ) / sizeof ( Console : : Command ) ; i + + ) {
_console - > addCommand ( commands [ i ] ) ;
}
2014-03-12 11:04:56 +08:00
_console - > listenOnTCP ( 6010 ) ;
2014-03-10 19:33:57 +08:00
_fileserver = new FileServer ( ) ;
2014-03-12 11:04:56 +08:00
_fileserver - > listenOnTCP ( 6020 ) ;
2014-03-10 19:33:57 +08:00
}
~ ConsoleCustomCommand ( )
{
2014-04-10 15:37:59 +08:00
Director : : getInstance ( ) - > getConsole ( ) - > stop ( ) ;
2014-03-10 19:33:57 +08:00
_fileserver - > stop ( ) ;
if ( _fileserver ) {
delete _fileserver ;
_fileserver = nullptr ;
}
}
2014-04-10 15:37:59 +08:00
void onSendCommand ( int fd , const std : : string & args )
{
Director : : getInstance ( ) - > getScheduler ( ) - > performFunctionInCocosThread ( [ = ] ( ) {
rapidjson : : Document dArgParse ;
dArgParse . Parse < 0 > ( args . c_str ( ) ) ;
if ( dArgParse . HasMember ( " cmd " ) )
{
2014-03-28 11:37:17 +08:00
string strcmd = dArgParse [ " cmd " ] . GetString ( ) ;
rapidjson : : Document dReplyParse ;
2014-04-10 15:37:59 +08:00
dReplyParse . SetObject ( ) ;
dReplyParse . AddMember ( " cmd " , strcmd . c_str ( ) , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
if ( dArgParse . HasMember ( " seq " ) ) {
2014-04-10 15:37:59 +08:00
dReplyParse . AddMember ( " seq " , dArgParse [ " seq " ] , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
}
2014-04-10 15:37:59 +08:00
if ( strcmp ( strcmd . c_str ( ) , " start-logic " ) = = 0 )
{
char szDebugArg [ 1024 ] = { 0 } ;
sprintf ( szDebugArg , " require('debugger')(%s,'%s') " , dArgParse [ " debugcfg " ] . GetString ( ) , g_resourcePath . c_str ( ) ) ;
startScript ( szDebugArg ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
} else if ( strcmp ( strcmd . c_str ( ) , " reload " ) = = 0 )
{
if ( dArgParse . HasMember ( " modulefiles " ) )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-04-10 15:37:59 +08:00
const rapidjson : : Value & objectfiles = dArgParse [ " modulefiles " ] ;
for ( rapidjson : : SizeType i = 0 ; i < objectfiles . Size ( ) ; i + + )
{
if ( ! reloadScript ( objectfiles [ i ] . GetString ( ) ) ) {
bodyvalue . AddMember ( objectfiles [ i ] . GetString ( ) , 1 , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
}
2014-04-10 15:37:59 +08:00
}
if ( 0 = = objectfiles . Size ( ) )
{
reloadScript ( " " ) ;
}
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
}
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
} else if ( strcmp ( strcmd . c_str ( ) , " getversion " ) = = 0 )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-04-10 15:37:59 +08:00
bodyvalue . AddMember ( " version " , getRuntimeVersion ( ) , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " getfileinfo " ) = = 0 )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-04-10 15:37:59 +08:00
for ( auto it = g_filecfgjson . MemberonBegin ( ) ; it ! = g_filecfgjson . MemberonEnd ( ) ; + + it )
{
bodyvalue . AddMember ( it - > name . GetString ( ) , it - > value . GetString ( ) , dReplyParse . GetAllocator ( ) ) ;
}
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-05-09 14:06:20 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " getEntryfile " ) = = 0 )
{
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
rapidjson : : Value entryFileValue ( rapidjson : : kStringType ) ;
entryFileValue . SetString ( ConfigParser : : getInstance ( ) - > getEntryFile ( ) . c_str ( ) , dReplyParse . GetAllocator ( ) ) ;
bodyvalue . AddMember ( " entryfile " , entryFileValue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " getIP " ) = = 0 )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-04-10 15:37:59 +08:00
rapidjson : : Value IPValue ( rapidjson : : kStringType ) ;
IPValue . SetString ( getIPAddress ( ) . c_str ( ) , dReplyParse . GetAllocator ( ) ) ;
bodyvalue . AddMember ( " IP " , IPValue , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " updatefileinfo " ) = = 0 )
{
if ( updateResFileInfo ( ) )
{
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
} else
{
dReplyParse . AddMember ( " code " , 1 , dReplyParse . GetAllocator ( ) ) ;
}
} else if ( strcmp ( strcmd . c_str ( ) , " remove " ) = = 0 )
{
if ( dArgParse . HasMember ( " files " ) )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-04-10 15:37:59 +08:00
const rapidjson : : Value & objectfiles = dArgParse [ " files " ] ;
for ( rapidjson : : SizeType i = 0 ; i < objectfiles . Size ( ) ; i + + )
{
string filename ( g_resourcePath ) ;
filename . append ( " / " ) ;
filename . append ( objectfiles [ i ] . GetString ( ) ) ;
if ( FileUtils : : getInstance ( ) - > isFileExist ( filename ) )
{
2014-03-31 11:18:41 +08:00
if ( remove ( filename . c_str ( ) ) = = 0 )
2014-04-10 15:37:59 +08:00
{
if ( g_filecfgjson . HasMember ( objectfiles [ i ] . GetString ( ) ) ) {
g_filecfgjson . RemoveMember ( objectfiles [ i ] . GetString ( ) ) ;
}
}
else
{
bodyvalue . AddMember ( objectfiles [ i ] . GetString ( ) , 2 , dReplyParse . GetAllocator ( ) ) ;
}
2014-03-28 11:37:17 +08:00
} else
{
2014-04-10 15:37:59 +08:00
bodyvalue . AddMember ( objectfiles [ i ] . GetString ( ) , 1 , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
}
2014-04-10 15:37:59 +08:00
}
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
updateResFileInfo ( ) ;
}
2014-03-28 11:37:17 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-03-26 14:48:04 +08:00
2014-04-10 15:37:59 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " shutdownapp " ) = = 0 )
{
2014-03-17 20:46:49 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-04-10 15:37:59 +08:00
extern void shutDownApp ( ) ;
shutDownApp ( ) ;
2014-03-17 20:46:49 +08:00
# else
2014-04-10 15:37:59 +08:00
exit ( 0 ) ;
2014-03-17 20:46:49 +08:00
# endif
2014-04-10 15:37:59 +08:00
}
2014-03-28 11:37:17 +08:00
rapidjson : : StringBuffer buffer ;
rapidjson : : Writer < rapidjson : : StringBuffer > writer ( buffer ) ;
dReplyParse . Accept ( writer ) ;
const char * str = buffer . GetString ( ) ;
char msgSize [ 64 ] = { 0x1 , 0 } ;
2014-04-10 15:37:59 +08:00
sprintf ( msgSize + 1 , " %d: " , strlen ( str ) ) ;
2014-03-28 11:37:17 +08:00
string replymsg ( msgSize ) ;
replymsg . append ( str ) ;
2014-04-10 15:37:59 +08:00
send ( fd , replymsg . c_str ( ) , replymsg . size ( ) , 0 ) ;
}
} ) ;
}
2014-03-10 19:33:57 +08:00
private :
FileServer * _fileserver ;
} ;
2014-05-05 21:04:04 +08:00
int lua_cocos2dx_runtime_addSearchPath ( lua_State * tolua_S )
2014-03-10 19:33:57 +08:00
{
2014-05-05 21:04:04 +08:00
int argc = 0 ;
cocos2d : : FileUtils * cobj = nullptr ;
bool ok = true ;
# if COCOS2D_DEBUG >= 1
tolua_Error tolua_err ;
2014-04-09 19:17:13 +08:00
# endif
2014-05-05 21:04:04 +08:00
# if COCOS2D_DEBUG >= 1
if ( ! tolua_isusertype ( tolua_S , 1 , " cc.FileUtils " , 0 , & tolua_err ) ) goto tolua_lerror ;
2014-04-09 19:17:13 +08:00
# endif
2014-05-05 21:04:04 +08:00
cobj = ( cocos2d : : FileUtils * ) tolua_tousertype ( tolua_S , 1 , 0 ) ;
# if COCOS2D_DEBUG >= 1
if ( ! cobj )
{
tolua_error ( tolua_S , " invalid 'cobj' in function 'lua_cocos2dx_FileUtils_addSearchPath' " , nullptr ) ;
return 0 ;
}
2014-04-09 19:17:13 +08:00
# endif
2014-05-05 21:04:04 +08:00
argc = lua_gettop ( tolua_S ) - 1 ;
if ( argc = = 1 )
{
std : : string arg0 ;
ok & = luaval_to_std_string ( tolua_S , 2 , & arg0 ) ;
if ( ! ok )
return 0 ;
if ( ! FileUtils : : getInstance ( ) - > isAbsolutePath ( arg0 ) )
arg0 = g_resourcePath + arg0 ;
cobj - > addSearchPath ( arg0 ) ;
return 0 ;
}
CCLOG ( " %s has wrong number of arguments: %d, was expecting %d \n " , " addSearchPath " , argc , 1 ) ;
return 0 ;
# if COCOS2D_DEBUG >= 1
tolua_lerror :
tolua_error ( tolua_S , " #ferror in function 'lua_cocos2dx_FileUtils_addSearchPath'. " , & tolua_err ) ;
2014-04-09 19:17:13 +08:00
# endif
2014-05-05 21:04:04 +08:00
return 0 ;
}
static void register_runtime_override_function ( lua_State * tolua_S )
{
lua_pushstring ( tolua_S , " cc.FileUtils " ) ;
lua_rawget ( tolua_S , LUA_REGISTRYINDEX ) ;
if ( lua_istable ( tolua_S , - 1 ) )
{
tolua_function ( tolua_S , " addSearchPath " , lua_cocos2dx_runtime_addSearchPath ) ;
}
lua_pop ( tolua_S , 1 ) ;
}
2014-05-09 14:06:20 +08:00
bool initRuntime ( )
2014-05-05 21:04:04 +08:00
{
2014-05-08 16:02:55 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
# ifndef _DEBUG
return false ;
# endif
# elif(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
# ifdef NDEBUG
return false ;
# endif
# elif(CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
# ifndef COCOS2D_DEBUG
return false ;
# endif
# endif
2014-04-10 15:37:59 +08:00
vector < string > searchPathArray ;
2014-03-19 17:23:06 +08:00
searchPathArray = FileUtils : : getInstance ( ) - > getSearchPaths ( ) ;
2014-03-18 18:24:58 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
2014-04-10 15:37:59 +08:00
if ( g_resourcePath . empty ( ) )
{
extern std : : string getCurAppPath ( ) ;
string resourcePath = getCurAppPath ( ) ;
2014-03-28 11:37:17 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-04-10 15:37:59 +08:00
resourcePath . append ( " /../../ " ) ;
2014-03-28 11:37:17 +08:00
# elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
resourcePath . append ( " /../../../ " ) ;
# endif
2014-04-10 15:37:59 +08:00
resourcePath = replaceAll ( resourcePath , " \\ " , " / " ) ;
g_resourcePath = resourcePath ;
}
2014-05-05 21:04:04 +08:00
2014-03-18 18:24:58 +08:00
# else
2014-04-10 15:37:59 +08:00
g_resourcePath = FileUtils : : getInstance ( ) - > getWritablePath ( ) ;
2014-05-05 21:04:04 +08:00
g_resourcePath + = " debugruntime/ " ;
2014-03-18 18:24:58 +08:00
# endif
2014-05-05 21:04:04 +08:00
2014-03-18 18:24:58 +08:00
g_resourcePath = replaceAll ( g_resourcePath , " \\ " , " / " ) ;
2014-05-08 16:02:55 +08:00
if ( g_resourcePath . at ( g_resourcePath . length ( ) - 1 ) ! = ' / ' )
{
g_resourcePath . append ( " / " ) ;
}
2014-04-10 15:37:59 +08:00
searchPathArray . insert ( searchPathArray . begin ( ) , g_resourcePath ) ;
2014-03-19 17:23:06 +08:00
FileUtils : : getInstance ( ) - > setSearchPaths ( searchPathArray ) ;
2014-05-05 21:04:04 +08:00
return true ;
}
bool startRuntime ( )
{
2014-05-08 16:02:55 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
# ifndef _DEBUG
return false ;
# endif
# elif(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
# ifdef NDEBUG
return false ;
# endif
2014-05-05 21:04:04 +08:00
# elif(CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
2014-05-08 16:02:55 +08:00
# ifndef COCOS2D_DEBUG
return false ;
2014-05-05 21:04:04 +08:00
# endif
# endif
2014-04-10 15:37:59 +08:00
static ConsoleCustomCommand s_customCommand ;
auto engine = LuaEngine : : getInstance ( ) ;
ScriptEngineManager : : getInstance ( ) - > setScriptEngine ( engine ) ;
2014-05-05 21:04:04 +08:00
LuaStack * stack = engine - > getLuaStack ( ) ;
register_runtime_override_function ( stack - > getLuaState ( ) ) ;
2014-04-10 15:37:59 +08:00
luaopen_debugger ( engine - > getLuaStack ( ) - > getLuaState ( ) ) ;
2014-03-31 11:18:41 +08:00
readResFileFinfo ( ) ;
2014-03-10 19:33:57 +08:00
auto scene = Scene : : create ( ) ;
2014-05-27 01:21:57 +08:00
auto connectLayer = new ConnectWaitLayer ( ) ;
connectLayer - > autorelease ( ) ;
2014-03-10 19:33:57 +08:00
auto director = Director : : getInstance ( ) ;
2014-05-27 01:21:57 +08:00
scene - > addChild ( connectLayer ) ;
2014-03-10 19:33:57 +08:00
director - > runWithScene ( scene ) ;
2014-05-27 01:21:57 +08:00
2014-04-10 15:37:59 +08:00
return true ;
2014-03-10 19:33:57 +08:00
}