mirror of https://github.com/axmolengine/axmol.git
Merge pull request #5477 from heliclei/console-upload-file
CCConsole:support file upload via telnet console
This commit is contained in:
commit
b363751b1a
|
@ -105,6 +105,7 @@ static bool isFloat( std::string myString ) {
|
||||||
// Check the entire string was consumed and if either failbit or badbit is set
|
// Check the entire string was consumed and if either failbit or badbit is set
|
||||||
return iss.eof() && !iss.fail();
|
return iss.eof() && !iss.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper free functions
|
// helper free functions
|
||||||
|
|
||||||
// dprintf() is not defined in Android
|
// dprintf() is not defined in Android
|
||||||
|
@ -281,7 +282,7 @@ Console::Console()
|
||||||
{ "texture", "Flush or print the TextureCache info. Args: [flush | ] ", std::bind(&Console::commandTextures, this, std::placeholders::_1, std::placeholders::_2) },
|
{ "texture", "Flush or print the TextureCache info. Args: [flush | ] ", std::bind(&Console::commandTextures, this, std::placeholders::_1, std::placeholders::_2) },
|
||||||
{ "director", "director commands, type -h or [director help] to list supported directives", std::bind(&Console::commandDirector, this, std::placeholders::_1, std::placeholders::_2) },
|
{ "director", "director commands, type -h or [director help] to list supported directives", std::bind(&Console::commandDirector, this, std::placeholders::_1, std::placeholders::_2) },
|
||||||
{ "touch", "simulate touch event via console, type -h or [touch help] to list supported directives", std::bind(&Console::commandTouch, this, std::placeholders::_1, std::placeholders::_2) },
|
{ "touch", "simulate touch event via console, type -h or [touch help] to list supported directives", std::bind(&Console::commandTouch, this, std::placeholders::_1, std::placeholders::_2) },
|
||||||
|
{ "upload", "upload file. Args: [filename filesize]", std::bind(&Console::commandUpload, this, std::placeholders::_1, std::placeholders::_2) },
|
||||||
};
|
};
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -753,6 +754,22 @@ void Console::commandTouch(int fd, const std::string& args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Console::commandUpload(int fd, const std::string& args)
|
||||||
|
{
|
||||||
|
auto argv = split(args,' ');
|
||||||
|
if(argv.size() == 2)
|
||||||
|
{
|
||||||
|
_upload_file_name = argv[0];
|
||||||
|
_upload_file_size = std::atoi(argv[1].c_str());
|
||||||
|
_file_uploading = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char msg[] = "upload: invalid arguments.\n";
|
||||||
|
send(fd, msg, sizeof(msg) - 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
bool Console::parseCommand(int fd)
|
bool Console::parseCommand(int fd)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
@ -832,6 +849,48 @@ ssize_t Console::readline(int fd, char* ptr, int maxlen)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Console::readfile(int fd, std::string& file_name, int file_size)
|
||||||
|
{
|
||||||
|
ssize_t n, rc;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
auto sharedFileUtils = FileUtils::getInstance();
|
||||||
|
|
||||||
|
std::string writablePath = sharedFileUtils->getWritablePath();
|
||||||
|
std::string fileName = writablePath+file_name;
|
||||||
|
|
||||||
|
FILE* fp = fopen(fileName.c_str(), "wb");
|
||||||
|
if(!fp)
|
||||||
|
{
|
||||||
|
const char err[] = "can't create file!\n";
|
||||||
|
send(fd, err, sizeof(err),0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (fp)
|
||||||
|
// {
|
||||||
|
// size_t ret = fwrite(szBuf, 1, strl6en(szBuf), fp);
|
||||||
|
// CCASSERT(ret != 0, "fwrite function returned zero value");
|
||||||
|
// fclose(fp);
|
||||||
|
// if (ret != 0)
|
||||||
|
// log("Writing file to writable path succeed.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
for( n=0; n<file_size; n++ ) {
|
||||||
|
if( (rc = recv(fd, &c, 1, 0)) ==1 ) {
|
||||||
|
fwrite(&c, 1, 1, fp);
|
||||||
|
} else if( rc == 0 ) {
|
||||||
|
return 0;
|
||||||
|
} else if( errno == EINTR ) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
void Console::addClient()
|
void Console::addClient()
|
||||||
{
|
{
|
||||||
struct sockaddr client;
|
struct sockaddr client;
|
||||||
|
@ -910,10 +969,21 @@ void Console::loop()
|
||||||
/* data from client */
|
/* data from client */
|
||||||
std::vector<int> to_remove;
|
std::vector<int> to_remove;
|
||||||
for(const auto &fd: _fds) {
|
for(const auto &fd: _fds) {
|
||||||
if(FD_ISSET(fd,©_set)) {
|
if(FD_ISSET(fd,©_set))
|
||||||
if( ! parseCommand(fd) ) {
|
{
|
||||||
|
if(!_file_uploading)
|
||||||
|
{
|
||||||
|
if( ! parseCommand(fd) )
|
||||||
|
{
|
||||||
to_remove.push_back(fd);
|
to_remove.push_back(fd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
readfile(fd, _upload_file_name, _upload_file_size);
|
||||||
|
_file_uploading = false;
|
||||||
|
|
||||||
|
}
|
||||||
if(--nready <= 0)
|
if(--nready <= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void loop();
|
void loop();
|
||||||
ssize_t readline(int fd, char *buf, int maxlen);
|
ssize_t readline(int fd, char *buf, int maxlen);
|
||||||
|
ssize_t readfile(int fd, std::string &file_name, int file_size);
|
||||||
bool parseCommand(int fd);
|
bool parseCommand(int fd);
|
||||||
|
|
||||||
void addClient();
|
void addClient();
|
||||||
|
@ -115,6 +116,7 @@ protected:
|
||||||
void commandProjection(int fd, const std::string &args);
|
void commandProjection(int fd, const std::string &args);
|
||||||
void commandDirector(int fd, const std::string &args);
|
void commandDirector(int fd, const std::string &args);
|
||||||
void commandTouch(int fd, const std::string &args);
|
void commandTouch(int fd, const std::string &args);
|
||||||
|
void commandUpload(int fd, const std::string &args);
|
||||||
// file descriptor: socket, console, etc.
|
// file descriptor: socket, console, etc.
|
||||||
int _listenfd;
|
int _listenfd;
|
||||||
int _maxfd;
|
int _maxfd;
|
||||||
|
@ -126,6 +128,10 @@ protected:
|
||||||
bool _running;
|
bool _running;
|
||||||
bool _endThread;
|
bool _endThread;
|
||||||
|
|
||||||
|
bool _file_uploading;
|
||||||
|
ssize_t _upload_file_size;
|
||||||
|
std::string _upload_file_name;
|
||||||
|
|
||||||
std::map<std::string, Command> _commands;
|
std::map<std::string, Command> _commands;
|
||||||
|
|
||||||
// strings generated by cocos2d sent to the remote console
|
// strings generated by cocos2d sent to the remote console
|
||||||
|
|
|
@ -24,17 +24,21 @@
|
||||||
|
|
||||||
#include "ConsoleTest.h"
|
#include "ConsoleTest.h"
|
||||||
#include "../testResource.h"
|
#include "../testResource.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
|
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
#else
|
#else
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <WS2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// EaseSpriteDemo
|
// ConsoleTest
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -42,8 +46,8 @@ static int sceneIdx = -1;
|
||||||
|
|
||||||
static std::function<Layer*()> createFunctions[] =
|
static std::function<Layer*()> createFunctions[] =
|
||||||
{
|
{
|
||||||
CL(ConsoleTCP),
|
|
||||||
CL(ConsoleCustomCommand),
|
CL(ConsoleCustomCommand),
|
||||||
|
CL(ConsoleUploadFile),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||||
|
@ -126,37 +130,6 @@ void ConsoleTestScene::runThisTest()
|
||||||
Director::getInstance()->replaceScene(this);
|
Director::getInstance()->replaceScene(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ConsoleTCP
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
|
|
||||||
ConsoleTCP::ConsoleTCP()
|
|
||||||
{
|
|
||||||
_console = Director::getInstance()->getConsole();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleTCP::~ConsoleTCP()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleTCP::onEnter()
|
|
||||||
{
|
|
||||||
BaseTestConsole::onEnter();
|
|
||||||
_console->listenOnTCP(5678);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ConsoleTCP::title() const
|
|
||||||
{
|
|
||||||
return "Console TCP";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ConsoleTCP::subtitle() const
|
|
||||||
{
|
|
||||||
return "telnet localhost 5678";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -166,6 +139,7 @@ std::string ConsoleTCP::subtitle() const
|
||||||
|
|
||||||
ConsoleCustomCommand::ConsoleCustomCommand()
|
ConsoleCustomCommand::ConsoleCustomCommand()
|
||||||
{
|
{
|
||||||
|
_console = Director::getInstance()->getConsole();
|
||||||
static struct Console::Command commands[] = {
|
static struct Console::Command commands[] = {
|
||||||
{"hello", "This is just a user generated command", [](int fd, const std::string& args) {
|
{"hello", "This is just a user generated command", [](int fd, const std::string& args) {
|
||||||
const char msg[] = "how are you?\nArguments passed: ";
|
const char msg[] = "how are you?\nArguments passed: ";
|
||||||
|
@ -184,7 +158,6 @@ ConsoleCustomCommand::~ConsoleCustomCommand()
|
||||||
void ConsoleCustomCommand::onEnter()
|
void ConsoleCustomCommand::onEnter()
|
||||||
{
|
{
|
||||||
BaseTestConsole::onEnter();
|
BaseTestConsole::onEnter();
|
||||||
_console->listenOnTCP(5678);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ConsoleCustomCommand::title() const
|
std::string ConsoleCustomCommand::title() const
|
||||||
|
@ -196,3 +169,162 @@ std::string ConsoleCustomCommand::subtitle() const
|
||||||
{
|
{
|
||||||
return "telnet localhost 5678";
|
return "telnet localhost 5678";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ConsoleUploadFile
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
ConsoleUploadFile::ConsoleUploadFile()
|
||||||
|
{
|
||||||
|
srand (time(NULL));
|
||||||
|
int _id = rand()%100000;
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "%d", _id);
|
||||||
|
_target_file_name = std::string("grossini") + buf;
|
||||||
|
|
||||||
|
_src_file_path = FileUtils::getInstance()->fullPathForFilename(s_pathGrossini);
|
||||||
|
_thread = std::thread( &ConsoleUploadFile::uploadFile, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleUploadFile::onEnter()
|
||||||
|
{
|
||||||
|
BaseTestConsole::onEnter();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleUploadFile::~ConsoleUploadFile()
|
||||||
|
{
|
||||||
|
_thread.join();
|
||||||
|
}
|
||||||
|
void ConsoleUploadFile::uploadFile()
|
||||||
|
{
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *result, *rp;
|
||||||
|
int sfd, s, j;
|
||||||
|
|
||||||
|
/* Obtain address(es) matching host/port */
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
|
hints.ai_family = AF_INET; /* Allow IPv4 or IPv6 */
|
||||||
|
hints.ai_socktype = SOCK_STREAM; /* stream socket */
|
||||||
|
hints.ai_flags = 0;
|
||||||
|
hints.ai_protocol = 0; /* Any protocol */
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
|
WSADATA wsaData;
|
||||||
|
WSAStartup(MAKEWORD(2, 2),&wsaData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s = getaddrinfo("localhost", "5678", &hints, &result);
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
CCLOG("ConsoleUploadFile: getaddrinfo error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* getaddrinfo() returns a list of address structures.
|
||||||
|
Try each address until we successfully connect(2).
|
||||||
|
If socket(2) (or connect(2)) fails, we (close the socket
|
||||||
|
and) try the next address. */
|
||||||
|
|
||||||
|
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||||
|
sfd = socket(rp->ai_family, rp->ai_socktype,
|
||||||
|
rp->ai_protocol);
|
||||||
|
if (sfd == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||||
|
break; /* Success */
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
|
closesocket(sfd);
|
||||||
|
#else
|
||||||
|
close(sfd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp == NULL) { /* No address succeeded */
|
||||||
|
CCLOG("ConsoleUploadFile: could not connect!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(result); /* No longer needed */
|
||||||
|
|
||||||
|
|
||||||
|
FILE* fp = fopen(_src_file_path.c_str(), "rb");
|
||||||
|
if(!fp)
|
||||||
|
{
|
||||||
|
CCLOG("ConsoleUploadFile: could not open file %s", _src_file_path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//read file size
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
int size = ftell(fp);
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
char sb[32];
|
||||||
|
sprintf(sb, "%d", size);
|
||||||
|
std::string tmp = "upload";
|
||||||
|
|
||||||
|
tmp += " ";
|
||||||
|
tmp += _target_file_name;
|
||||||
|
tmp += " ";
|
||||||
|
tmp += sb;
|
||||||
|
tmp += "\n";
|
||||||
|
char cmd[512];
|
||||||
|
|
||||||
|
strcpy(cmd, tmp.c_str());
|
||||||
|
send(sfd,cmd,strlen(cmd),0);
|
||||||
|
|
||||||
|
// allocate memory to contain the whole file:
|
||||||
|
char* buffer = (char*) malloc (sizeof(char)*size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
CCLOG("ConsoleUploadFile: memory allocate error!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the file into the buffer:
|
||||||
|
int ret = fread(buffer, 1, size, fp);
|
||||||
|
if (ret != size)
|
||||||
|
{
|
||||||
|
CCLOG("ConsoleUploadFile: read file: %s error!",_src_file_path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//send to console socket
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
send(sfd, &buffer[i], 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminate
|
||||||
|
fclose (fp);
|
||||||
|
free (buffer);
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
|
closesocket(sfd);
|
||||||
|
WSACleanup();
|
||||||
|
#else
|
||||||
|
close(sfd);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConsoleUploadFile::title() const
|
||||||
|
{
|
||||||
|
return "Console UploadFile";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConsoleUploadFile::subtitle() const
|
||||||
|
{
|
||||||
|
auto sharedFileUtils = FileUtils::getInstance();
|
||||||
|
|
||||||
|
std::string writablePath = sharedFileUtils->getWritablePath();
|
||||||
|
|
||||||
|
return "file uploaded to:" + writablePath + _target_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,31 +45,13 @@ public:
|
||||||
void backCallback(Ref* sender) override;
|
void backCallback(Ref* sender) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConsoleTCP : public BaseTestConsole
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CREATE_FUNC(ConsoleTCP);
|
|
||||||
|
|
||||||
void onEnter() override;
|
|
||||||
virtual std::string title() const override;
|
|
||||||
virtual std::string subtitle() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ConsoleTCP();
|
|
||||||
virtual ~ConsoleTCP();
|
|
||||||
|
|
||||||
cocos2d::Console *_console;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleTCP);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConsoleCustomCommand : public BaseTestConsole
|
class ConsoleCustomCommand : public BaseTestConsole
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CREATE_FUNC(ConsoleCustomCommand);
|
CREATE_FUNC(ConsoleCustomCommand);
|
||||||
|
|
||||||
void onEnter() override;
|
virtual void onEnter() override;
|
||||||
virtual std::string title() const override;
|
virtual std::string title() const override;
|
||||||
virtual std::string subtitle() const override;
|
virtual std::string subtitle() const override;
|
||||||
|
|
||||||
|
@ -82,6 +64,27 @@ private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleCustomCommand);
|
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleCustomCommand);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConsoleUploadFile : public BaseTestConsole
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CREATE_FUNC(ConsoleUploadFile);
|
||||||
|
|
||||||
|
virtual void onEnter() override;
|
||||||
|
virtual std::string title() const override;
|
||||||
|
virtual std::string subtitle() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConsoleUploadFile();
|
||||||
|
virtual ~ConsoleUploadFile();
|
||||||
|
|
||||||
|
void uploadFile();
|
||||||
|
std::string _src_file_path;
|
||||||
|
std::string _target_file_name;
|
||||||
|
std::thread _thread;
|
||||||
|
private:
|
||||||
|
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleUploadFile);
|
||||||
|
};
|
||||||
|
|
||||||
class ConsoleTestScene : public TestScene
|
class ConsoleTestScene : public TestScene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue