Commit dc52ba24 authored by Subs's avatar Subs

Add a basic sock handler to receive commands from outside

This is the first commit. It adds :
- a UDP sock server on port 1337
- the ability to run games when receiving a message such as "START|gba|Uranus.gba|"

It's still at a very early stage and can be much improved. But it runs rather fine for now and needs larger testing.

Known bugs:
- if a same archive exists in different subfolders of a system, ES will launch the very first one it finds
parent 0479cf11
......@@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added vertical slide transition when carousel is vertical
- Added theming options for carousel and systeminfo in system view
- Added "features" tag in theming options
- Add a UDP sock server on port 1337
- Added new version support
- Added an option to scrape recalbox-mix-images from screenscraper
- Added new mamedb scrapper mirror
......
......@@ -55,6 +55,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/recalbox/RecalboxSystem.h
${CMAKE_CURRENT_SOURCE_DIR}/src/recalbox/RecalboxUpgrade.h
${CMAKE_CURRENT_SOURCE_DIR}/src/LibretroRatio.h
${CMAKE_CURRENT_SOURCE_DIR}/src/CommandThread.h
)
set(ES_SOURCES
......@@ -108,6 +109,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/recalbox/RecalboxSystem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/recalbox/RecalboxUpgrade.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/LibretroRatio.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/CommandThread.cpp
)
#-------------------------------------------------------------------------------
......
#include "CommandThread.h"
#include "guis/GuiMsgBox.h"
#include "SystemData.h"
#include "Log.h"
#include "views/ViewController.h"
#include <boost/asio.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
using boost::asio::ip::udp;
const int max_length = 2048;
CommandThread::CommandThread(Window* window) : mWindow(window) {
mRunning = true;
mThreadHandle = new boost::thread(boost::bind(&CommandThread::run, this));
}
CommandThread::~CommandThread() {
mThreadHandle->join();
}
void CommandThread::run() {
boost::this_thread::sleep(boost::posix_time::seconds(5));
LOG(LogInfo) << "CommandThread started";
boost::asio::io_service io_service;
udp::socket sock(io_service, udp::endpoint(udp::v4(), 1337));
char buf[max_length];
while (mRunning) {
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(boost::asio::buffer(buf, max_length), sender_endpoint);
if (length <= 0) {
continue;
}
buf[length + 1] = '\0';
std::string str(buf, length);
std::vector<std::string> tokens;
boost::split(tokens, str, boost::is_from_range('|', '|'), boost::token_compress_on);
// Check that the command is valid. Easy way as there is just 1 for now
if (tokens[0] != "START") {
LOG(LogError) << "Wrong network command " << tokens[0];
continue;
}
SystemData *system = NULL;
for (auto tmp = SystemData::sSystemVector.begin(); tmp != SystemData::sSystemVector.end(); tmp ++) {
if ((*tmp)->getName() == tokens[1]) {
system = *tmp;
break;
}
}
// The system is not a valid one
if (system == NULL) {
LOG(LogError) << "Invalid system on network command: " << tokens[1];
continue;
}
std::vector<FileData*> games = system->getRootFolder()->getChildren();
FileData* result = findRecursive(games, tokens[2]);
if (result != NULL) {
LOG(LogInfo) << "Starting game " << tokens[2] << " for system " << tokens[1];
runGame(result);
} else {
LOG(LogError) << "Couldn't find game " << tokens[2] << " for system " << tokens[1];
}
/*
ViewController *view = ViewController::get();
bool found = false;
Eigen::Vector3f target(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0);
LOG(LogInfo) << "Looking for game: " << tokens[2];
std::vector<FileData*> games = system->getRootFolder()->getChildren();
for (auto game = games.begin(); game != games.end(); ++game) {
LOG(LogError) << "Checking: " << (*game)->getPath().filename();
if ((*game)->getType() == FOLDER) {
LOG(LogError) << "Skipping folder: " << (*game)->getPath().filename();
continue;
}
if ((*game)->getType() == GAME and (*game)->getPath().filename() == tokens[2]) {
LOG(LogInfo) << "Game found !";
found = true;
//mWindow->wakeUp();
view->launch(*game, target);
break;
}
}
if (!found) {
LOG(LogError) << "Could not find the game";
}
//*/
}
}
FileData* CommandThread::findRecursive(std::vector<FileData*> gameFolder, std::string gameName) {
for (auto game = gameFolder.begin(); game != gameFolder.end(); ++game) {
LOG(LogInfo) << "Checking: " << (*game)->getPath().filename();
if ((*game)->getType() == FOLDER) {
FileData* foundGame = findRecursive((*game)->getChildren(), gameName);
if ( foundGame != NULL ) {
LOG(LogInfo) << "Game found !";
return foundGame;
}
}
if ((*game)->getType() == GAME and (*game)->getPath().filename() == gameName) {
LOG(LogInfo) << "Game found !";
return *game;
}
}
return NULL;
}
void CommandThread::runGame (FileData* game) {
ViewController *view = ViewController::get();
Eigen::Vector3f target(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0);
//mWindow->wakeUp();
view->launch(game, target);
}
#include <Window.h>
#include "FileData.h"
#include <boost/thread/thread.hpp>
class CommandThread {
public:
CommandThread(Window* window);
~CommandThread();
void run();
FileData* findRecursive(std::vector<FileData*> gameFolder, std::string gameName);
void runGame (FileData* game);
private:
Window* mWindow;
bool mRunning;
boost::thread* mThreadHandle;
};
......@@ -29,6 +29,7 @@
#include "NetworkThread.h"
#include "recalbox/RecalboxSystem.h"
#include "FileSorts.h"
#include "CommandThread.h"
#ifdef WIN32
......@@ -347,6 +348,9 @@ int main(int argc, char* argv[])
// UPDATE CHECK THREAD
NetworkThread * nthread = new NetworkThread(&window);
// Start the socket server
CommandThread* ct = new CommandThread(&window);
//run the command line scraper then quit
if(scrape_cmdline)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment