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-06-13 11:17:44 +08:00
# include "Protos.pb.h"
2014-06-18 15:43:38 +08:00
# include "zlib.h"
2014-07-16 18:19:33 +08:00
# include "lua.h"
2014-03-10 19:33:57 +08:00
2014-09-17 18:01:25 +08:00
// header files for directory operation
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-08-29 15:05:55 +08:00
static std : : string g_projectPath ;
2014-06-13 11:17:44 +08:00
//1M size
# define MAXPROTOLENGTH 1048576
2014-09-17 18:01:25 +08:00
# define PROTO_START "RuntimeSend:"
2014-06-13 11:17:44 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-06-20 13:43:09 +08:00
# define usleep(t) Sleep(t)
# else
2014-09-24 11:43:21 +08:00
# include <unistd.h>
2014-06-13 11:17:44 +08:00
# endif
2014-07-11 11:34:15 +08:00
extern string getIPAddress ( ) ;
2014-09-17 18:01:25 +08:00
2014-03-28 11:37:17 +08:00
const char * getRuntimeVersion ( )
2014-03-11 16:52:06 +08:00
{
2014-08-29 15:05:55 +08:00
return " 1.4 " ;
2014-03-11 16:52:06 +08:00
}
2014-05-08 13:47:41 +08:00
2014-09-17 18:01:25 +08:00
static string & replaceAll ( string & str , const string & old_value , const string & new_value )
2014-03-10 19:33:57 +08:00
{
2014-09-17 18:01:25 +08:00
size_t start = 0 ;
2014-07-16 18:19:33 +08:00
while ( true )
2014-04-10 15:37:59 +08:00
{
2014-09-17 18:01:25 +08:00
size_t pos = 0 ;
if ( ( pos = str . find ( old_value , start ) ) ! = string : : npos ) {
str . replace ( pos , old_value . length ( ) , new_value ) ;
2014-09-11 17:50:46 +08:00
start = pos + new_value . length ( ) ;
}
2014-07-16 18:19:33 +08:00
else break ;
2014-04-10 15:37:59 +08:00
}
2014-07-16 18:19:33 +08:00
return str ;
2014-03-10 19:33:57 +08:00
}
2014-09-11 17:50:46 +08:00
2014-09-17 18:01:25 +08:00
void startScript ( string strDebugArg )
{
// register lua engine
auto engine = LuaEngine : : getInstance ( ) ;
if ( ! strDebugArg . empty ( ) )
{
engine - > executeString ( strDebugArg . c_str ( ) ) ;
}
cocos2d : : log ( " debug args = %s " , strDebugArg . c_str ( ) ) ;
engine - > executeScriptFile ( ConfigParser : : getInstance ( ) - > getEntryFile ( ) . c_str ( ) ) ;
}
2014-07-16 18:19:33 +08:00
static bool resetLuaModule ( string fileName )
2014-03-10 19:33:57 +08:00
{
2014-07-16 18:19:33 +08:00
if ( fileName . empty ( ) )
2014-04-10 15:37:59 +08:00
{
2014-07-16 18:19:33 +08:00
CCLOG ( " fileName is null " ) ;
return false ;
2014-04-10 15:37:59 +08:00
}
2014-07-16 18:19:33 +08:00
auto engine = LuaEngine : : getInstance ( ) ;
LuaStack * luaStack = engine - > getLuaStack ( ) ;
2014-09-17 18:01:25 +08:00
lua_State * stack = luaStack - > getLuaState ( ) ;
2014-07-16 18:19:33 +08:00
lua_getglobal ( stack , " package " ) ; /* L: package */
lua_getfield ( stack , - 1 , " loaded " ) ; /* L: package loaded */
lua_pushnil ( stack ) ; /* L: lotable ?-.. nil */
2014-09-17 18:01:25 +08:00
while ( 0 ! = lua_next ( stack , - 2 ) ) /* L: lotable ?-.. key value */
2014-07-16 18:19:33 +08:00
{
//CCLOG("%s - %s \n", tolua_tostring(stack, -2, ""), lua_typename(stack, lua_type(stack, -1)));
2014-09-17 18:01:25 +08:00
std : : string key = tolua_tostring ( stack , - 2 , " " ) ;
std : : string tableKey = key ;
size_t found = tableKey . rfind ( " .lua " ) ;
if ( found ! = std : : string : : npos )
tableKey = tableKey . substr ( 0 , found ) ;
tableKey = replaceAll ( tableKey , " . " , " / " ) ;
tableKey = replaceAll ( tableKey , " \\ " , " / " ) ;
2014-07-16 18:19:33 +08:00
tableKey . append ( " .lua " ) ;
found = fileName . rfind ( tableKey ) ;
2014-09-17 18:01:25 +08:00
if ( 0 = = found | | ( found ! = std : : string : : npos & & fileName . at ( found - 1 ) = = ' / ' ) )
2014-07-16 18:19:33 +08:00
{
lua_pushstring ( stack , key . c_str ( ) ) ;
lua_pushnil ( stack ) ;
if ( lua_istable ( stack , - 5 ) )
{
lua_settable ( stack , - 5 ) ;
}
}
lua_pop ( stack , 1 ) ;
}
lua_pop ( stack , 2 ) ;
return true ;
}
2014-09-17 18:01:25 +08:00
bool reloadScript ( const string & file )
2014-07-16 18:19:33 +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-09-17 18:01:25 +08:00
string modulefile = file ;
2014-07-16 18:19:33 +08:00
if ( ! resetLuaModule ( modulefile ) )
{
modulefile = ConfigParser : : getInstance ( ) - > getEntryFile ( ) . c_str ( ) ;
}
auto engine = LuaEngine : : getInstance ( ) ;
LuaStack * luaStack = engine - > getLuaStack ( ) ;
std : : string require = " require \' " + modulefile + " \' " ;
return luaStack - > executeString ( require . c_str ( ) ) ;
}
2014-03-10 19:33:57 +08:00
2014-09-17 18:01:25 +08:00
// header files for socket
# ifdef _WIN32
2014-03-10 19:33:57 +08:00
# include <io.h>
# include <WS2tcpip.h>
# define bzero(a, b) memset(a, 0, b);
# else
# include <netdb.h>
# include <arpa/inet.h>
# include <netinet/in.h>
# include <sys/socket.h>
# endif
class FileServer
{
2014-06-13 11:17:44 +08:00
static FileServer * s_sharedFileServer ;
2014-03-10 19:33:57 +08:00
public :
2014-09-17 18:01:25 +08:00
static FileServer * getShareInstance ( )
{
if ( s_sharedFileServer = = nullptr )
{
s_sharedFileServer = new FileServer ( ) ;
2014-06-13 11:17:44 +08:00
}
return s_sharedFileServer ;
}
bool listenOnTCP ( int port ) ;
void stop ( ) ;
2014-03-10 19:33:57 +08:00
2014-06-13 11:17:44 +08:00
void readResFileFinfo ( ) ;
void addResFileInfo ( const char * filename , uint64_t u64 ) ;
void removeResFileInfo ( const char * filename ) ;
2014-09-17 18:01:25 +08:00
rapidjson : : Document * getFileCfgJson ( )
{
2014-06-13 11:17:44 +08:00
return & _filecfgjson ;
} ;
2014-09-17 18:01:25 +08:00
string getTransingFileName ( )
{
2014-06-13 11:17:44 +08:00
_fileNameMutex . lock ( ) ;
string filename = _strFileName ;
_fileNameMutex . unlock ( ) ;
return filename ;
}
protected :
2014-09-17 18:01:25 +08:00
FileServer ( )
{
2014-03-10 19:33:57 +08:00
_listenfd = - 1 ;
_running = false ;
_endThread = false ;
2014-06-13 11:17:44 +08:00
_protoBuf = nullptr ;
}
2014-09-17 18:01:25 +08:00
~ FileServer ( )
{
2014-06-13 11:17:44 +08:00
CC_SAFE_DELETE_ARRAY ( _protoBuf ) ;
2014-03-10 19:33:57 +08:00
}
private :
2014-06-18 15:43:38 +08:00
void loopReceiveFile ( ) ;
2014-06-13 11:17:44 +08:00
void loopWriteFile ( ) ;
void loopResponse ( ) ;
2014-06-19 17:21:17 +08:00
void addResponse ( int fd , string filename , int errortype , int errornum ) ;
2014-06-13 11:17:44 +08:00
enum PROTONUM
{
2014-09-17 18:01:25 +08:00
FILEPROTO = 1 ,
FILESENDCOMPLETE = 2 ,
DIRPROTO = 3 ,
DIRSENDCOMPLETE = 4
2014-06-13 11:17:44 +08:00
} ;
struct RecvBufStruct
{
runtime : : FileSendProtos fileProto ;
2014-06-18 15:43:38 +08:00
std : : string contentBuf ;
2014-06-13 11:17:44 +08:00
int fd ;
} ;
struct ResponseStruct
{
runtime : : FileSendComplete fileResponseProto ;
int fd ;
} ;
2014-03-10 19:33:57 +08:00
// file descriptor: socket, console, etc.
int _listenfd ;
int _maxfd ;
std : : vector < int > _fds ;
2014-06-13 11:17:44 +08:00
std : : thread _responseThread ;
std : : thread _receiveThread ;
std : : thread _writeThread ;
2014-03-10 19:33:57 +08:00
fd_set _read_set ;
bool _running ;
bool _endThread ;
2014-06-13 11:17:44 +08:00
char * _protoBuf ;
std : : list < RecvBufStruct > _recvBufList ;
std : : list < ResponseStruct > _responseBufList ;
std : : mutex _recvBufListMutex ;
std : : mutex _responseBufListMutex ;
rapidjson : : Document _filecfgjson ;
string _strFileName ;
std : : mutex _fileNameMutex ;
2014-06-19 16:50:16 +08:00
string _recvErrorFile ;
string _writeErrorFile ;
2014-03-10 19:33:57 +08:00
} ;
2014-06-13 11:17:44 +08:00
FileServer * FileServer : : s_sharedFileServer = nullptr ;
void FileServer : : readResFileFinfo ( )
{
string filecfg = g_resourcePath ;
filecfg . append ( " / " ) ;
filecfg . append ( " fileinfo_debug.json " ) ;
FILE * pFile = fopen ( filecfg . c_str ( ) , " r " ) ;
2014-09-17 18:01:25 +08:00
if ( pFile )
{
2014-06-13 11:17:44 +08:00
rapidjson : : FileStream inputStream ( pFile ) ;
_filecfgjson . ParseStream < 0 > ( inputStream ) ;
fclose ( pFile ) ;
}
2014-09-17 18:01:25 +08:00
if ( ! _filecfgjson . IsObject ( ) ) {
2014-06-13 11:17:44 +08:00
_filecfgjson . SetObject ( ) ;
}
2014-09-17 18:01:25 +08:00
//save file info to disk every five second
2014-06-13 11:17:44 +08:00
Director : : getInstance ( ) - > getScheduler ( ) - > schedule ( [ & ] ( float ) {
rapidjson : : StringBuffer buffer ;
rapidjson : : Writer < rapidjson : : StringBuffer > writer ( buffer ) ;
_filecfgjson . Accept ( writer ) ;
const char * str = buffer . GetString ( ) ;
string filecfg = g_resourcePath ;
filecfg . append ( " / " ) ;
filecfg . append ( " fileinfo_debug.json " ) ;
2014-09-17 18:01:25 +08:00
FILE * pFile = fopen ( filecfg . c_str ( ) , " w " ) ;
2014-06-13 11:17:44 +08:00
if ( ! pFile ) return ;
2014-09-17 18:01:25 +08:00
fwrite ( str , sizeof ( char ) , strlen ( str ) , pFile ) ;
2014-06-13 11:17:44 +08:00
fclose ( pFile ) ;
2014-07-16 19:35:04 +08:00
} , this , 5.0f , false , " fileinfo " ) ;
2014-06-13 11:17:44 +08:00
}
void FileServer : : addResFileInfo ( const char * filename , uint64_t u64 )
{
2014-09-17 18:01:25 +08:00
if ( _filecfgjson . HasMember ( filename ) ) {
2014-06-13 11:17:44 +08:00
_filecfgjson . RemoveMember ( filename ) ;
}
2014-06-25 11:36:59 +08:00
char filetime [ 512 ] = { 0 } ;
2014-09-17 18:01:25 +08:00
sprintf ( filetime , " %llu " , u64 ) ;
2014-06-25 11:36:59 +08:00
rapidjson : : Value filetimeValue ( rapidjson : : kStringType ) ;
2014-09-17 18:01:25 +08:00
filetimeValue . SetString ( filetime , _filecfgjson . GetAllocator ( ) ) ;
2014-06-13 11:17:44 +08:00
rapidjson : : Value filenameValue ( rapidjson : : kStringType ) ;
filenameValue . SetString ( filename , _filecfgjson . GetAllocator ( ) ) ;
2014-09-17 18:01:25 +08:00
_filecfgjson . AddMember ( filenameValue . GetString ( ) , filetimeValue , _filecfgjson . GetAllocator ( ) ) ;
2014-06-13 11:17:44 +08:00
}
void FileServer : : removeResFileInfo ( const char * filename )
{
if ( _filecfgjson . HasMember ( filename ) ) {
_filecfgjson . RemoveMember ( filename ) ;
}
}
2014-03-10 19:33:57 +08:00
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 ) ) ;
2014-06-13 11:17:44 +08:00
//setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on));
2014-04-10 15:37:59 +08:00
if ( : : bind ( listenfd , res - > ai_addr , res - > ai_addrlen ) = = 0 )
break ; /* success */
close ( listenfd ) ; /* bind error, close and try next one */
2014-09-17 18:01:25 +08:00
} while ( ( res = res - > ai_next ) ! = NULL ) ;
2014-04-10 15:37:59 +08:00
2014-09-17 18:01:25 +08:00
if ( res = = NULL )
{
2014-04-10 15:37:59 +08:00
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 ;
2014-06-18 15:43:38 +08:00
_receiveThread = std : : thread ( std : : bind ( & FileServer : : loopReceiveFile , this ) ) ;
2014-06-13 11:17:44 +08:00
_writeThread = std : : thread ( std : : bind ( & FileServer : : loopWriteFile , this ) ) ;
_responseThread = std : : thread ( std : : bind ( & FileServer : : loopResponse , this ) ) ;
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
2014-03-10 19:33:57 +08:00
void FileServer : : stop ( )
{
2014-09-17 18:01:25 +08:00
if ( _running )
{
2014-04-10 15:37:59 +08:00
_endThread = true ;
2014-06-13 11:17:44 +08:00
_receiveThread . join ( ) ;
_writeThread . join ( ) ;
_responseThread . join ( ) ;
2014-04-10 15:37:59 +08:00
}
2014-03-10 19:33:57 +08:00
}
2014-07-16 18:19:33 +08:00
static bool CreateDir ( const char * sPathName )
2014-03-10 19:33:57 +08:00
{
2014-04-10 15:37:59 +08:00
char DirName [ 256 ] = { 0 } ;
2014-09-17 18:01:25 +08:00
strcpy ( DirName , sPathName ) ;
size_t i , len = strlen ( DirName ) ;
if ( DirName [ len - 1 ] ! = ' / ' )
{
strcat ( DirName , " / " ) ;
}
2014-03-10 19:33:57 +08:00
2014-09-17 18:01:25 +08:00
len = strlen ( DirName ) ;
for ( i = 1 ; i < len ; i + + )
2014-04-10 15:37:59 +08:00
{
2014-09-17 18:01:25 +08:00
if ( DirName [ i ] = = ' / ' )
2014-04-10 15:37:59 +08:00
{
2014-09-17 18:01:25 +08:00
DirName [ i ] = 0 ;
if ( access ( DirName , NULL ) ! = 0 )
2014-04-10 15:37:59 +08:00
{
2014-03-10 19:33:57 +08:00
# ifdef _WIN32
2014-09-17 18:01:25 +08:00
if ( _mkdir ( DirName /*, 0755*/ ) = = - 1 )
2014-03-10 19:33:57 +08:00
# else
2014-09-17 18:01:25 +08:00
if ( mkdir ( DirName , 0755 ) = = - 1 )
2014-03-10 19:33:57 +08:00
# endif
{
2014-09-17 18:01:25 +08:00
perror ( " mkdir error " ) ;
return false ;
2014-03-10 19:33:57 +08:00
}
2014-04-10 15:37:59 +08:00
}
2014-09-17 18:01:25 +08:00
DirName [ i ] = ' / ' ;
2014-04-10 15:37:59 +08:00
}
}
2014-03-10 19:33:57 +08:00
2014-09-17 18:01:25 +08:00
return true ;
}
static void recvBuf ( int fd , char * pbuf , unsigned long bufsize )
{
unsigned long leftLength = bufsize ;
while ( leftLength ! = 0 )
{
size_t recvlen = recv ( fd , pbuf + bufsize - leftLength , leftLength , 0 ) ;
if ( recvlen < = 0 )
{
usleep ( 1 ) ;
continue ;
}
leftLength - = recvlen ;
}
2014-03-10 19:33:57 +08:00
}
2014-09-18 12:40:26 +08:00
static void sendBuf ( int fd , const char * pbuf , unsigned long bufsize )
2014-06-19 11:27:31 +08:00
{
2014-09-17 18:01:25 +08:00
unsigned long leftLength = bufsize ;
while ( leftLength ! = 0 )
{
size_t sendlen = send ( fd , pbuf + bufsize - leftLength , leftLength , 0 ) ;
if ( sendlen < = 0 )
{
2014-06-20 13:43:09 +08:00
usleep ( 1 ) ;
2014-06-19 11:27:31 +08:00
continue ;
}
2014-09-17 18:01:25 +08:00
leftLength - = sendlen ;
2014-06-19 11:27:31 +08:00
}
}
2014-06-18 15:43:38 +08:00
void FileServer : : loopReceiveFile ( )
2014-03-26 14:48:04 +08:00
{
2014-06-18 15:43:38 +08:00
struct sockaddr client ;
socklen_t client_len ;
/* new client */
2014-09-17 18:01:25 +08:00
client_len = sizeof ( client ) ;
2014-06-18 15:43:38 +08:00
int fd = accept ( _listenfd , ( struct sockaddr * ) & client , & client_len ) ;
2014-09-17 18:01:25 +08:00
if ( _protoBuf = = nullptr )
{
2014-06-13 11:17:44 +08:00
_protoBuf = new char [ MAXPROTOLENGTH ] ;
}
2014-03-26 14:48:04 +08:00
2014-06-18 15:43:38 +08:00
while ( ! _endThread ) {
// recv start flag
2014-09-17 18:01:25 +08:00
char startflag [ 13 ] = { 0 } ;
recvBuf ( fd , startflag , sizeof ( startflag ) - 1 ) ;
if ( strcmp ( startflag , PROTO_START ) ! = 0 )
{
2014-06-18 15:43:38 +08:00
continue ;
}
2014-06-13 11:17:44 +08:00
2014-06-18 15:43:38 +08:00
// recv proto num
union
{
char char_type [ 3 ] ;
unsigned short uint16_type ;
} protonum ;
2014-09-17 18:01:25 +08:00
recvBuf ( fd , protonum . char_type , sizeof ( protonum . char_type ) - 1 ) ;
2014-06-18 15:43:38 +08:00
//recv protobuf length
union
{
char char_type [ 3 ] ;
unsigned short uint16_type ;
} protolength ;
2014-09-17 18:01:25 +08:00
recvBuf ( fd , protolength . char_type , sizeof ( protolength . char_type ) - 1 ) ;
2014-04-10 15:37:59 +08:00
2014-06-18 15:43:38 +08:00
//recv variable length
2014-09-17 18:01:25 +08:00
memset ( _protoBuf , 0 , MAXPROTOLENGTH ) ;
recvBuf ( fd , _protoBuf , protolength . uint16_type ) ;
2014-04-10 15:37:59 +08:00
2014-06-18 15:43:38 +08:00
RecvBufStruct recvDataBuf ;
recvDataBuf . fd = fd ;
recvDataBuf . fileProto . ParseFromString ( _protoBuf ) ;
2014-09-17 18:01:25 +08:00
if ( 1 = = recvDataBuf . fileProto . package_seq ( ) )
{
2014-06-19 16:50:16 +08:00
_recvErrorFile = " " ;
2014-09-17 18:01:25 +08:00
} else
{
2014-06-19 16:50:16 +08:00
// recv error
2014-09-17 18:01:25 +08:00
if ( _recvErrorFile = = recvDataBuf . fileProto . file_name ( ) )
{
2014-06-19 16:50:16 +08:00
continue ;
}
}
2014-09-17 18:01:25 +08:00
unsigned long contentSize = recvDataBuf . fileProto . content_size ( ) ;
2014-07-11 10:38:55 +08:00
if ( contentSize = = 0 )
{
recvDataBuf . contentBuf = " " ;
_recvBufListMutex . lock ( ) ;
_recvBufList . push_back ( recvDataBuf ) ;
_recvBufListMutex . unlock ( ) ;
2014-09-17 18:01:25 +08:00
} else if ( contentSize > 0 )
2014-07-11 10:38:55 +08:00
{
2014-06-18 15:43:38 +08:00
//recv body data
2014-09-17 18:01:25 +08:00
Bytef * contentbuf = new Bytef [ contentSize + 1 ] ;
memset ( contentbuf , 0 , contentSize + 1 ) ;
unsigned long recvTotalLen = contentSize ;
2014-06-18 15:43:38 +08:00
while ( recvTotalLen ! = 0 ) {
2014-09-17 18:01:25 +08:00
unsigned long recvLen = MAXPROTOLENGTH ;
2014-06-18 15:43:38 +08:00
if ( recvTotalLen < MAXPROTOLENGTH )
recvLen = recvTotalLen ;
2014-09-17 18:01:25 +08:00
memset ( _protoBuf , 0 , MAXPROTOLENGTH ) ;
unsigned long result = recv ( fd , _protoBuf , recvLen , 0 ) ;
if ( result < = 0 )
{
2014-06-20 13:43:09 +08:00
usleep ( 1 ) ;
2014-06-18 15:43:38 +08:00
continue ;
}
2014-09-17 18:01:25 +08:00
memcpy ( contentbuf + contentSize - recvTotalLen , _protoBuf , result ) ;
2014-06-18 15:43:38 +08:00
recvTotalLen - = result ;
2014-04-10 15:37:59 +08:00
}
2014-06-18 15:43:38 +08:00
if ( recvDataBuf . fileProto . compress_type ( ) = = runtime : : FileSendProtos_CompressType : : FileSendProtos_CompressType_ZIP ) {
2014-06-19 16:50:16 +08:00
unsigned long uncompressSize = recvDataBuf . fileProto . uncompress_size ( ) ;
2014-06-18 15:43:38 +08:00
Bytef * buff = new Bytef [ uncompressSize * sizeof ( Bytef ) ] ;
memset ( buff , 0 , uncompressSize * sizeof ( Bytef ) ) ;
2014-06-19 16:50:16 +08:00
int err = : : uncompress ( buff , & uncompressSize , contentbuf , contentSize * sizeof ( Bytef ) ) ;
2014-06-18 15:43:38 +08:00
if ( err ! = Z_OK ) {
2014-06-19 16:50:16 +08:00
CC_SAFE_DELETE_ARRAY ( buff ) ;
CC_SAFE_DELETE_ARRAY ( contentbuf ) ;
2014-09-17 18:01:25 +08:00
addResponse ( recvDataBuf . fd , recvDataBuf . fileProto . file_name ( ) , runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR , err ) ;
2014-06-19 16:50:16 +08:00
continue ;
2014-06-18 15:43:38 +08:00
}
CC_SAFE_DELETE_ARRAY ( contentbuf ) ;
contentbuf = buff ;
contentSize = uncompressSize ;
}
2014-09-17 18:01:25 +08:00
recvDataBuf . contentBuf . assign ( ( const char * ) contentbuf , contentSize ) ;
2014-06-18 15:43:38 +08:00
CC_SAFE_DELETE_ARRAY ( contentbuf ) ;
_recvBufListMutex . lock ( ) ;
_recvBufList . push_back ( recvDataBuf ) ;
_recvBufListMutex . unlock ( ) ;
2014-04-10 15:37:59 +08:00
}
}
2014-03-10 19:33:57 +08:00
}
2014-06-13 11:17:44 +08:00
void FileServer : : loopWriteFile ( )
{
2014-09-17 18:01:25 +08:00
while ( ! _endThread )
{
2014-06-13 11:17:44 +08:00
_recvBufListMutex . lock ( ) ;
2014-09-17 18:01:25 +08:00
size_t recvSize = _recvBufList . size ( ) ;
2014-06-13 11:17:44 +08:00
_recvBufListMutex . unlock ( ) ;
2014-09-17 18:01:25 +08:00
if ( 0 = = recvSize )
{
2014-06-20 13:43:09 +08:00
usleep ( 500 ) ;
2014-06-13 11:17:44 +08:00
continue ;
}
_recvBufListMutex . lock ( ) ;
RecvBufStruct recvDataBuf = _recvBufList . front ( ) ;
_recvBufList . pop_front ( ) ;
_recvBufListMutex . unlock ( ) ;
2014-06-18 15:43:38 +08:00
string filename = recvDataBuf . fileProto . file_name ( ) ;
2014-06-13 11:17:44 +08:00
string fullfilename = g_resourcePath ;
fullfilename + = filename ;
_fileNameMutex . lock ( ) ;
_strFileName = filename ;
_fileNameMutex . unlock ( ) ;
2014-07-16 18:19:33 +08:00
//cocos2d::log("WriteFile:: fullfilename = %s",filename.c_str());
2014-09-17 18:01:25 +08:00
CreateDir ( fullfilename . substr ( 0 , fullfilename . find_last_of ( " / " ) ) . c_str ( ) ) ;
2014-06-13 11:17:44 +08:00
2014-06-18 15:43:38 +08:00
FILE * fp = nullptr ;
2014-09-17 18:01:25 +08:00
if ( 1 = = recvDataBuf . fileProto . package_seq ( ) )
{
2014-06-19 16:50:16 +08:00
_writeErrorFile = " " ;
2014-09-17 18:01:25 +08:00
fp = fopen ( fullfilename . c_str ( ) , " wb " ) ;
} else
{
if ( _writeErrorFile = = filename )
{
2014-06-19 16:50:16 +08:00
continue ;
}
2014-06-18 15:43:38 +08:00
fp = fopen ( fullfilename . c_str ( ) , " ab " ) ;
}
2014-09-17 18:01:25 +08:00
if ( nullptr = = fp )
{
addResponse ( recvDataBuf . fd , filename , runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_FOPEN_ERROR , errno ) ;
2014-06-20 11:32:22 +08:00
continue ;
2014-06-18 15:43:38 +08:00
}
2014-09-17 18:01:25 +08:00
if ( fp )
{
if ( recvDataBuf . contentBuf . size ( ) > 0 & & 0 = = fwrite ( recvDataBuf . contentBuf . c_str ( ) , sizeof ( char ) , recvDataBuf . contentBuf . size ( ) , fp ) )
{
addResponse ( recvDataBuf . fd , filename , runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_FWRITE_ERROR , errno ) ;
2014-06-20 11:32:22 +08:00
fclose ( fp ) ;
continue ;
2014-06-19 16:50:16 +08:00
}
2014-06-18 15:43:38 +08:00
fclose ( fp ) ;
}
2014-09-17 18:01:25 +08:00
if ( 1 = = recvDataBuf . fileProto . package_seq ( ) )
{
2014-06-18 15:43:38 +08:00
//record new file modify
2014-09-17 18:01:25 +08:00
addResFileInfo ( filename . c_str ( ) , recvDataBuf . fileProto . modified_time ( ) ) ;
addResponse ( recvDataBuf . fd , filename , runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_SUCCESS , 0 ) ;
2014-06-13 11:17:44 +08:00
}
}
}
2014-09-17 18:01:25 +08:00
void FileServer : : addResponse ( int fd , string filename , int errortype , int errornum )
2014-06-19 11:27:31 +08:00
{
2014-06-19 16:50:16 +08:00
switch ( errortype )
{
case runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR :
case runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_RECV_ERROR :
_recvErrorFile = filename ;
break ;
case runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_FOPEN_ERROR :
case runtime : : FileSendComplete : : RESULTTYPE : : FileSendComplete_RESULTTYPE_FWRITE_ERROR :
_writeErrorFile = filename ;
break ;
default :
break ;
}
2014-06-19 11:27:31 +08:00
ResponseStruct responseBuf ;
responseBuf . fd = fd ;
responseBuf . fileResponseProto . set_file_name ( filename . c_str ( ) ) ;
2014-06-19 16:50:16 +08:00
responseBuf . fileResponseProto . set_result ( ( : : runtime : : FileSendComplete_RESULTTYPE ) errortype ) ;
responseBuf . fileResponseProto . set_error_num ( errornum ) ;
2014-06-19 11:27:31 +08:00
// push Response struct
_responseBufListMutex . lock ( ) ;
_responseBufList . push_back ( responseBuf ) ;
_responseBufListMutex . unlock ( ) ;
}
2014-06-18 15:43:38 +08:00
2014-06-13 11:17:44 +08:00
void FileServer : : loopResponse ( )
{
while ( ! _endThread ) {
_responseBufListMutex . lock ( ) ;
2014-09-17 18:01:25 +08:00
size_t responseSize = _responseBufList . size ( ) ;
2014-06-13 11:17:44 +08:00
_responseBufListMutex . unlock ( ) ;
2014-09-17 18:01:25 +08:00
if ( 0 = = responseSize )
{
2014-06-20 13:43:09 +08:00
usleep ( 500 ) ;
2014-09-17 18:01:25 +08:00
/* error */
2014-06-13 11:17:44 +08:00
continue ;
}
_responseBufListMutex . lock ( ) ;
ResponseStruct responseBuf = _responseBufList . front ( ) ;
_responseBufList . pop_front ( ) ;
_responseBufListMutex . unlock ( ) ;
//send response
string responseString ;
runtime : : FileSendComplete fileSendProtoComplete ;
2014-06-18 15:43:38 +08:00
fileSendProtoComplete . set_file_name ( responseBuf . fileResponseProto . file_name ( ) ) ;
2014-06-13 11:17:44 +08:00
fileSendProtoComplete . set_result ( responseBuf . fileResponseProto . result ( ) ) ;
2014-06-20 11:32:22 +08:00
fileSendProtoComplete . set_error_num ( responseBuf . fileResponseProto . error_num ( ) ) ;
2014-06-13 11:17:44 +08:00
fileSendProtoComplete . SerializeToString ( & responseString ) ;
2014-09-17 18:01:25 +08:00
char dataBuf [ 1024 ] = { 0 } ;
struct ResponseHeaderStruct
2014-06-13 11:17:44 +08:00
{
char startFlag [ 12 ] ;
unsigned short protoNum ;
unsigned short protoBufLen ;
} ;
2014-09-17 18:01:25 +08:00
ResponseHeaderStruct responseHeader ;
strcpy ( responseHeader . startFlag , PROTO_START ) ;
responseHeader . protoNum = PROTONUM : : FILESENDCOMPLETE ;
responseHeader . protoBufLen = ( unsigned short ) responseString . size ( ) ;
memcpy ( dataBuf , & responseHeader , sizeof ( responseHeader ) ) ;
memcpy ( dataBuf + sizeof ( responseHeader ) , responseString . c_str ( ) , responseString . size ( ) ) ;
sendBuf ( responseBuf . fd , dataBuf , sizeof ( responseHeader ) + responseString . size ( ) ) ;
cocos2d : : log ( " responseFile:%s,result:%d " , fileSendProtoComplete . file_name ( ) . c_str ( ) , fileSendProtoComplete . result ( ) ) ;
2014-06-13 11:17:44 +08:00
}
}
class ConnectWaitLayer : public Layer
{
private :
Label * _labelUploadFile ;
public :
ConnectWaitLayer ( )
{
# include "ResData.h"
int designWidth = 1280 ;
int designHeight = 800 ;
Image * imagebg = new Image ( ) ;
2014-09-24 11:43:21 +08:00
if ( ConfigParser : : getInstance ( ) - > isLanscape ( ) )
{
imagebg - > initWithImageData ( __landscapePngData , sizeof ( __landscapePngData ) ) ;
Director : : getInstance ( ) - > getOpenGLView ( ) - > setDesignResolutionSize ( designWidth , designHeight , ResolutionPolicy : : EXACT_FIT ) ;
} else
2014-09-17 18:01:25 +08:00
{
2014-06-13 11:17:44 +08:00
imagebg - > initWithImageData ( __portraitPngData , sizeof ( __portraitPngData ) ) ;
2014-09-24 11:43:21 +08:00
Director : : getInstance ( ) - > getOpenGLView ( ) - > setDesignResolutionSize ( designHeight , designWidth , ResolutionPolicy : : EXACT_FIT ) ;
2014-06-13 11:17:44 +08:00
}
Texture2D * texturebg = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imagebg , " play_background " ) ;
auto background = Sprite : : createWithTexture ( texturebg ) ;
2014-09-24 11:43:21 +08:00
background - > setAnchorPoint ( Vec2 ( 0.5 , 0.5 ) ) ;
background - > setPosition ( VisibleRect : : center ( ) ) ;
addChild ( background , 9000 ) ;
2014-06-13 11:17:44 +08:00
// variable of below is"play" button position.
int portraitX = 400 ;
int portraitY = 500 ;
int lanscaptX = 902 ;
int lanscaptY = 400 ;
Image * imageplay = new Image ( ) ;
imageplay - > initWithImageData ( __playEnablePngData , sizeof ( __playEnablePngData ) ) ;
Texture2D * textureplay = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imageplay , " play_enable " ) ;
auto playSprite = Sprite : : createWithTexture ( textureplay ) ;
2014-09-24 11:43:21 +08:00
addChild ( playSprite , 9999 ) ;
2014-06-13 11:17:44 +08:00
Image * imageShine = new Image ( ) ;
imageShine - > initWithImageData ( __shinePngData , sizeof ( __shinePngData ) ) ;
2014-09-24 11:43:21 +08:00
Texture2D * textureShine = Director : : getInstance ( ) - > getTextureCache ( ) - > addImage ( imageShine , " shine " ) ;
2014-06-13 11:17:44 +08:00
auto shineSprite = Sprite : : createWithTexture ( textureShine ) ;
shineSprite - > setOpacity ( 0 ) ;
Vector < FiniteTimeAction * > arrayOfActions ;
2014-06-20 13:43:09 +08:00
arrayOfActions . pushBack ( DelayTime : : create ( 0.4f ) ) ;
2014-09-24 11:43:21 +08:00
arrayOfActions . pushBack ( FadeTo : : create ( 0.8f , 200 ) ) ;
arrayOfActions . pushBack ( FadeTo : : create ( 0.8f , 255 ) ) ;
arrayOfActions . pushBack ( FadeTo : : create ( 0.8f , 200 ) ) ;
arrayOfActions . pushBack ( FadeTo : : create ( 0.8f , 0 ) ) ;
2014-06-20 13:43:09 +08:00
arrayOfActions . pushBack ( DelayTime : : create ( 0.4f ) ) ;
2014-06-13 11:17:44 +08:00
shineSprite - > runAction ( RepeatForever : : create ( Sequence : : create ( arrayOfActions ) ) ) ;
2014-09-24 11:43:21 +08:00
addChild ( shineSprite , 9998 ) ;
2014-06-13 11:17:44 +08:00
string strip = getIPAddress ( ) ;
2014-09-24 11:43:21 +08:00
char szIPAddress [ 64 ] = { 0 } ;
2014-09-17 18:01:25 +08:00
sprintf ( szIPAddress , " IP: %s " , strip . c_str ( ) ) ;
auto IPlabel = Label : : createWithSystemFont ( szIPAddress , " " , 72 ) ;
2014-09-24 11:43:21 +08:00
IPlabel - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
2014-06-13 11:17:44 +08:00
int spaceSizex = 72 ;
int spaceSizey = 200 ;
2014-09-17 18:01:25 +08:00
IPlabel - > setPosition ( Point ( VisibleRect : : leftTop ( ) . x + spaceSizex , VisibleRect : : top ( ) . y - spaceSizey ) ) ;
2014-06-13 11:17:44 +08:00
addChild ( IPlabel , 9001 ) ;
2014-09-24 11:43:21 +08:00
string transferTip = " waiting for file transfer ... " ;
2014-09-17 18:01:25 +08:00
if ( CC_PLATFORM_WIN32 = = CC_TARGET_PLATFORM | | CC_PLATFORM_MAC = = CC_TARGET_PLATFORM )
{
2014-09-24 11:43:21 +08:00
transferTip = " waiting for debugger to connect ... " ;
2014-06-13 11:17:44 +08:00
}
2014-09-24 11:43:21 +08:00
char szVersion [ 256 ] = { 0 } ;
sprintf ( szVersion , " runtimeVersion:%s \n engineVersion:%s " , getRuntimeVersion ( ) , cocos2dVersion ( ) ) ;
2014-09-17 18:01:25 +08:00
Label * verLable = Label : : createWithSystemFont ( szVersion , " " , 24 ) ;
verLable - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
2014-06-13 11:17:44 +08:00
int width = verLable - > getBoundingBox ( ) . size . width ;
2014-09-24 11:43:21 +08:00
verLable - > setPosition ( Point ( VisibleRect : : right ( ) . x - width , VisibleRect : : rightBottom ( ) . y ) ) ;
2014-06-13 11:17:44 +08:00
verLable - > setAlignment ( TextHAlignment : : LEFT ) ;
addChild ( verLable , 9002 ) ;
2014-09-24 11:43:21 +08:00
_labelUploadFile = Label : : createWithSystemFont ( transferTip , " " , 36 ) ;
2014-09-17 18:01:25 +08:00
_labelUploadFile - > setAnchorPoint ( Vec2 ( 0 , 0 ) ) ;
_labelUploadFile - > setPosition ( Point ( VisibleRect : : leftTop ( ) . x + spaceSizex , IPlabel - > getPositionY ( ) - spaceSizex ) ) ;
2014-06-13 11:17:44 +08:00
_labelUploadFile - > setAlignment ( TextHAlignment : : LEFT ) ;
addChild ( _labelUploadFile , 9003 ) ;
2014-09-24 11:43:21 +08:00
if ( ConfigParser : : getInstance ( ) - > isLanscape ( ) )
{
playSprite - > setPosition ( lanscaptX , lanscaptY ) ;
shineSprite - > setPosition ( lanscaptX , lanscaptY ) ;
}
else
2014-06-13 11:17:44 +08:00
{
2014-09-24 11:43:21 +08:00
playSprite - > setPosition ( portraitX , portraitY ) ;
shineSprite - > setPosition ( portraitX , portraitY ) ;
2014-06-13 11:17:44 +08:00
}
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 ( ) ;
2014-09-17 18:01:25 +08:00
target - > runAction ( Sequence : : createWithTwoActions ( ScaleBy : : create ( 0.05f , 0.9f ) , ScaleTo : : create ( 0.125f , 1 ) ) ) ;
2014-06-13 11:17:44 +08:00
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 ) ;
this - > scheduleUpdate ( ) ;
}
2014-09-17 18:01:25 +08:00
// clean up: ignore stdin, stdout and stderr
void update ( float fDelta )
2014-06-13 11:17:44 +08:00
{
2014-09-24 11:43:21 +08:00
string transferTip = FileServer : : getShareInstance ( ) - > getTransingFileName ( ) ;
if ( transferTip . empty ( ) ) {
2014-06-13 11:17:44 +08:00
return ;
}
2014-09-24 11:43:21 +08:00
_labelUploadFile - > setString ( transferTip ) ;
2014-06-13 11:17:44 +08:00
}
} ;
2014-03-10 19:33:57 +08:00
class ConsoleCustomCommand
{
public :
2014-06-13 11:17:44 +08:00
void init ( )
2014-03-10 19:33:57 +08:00
{
cocos2d : : Console * _console = Director : : getInstance ( ) - > getConsole ( ) ;
2014-09-17 18:01:25 +08:00
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-09-17 18:01:25 +08:00
for ( int i = 0 ; i < sizeof ( commands ) / sizeof ( Console : : Command ) ; i + + )
{
2014-03-10 19:33:57 +08:00
_console - > addCommand ( commands [ i ] ) ;
}
2014-07-17 15:37:37 +08:00
# if(CC_PLATFORM_MAC == CC_TARGET_PLATFORM || CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM)
2014-07-16 20:19:19 +08:00
_console - > listenOnTCP ( ConfigParser : : getInstance ( ) - > getConsolePort ( ) ) ;
2014-07-17 15:37:37 +08:00
# else
_console - > listenOnTCP ( 6010 ) ;
# endif
2014-07-16 21:20:48 +08:00
_fileserver = nullptr ;
2014-06-13 11:17:44 +08:00
_fileserver = FileServer : : getShareInstance ( ) ;
2014-08-29 15:05:55 +08:00
# if(CC_PLATFORM_MAC == CC_TARGET_PLATFORM || CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM)
_fileserver - > listenOnTCP ( ConfigParser : : getInstance ( ) - > getUploadPort ( ) ) ;
# else
2014-03-12 11:04:56 +08:00
_fileserver - > listenOnTCP ( 6020 ) ;
2014-07-16 20:19:19 +08:00
# endif
2014-08-29 15:05:55 +08:00
_fileserver - > readResFileFinfo ( ) ;
2014-03-10 19:33:57 +08:00
}
2014-06-13 11:17:44 +08:00
2014-03-10 19:33:57 +08:00
~ ConsoleCustomCommand ( )
{
2014-04-10 15:37:59 +08:00
Director : : getInstance ( ) - > getConsole ( ) - > stop ( ) ;
2014-07-16 20:19:19 +08:00
if ( _fileserver )
2014-09-17 18:01:25 +08:00
_fileserver - > stop ( ) ;
2014-03-10 19:33:57 +08:00
}
2014-06-13 11:17:44 +08:00
2014-04-10 15:37:59 +08:00
void onSendCommand ( int fd , const std : : string & args )
{
2014-09-17 18:01:25 +08:00
Director : : getInstance ( ) - > getScheduler ( ) - > performFunctionInCocosThread ( [ = ] ( ) {
2014-04-10 15:37:59 +08:00
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-09-17 18:01:25 +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-09-17 18:01:25 +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 ( ) ) ;
2014-04-10 15:37:59 +08:00
startScript ( szDebugArg ) ;
2014-09-17 18:01:25 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
2014-09-17 18:01:25 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " reload " ) = = 0 )
2014-04-10 15:37:59 +08:00
{
2014-09-17 18:01:25 +08:00
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 " ] ;
2014-09-17 18:01:25 +08:00
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
}
2014-09-17 18:01:25 +08:00
if ( 0 = = objectfiles . Size ( ) )
{
2014-04-10 15:37:59 +08:00
reloadScript ( " " ) ;
}
2014-09-17 18:01:25 +08:00
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
}
2014-09-17 18:01:25 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
} else if ( strcmp ( strcmd . c_str ( ) , " getversion " ) = = 0 )
2014-04-10 15:37:59 +08:00
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-09-17 18:01:25 +08:00
bodyvalue . AddMember ( " version " , getRuntimeVersion ( ) , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
} else if ( strcmp ( strcmd . c_str ( ) , " getfileinfo " ) = = 0 )
{
2014-03-28 11:37:17 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
2014-07-16 21:20:48 +08:00
if ( _fileserver ) {
rapidjson : : Document * filecfgjson = _fileserver - > getFileCfgJson ( ) ;
2014-09-17 18:01:25 +08:00
for ( auto it = filecfgjson - > MemberonBegin ( ) ; it ! = filecfgjson - > MemberonEnd ( ) ; + + it )
{
bodyvalue . AddMember ( it - > name . GetString ( ) , it - > value . GetString ( ) , dReplyParse . GetAllocator ( ) ) ;
2014-07-16 21:20:48 +08:00
}
2014-04-10 15:37:59 +08:00
}
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-09-17 18:01:25 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " getEntryfile " ) = = 0 )
{
2014-05-09 14:06:20 +08:00
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
rapidjson : : Value entryFileValue ( rapidjson : : kStringType ) ;
2014-09-17 18:01:25 +08:00
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 ( ) ) ;
} 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 ) ;
2014-09-17 18:01:25 +08:00
IPValue . SetString ( getIPAddress ( ) . c_str ( ) , dReplyParse . GetAllocator ( ) ) ;
bodyvalue . AddMember ( " IP " , IPValue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
2014-03-28 11:37:17 +08:00
2014-09-17 18:01:25 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " remove " ) = = 0 )
2014-04-10 15:37:59 +08:00
{
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 " ] ;
2014-09-17 18:01:25 +08:00
const char * filename = NULL ;
2014-04-10 15:37:59 +08:00
for ( rapidjson : : SizeType i = 0 ; i < objectfiles . Size ( ) ; i + + )
{
2014-09-17 18:01:25 +08:00
filename = objectfiles [ i ] . GetString ( ) ;
// remove file from disk
string filepath ( g_resourcePath + " / " + filename ) ;
if ( FileUtils : : getInstance ( ) - > isFileExist ( filepath ) )
{
if ( remove ( filepath . c_str ( ) ) ! = 0 )
{
// remove failed
bodyvalue . AddMember ( filename , 2 , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
}
2014-09-17 18:01:25 +08:00
} else
{
// file not exist
bodyvalue . AddMember ( filename , 1 , dReplyParse . GetAllocator ( ) ) ;
}
if ( _fileserver )
{
// file remove success, remove it from record
if ( ! FileUtils : : getInstance ( ) - > isFileExist ( filepath ) )
_fileserver - > removeResFileInfo ( filename ) ;
2014-03-28 11:37:17 +08:00
}
2014-04-10 15:37:59 +08:00
}
2014-09-17 18:01:25 +08:00
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
2014-04-10 15:37:59 +08:00
}
2014-03-26 14:48:04 +08:00
2014-09-17 18:01:25 +08:00
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
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-09-17 18:01:25 +08:00
} else if ( strcmp ( strcmd . c_str ( ) , " getplatform " ) = = 0 )
2014-08-13 11:30:43 +08:00
{
string platform = " UNKNOW " ;
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
platform = " WIN32 " ;
# elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
platform = " MAC " ;
# elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
platform = " IOS " ;
# elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
platform = " ANDROID " ;
# endif
rapidjson : : Value bodyvalue ( rapidjson : : kObjectType ) ;
rapidjson : : Value platformValue ( rapidjson : : kStringType ) ;
2014-09-17 18:01:25 +08:00
platformValue . SetString ( platform . c_str ( ) , dReplyParse . GetAllocator ( ) ) ;
bodyvalue . AddMember ( " platform " , platformValue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " body " , bodyvalue , dReplyParse . GetAllocator ( ) ) ;
dReplyParse . AddMember ( " code " , 0 , dReplyParse . GetAllocator ( ) ) ;
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 ) ;
2014-09-17 18:01:25 +08:00
string msgContent = buffer . GetString ( ) ;
char msgLength [ 64 ] = { 0x1 , 0 } ;
sprintf ( msgLength + 1 , " %zu: " , msgContent . size ( ) ) ;
string msg ( msgLength + msgContent ) ;
2014-09-18 12:40:26 +08:00
sendBuf ( fd , msg . c_str ( ) , msg . size ( ) ) ;
2014-04-10 15:37:59 +08:00
}
} ) ;
}
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 ;
2014-08-29 15:05:55 +08:00
std : : string originPath = arg0 ;
if ( ! FileUtils : : getInstance ( ) - > isAbsolutePath ( originPath ) )
2014-09-17 18:01:25 +08:00
arg0 = g_resourcePath + originPath ;
2014-05-05 21:04:04 +08:00
cobj - > addSearchPath ( arg0 ) ;
2014-09-17 18:01:25 +08:00
2014-08-29 15:05:55 +08:00
if ( ! FileUtils : : getInstance ( ) - > isAbsolutePath ( originPath ) )
2014-09-17 18:01:25 +08:00
# if(CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
cobj - > addSearchPath ( g_projectPath + originPath ) ;
2014-08-29 15:05:55 +08:00
# endif
2014-06-27 09:46:53 +08:00
# if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
2014-09-17 18:01:25 +08:00
cobj - > addSearchPath ( originPath ) ;
2014-06-27 09:46:53 +08:00
# endif
2014-05-05 21:04:04 +08:00
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 ;
}
2014-06-16 14:47:14 +08:00
int lua_cocos2dx_runtime_setSearchPaths ( lua_State * tolua_S )
{
int argc = 0 ;
cocos2d : : FileUtils * cobj = nullptr ;
bool ok = true ;
# if COCOS2D_DEBUG >= 1
tolua_Error tolua_err ;
# endif
# if COCOS2D_DEBUG >= 1
if ( ! tolua_isusertype ( tolua_S , 1 , " cc.FileUtils " , 0 , & tolua_err ) ) goto tolua_lerror ;
# endif
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_runtime_setSearchPaths' " , nullptr ) ;
return 0 ;
}
# endif
argc = lua_gettop ( tolua_S ) - 1 ;
if ( argc = = 1 )
{
std : : vector < std : : string > vecPaths ;
ok & = luaval_to_std_vector_string ( tolua_S , 2 , & vecPaths ) ;
if ( ! ok )
return 0 ;
2014-08-29 15:05:55 +08:00
std : : vector < std : : string > originPath ; // for IOS platform.
std : : vector < std : : string > projPath ; // for Desktop platform.
2014-06-16 14:47:14 +08:00
for ( int i = 0 ; i < vecPaths . size ( ) ; i + + )
{
if ( ! FileUtils : : getInstance ( ) - > isAbsolutePath ( vecPaths [ i ] ) )
2014-06-27 09:46:53 +08:00
{
2014-08-29 15:05:55 +08:00
originPath . push_back ( vecPaths [ i ] ) ; // for IOS platform.
projPath . push_back ( g_projectPath + vecPaths [ i ] ) ; //for Desktop platform.
2014-06-16 14:47:14 +08:00
vecPaths [ i ] = g_resourcePath + vecPaths [ i ] ;
2014-06-27 09:46:53 +08:00
}
2014-06-16 14:47:14 +08:00
}
2014-08-29 15:05:55 +08:00
# if(CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
vecPaths . insert ( vecPaths . end ( ) , projPath . begin ( ) , projPath . end ( ) ) ;
# endif
2014-06-27 09:46:53 +08:00
# if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
2014-08-29 15:05:55 +08:00
vecPaths . insert ( vecPaths . end ( ) , originPath . begin ( ) , originPath . end ( ) ) ;
2014-06-27 09:46:53 +08:00
# endif
2014-06-16 14:47:14 +08:00
cobj - > setSearchPaths ( vecPaths ) ;
return 0 ;
}
CCLOG ( " %s has wrong number of arguments: %d, was expecting %d \n " , " setSearchPaths " , argc , 1 ) ;
return 0 ;
# if COCOS2D_DEBUG >= 1
tolua_lerror :
tolua_error ( tolua_S , " #ferror in function 'lua_cocos2dx_runtime_setSearchPaths'. " , & tolua_err ) ;
# endif
return 0 ;
}
2014-05-05 21:04:04 +08:00
static void register_runtime_override_function ( lua_State * tolua_S )
{
lua_pushstring ( tolua_S , " cc.FileUtils " ) ;
lua_rawget ( tolua_S , LUA_REGISTRYINDEX ) ;
2014-06-13 11:17:44 +08:00
if ( lua_istable ( tolua_S , - 1 ) ) {
2014-05-05 21:04:04 +08:00
tolua_function ( tolua_S , " addSearchPath " , lua_cocos2dx_runtime_addSearchPath ) ;
2014-06-16 14:47:14 +08:00
tolua_function ( tolua_S , " setSearchPaths " , lua_cocos2dx_runtime_setSearchPaths ) ;
2014-05-05 21:04:04 +08:00
}
lua_pop ( tolua_S , 1 ) ;
}
2014-09-24 11:43:21 +08:00
void initRuntime ( )
2014-05-05 21:04:04 +08:00
{
2014-09-24 11:43:21 +08:00
vector < string > 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-09-24 11:43:21 +08:00
// add peoject's root directory to search path
2014-08-29 15:05:55 +08:00
if ( g_projectPath . empty ( ) )
2014-04-10 15:37:59 +08:00
{
extern std : : string getCurAppPath ( ) ;
2014-08-29 15:05:55 +08:00
string appPath = getCurAppPath ( ) ;
2014-03-28 11:37:17 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
2014-08-29 15:05:55 +08:00
appPath . append ( " /../../ " ) ;
2014-03-28 11:37:17 +08:00
# elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
2014-08-29 15:05:55 +08:00
appPath . append ( " /../../../ " ) ;
2014-03-28 11:37:17 +08:00
# endif
2014-09-17 18:01:25 +08:00
appPath = replaceAll ( appPath , " \\ " , " / " ) ;
2014-08-29 15:05:55 +08:00
g_projectPath = appPath ;
2014-08-13 11:30:43 +08:00
}
2014-09-17 18:01:25 +08:00
searchPathArray . insert ( searchPathArray . begin ( ) , g_projectPath ) ;
2014-08-29 16:21:34 +08:00
# endif
2014-09-24 11:43:21 +08:00
// add writable path to search path
2014-08-29 15:05:55 +08:00
g_resourcePath = FileUtils : : getInstance ( ) - > getWritablePath ( ) ;
2014-09-17 18:01:25 +08:00
2014-09-01 17:35:08 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
std : : string getCurAppName ( void ) ;
g_resourcePath + = getCurAppName ( ) ;
2014-09-17 18:01:25 +08:00
g_resourcePath + = " / " ;
2014-09-01 17:35:08 +08:00
# endif
2014-09-17 18:01:25 +08:00
2014-08-29 15:05:55 +08:00
g_resourcePath + = " debugruntime/ " ;
2014-09-17 18:01:25 +08:00
g_resourcePath = replaceAll ( g_resourcePath , " \\ " , " / " ) ;
if ( g_resourcePath . at ( g_resourcePath . length ( ) - 1 ) ! = ' / ' ) {
2014-05-08 16:02:55 +08:00
g_resourcePath . append ( " / " ) ;
}
2014-09-17 18:01:25 +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
2014-07-16 18:19:33 +08:00
auto engine = LuaEngine : : getInstance ( ) ;
ScriptEngineManager : : getInstance ( ) - > setScriptEngine ( engine ) ;
LuaStack * stack = engine - > getLuaStack ( ) ;
register_runtime_override_function ( stack - > getLuaState ( ) ) ;
luaopen_debugger ( engine - > getLuaStack ( ) - > getLuaState ( ) ) ;
2014-09-16 16:19:05 +08:00
2014-08-13 11:30:43 +08:00
static ConsoleCustomCommand * g_customCommand ;
g_customCommand = new ConsoleCustomCommand ( ) ;
g_customCommand - > init ( ) ;
2014-05-05 21:04:04 +08:00
}
2014-09-24 11:43:21 +08:00
void startRuntime ( )
2014-05-05 21:04:04 +08:00
{
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 ) ;
}