Commit 5273f578 authored by Supernature2k's avatar Supernature2k

enhancement

parent b5169315
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -49,6 +49,7 @@ void GuiHashStart::start()
auto cmdResult = RecalboxSystem::getInstance()->execute(command);
//script output 1 if system is in fobidden list (like fba_libretro) so we skip to next system
if (cmdResult.second == 1) {
LOG(LogInfo) << "system \"" << system->getName() << "\" can't be hashed";
continue;
......@@ -110,14 +111,21 @@ void GuiHashStart::start()
mBusyAnim.setText(busyText);
// if missing only, don't bother calculating hash if tag is present
if (fileNode.child("hash") && mFilter->getSelected() != "all") {
continue;
}
std::string cmd = "/recalbox/scripts/recalbox-hash.sh -f \"" + path.string() + "\"";
auto hashResult = RecalboxSystem::getInstance()->execute(cmd);
std::string hashString = hashResult.first;
//script output an endline after hash, need to remove it
hashString.erase(std::remove(hashString.begin(), hashString.end(), '\n'), hashString.end());
//if tag exist, update if not, add it
if (fileNode.child("hash") && mFilter->getSelected() == "all") {
fileNode.child("hash").text().set(hashString.c_str());
} else {
......@@ -147,9 +155,20 @@ bool GuiHashStart::input(InputConfig* config, Input input)
void GuiHashStart::update(int deltaTime) {
GuiComponent::update(deltaTime);
mBusyAnim.update(deltaTime);
if (mState == 1) {
this->mLoading = true;
mHandle = new boost::thread(boost::bind(&GuiHashStart::start, this));
mWindow->pushGui(
new GuiMsgBox(mWindow, _("THIS COULD TAKE A WHILE, CONFIRM?"), _("YES"),
[this] {
this->mLoading = true;
mHandle = new boost::thread(boost::bind(&GuiHashStart::start, this));
mState = 0;
}, _("NO"), [this] {
mState = -1;
})
);
mState = 0;
}
if (mState == -1) {
......
......@@ -72,6 +72,7 @@ GuiNetPlay::GuiNetPlay(Window* window) : GuiComponent(window),
}
//ugly method to start a new thread THEN populate the grid via update()
void GuiNetPlay::checkLobby()
{
mLobbyLoaded = parseLobby();
......@@ -81,6 +82,42 @@ void GuiNetPlay::checkLobby()
mLobbyChecked = true;
}
bool GuiNetPlay::parseLobby()
{
mRooms.clear();
std::string lobby = RecalboxConf::getInstance()->get("global.netplay.lobby");
auto json_req = RecalboxSystem::getInstance()->execute("curl -s --connect-timeout 3 -m 3 " + lobby);
if (json_req.second == 0) {
json::ptree root;
std::stringstream ss;
ss << json_req.first;
try {
json::read_json(ss, root);
}
catch (const boost::property_tree::json_parser_error& e1) {
return false;
}
for (json::ptree::value_type &array_element : root) {
FileData* tmp = NULL;
if (array_element.second.get<std::string>("fields.game_crc") != "00000000") {
tmp = findGame(array_element.second.get<std::string>("fields.game_crc"));
}
if (!tmp) {
tmp = findGame(array_element.second.get<std::string>("fields.game_name"));
}
mGames.push_back(tmp);
//empty strings for ping on loading
mPings.push_back("\uF1c9 " + _("unknown"));
mRooms.push_back(array_element);
}
return true;
} else {
return false;
}
}
void GuiNetPlay::populateGrid()
{
if (mLobbyLoaded) {
......@@ -123,6 +160,8 @@ void GuiNetPlay::populateGrid()
mList->setFocusLostCallback([this]{mMetaText->setText(""); mLaunchText->setText("");});
mList->setFocusGainedCallback([this]{populateGridMeta(mList->getCursor());});
mHandle = new boost::thread(boost::bind(&GuiNetPlay::pingLobby, this));
mGrid.moveCursor(Eigen::Vector2i(0, -1));
} else {
auto text = std::make_shared<TextComponent>(mWindow, _("NO GAMES OR NO CONNECTION"), mMenuTheme->menuText.font, mMenuTheme->menuText.color, ALIGN_CENTER);
......@@ -131,6 +170,7 @@ void GuiNetPlay::populateGrid()
mLobbyChecked = false;
}
//called when changing cursor in mList
void GuiNetPlay::populateGridMeta(int i)
{
std::string text = "";
......@@ -175,9 +215,9 @@ void GuiNetPlay::populateGridMeta(int i)
text += "\uf1c2 ";
}
text += mRooms[i].second.get<std::string>("fields.core_version", "N/A");
text += "\n Latency : " + mPings[i];
text += "\n " + _("RA ver.") + " : " + mRooms[i].second.get<std::string>("fields.retroarch_version", "N/A");
text += "\n " + _("Host arch.") + " : " + mRooms[i].second.get<std::string>("fields.frontend", "N/A");
//text += "\n Latency : " + mPings[i];
mMetaText->setText(text);
std::string text2 = " " + _("Can join") + " : ";
if (mGames[i]) {
......@@ -214,109 +254,7 @@ void GuiNetPlay::launch()
}
}
float GuiNetPlay::getButtonGridHeight() const
{
auto menuTheme = MenuThemeData::getInstance()->getCurrentTheme();
return (mButtonGrid ? mButtonGrid->getSize().y() : menuTheme->menuText.font->getHeight() + BUTTON_GRID_VERT_PADDING);
}
bool GuiNetPlay::input(InputConfig* config, Input input)
{
if (config->isMappedTo("a", input) && input.value != 0)
{
delete this;
}
return GuiComponent::input(config, input);
}
void GuiNetPlay::updateSize()
{
const float height = Renderer::getScreenHeight() * 0.7f;
const float width = Renderer::getScreenWidth() * 0.8f;
setSize(width, height);
}
void GuiNetPlay::onSizeChanged()
{
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-32, -32));
// update grid row/col sizes
mGrid.setRowHeightPerc(0, TITLE_HEIGHT / mSize.y());
mGrid.setRowHeightPerc(2, getButtonGridHeight() / mSize.y());
mGrid.setSize(mSize);
}
std::vector<HelpPrompt> GuiNetPlay::getHelpPrompts()
{
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
prompts.push_back(HelpPrompt("a", _("BACK")));
prompts.push_back(HelpPrompt("b", _("LAUNCH")));
return prompts;
}
void GuiNetPlay::update(int deltaTime) {
GuiComponent::update(deltaTime);
mBusyAnim.update(deltaTime);
if (!mLoaded) {
mLoading = true;
mHandle = new boost::thread(boost::bind(&GuiNetPlay::checkLobby, this));
mLoaded = true;
}
if (mLobbyChecked) {
populateGrid();
}
}
void GuiNetPlay::render(const Eigen::Affine3f &parentTrans) {
Eigen::Affine3f trans = parentTrans * getTransform();
renderChildren(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0.f, 0.f, mSize.x(), mSize.y(), 0x00000011);
if (mLoading)
mBusyAnim.render(trans);
}
bool GuiNetPlay::parseLobby()
{
mRooms.clear();
std::string lobby = RecalboxConf::getInstance()->get("global.netplay.lobby");
auto json_req = RecalboxSystem::getInstance()->execute("curl -s --connect-timeout 3 -m 3 " + lobby);
if (json_req.second == 0) {
json::ptree root;
std::stringstream ss;
ss << json_req.first;
try {
json::read_json(ss, root);
}
catch (const boost::property_tree::json_parser_error& e1) {
return false;
}
for (json::ptree::value_type &array_element : root) {
FileData* tmp = NULL;
if (array_element.second.get<std::string>("fields.game_crc") != "00000000") {
tmp = findGame(array_element.second.get<std::string>("fields.game_crc"));
}
if (!tmp) {
tmp = findGame(array_element.second.get<std::string>("fields.game_name"));
}
mGames.push_back(tmp);
//mPings.push_back(pingLobbyHost(array_element.second.get<std::string>("fields.ip")));
mRooms.push_back(array_element);
}
return true;
} else {
return false;
}
}
FileData* GuiNetPlay::findGame(std::string gameNameOrHash)
{
......@@ -392,20 +330,96 @@ std::pair<std::string, std::string> GuiNetPlay::getCoreInfo(const std::string &n
return result;
}
std::string GuiNetPlay::pingLobbyHost(const std::string& ip)
void GuiNetPlay::pingLobby()
{
for (int i=0; i<mRooms.size(); i++ ) {
std::string ip = mRooms[i].second.get<std::string>("fields.ip");
mPings[i] = pingHost(ip);
}
}
std::string GuiNetPlay::pingHost(const std::string& ip)
{
std::pair<std::string, int> ping = RecalboxSystem::getInstance()->execute("ping -c 1 -w 1 " + ip + " | grep \"min/avg/max\" | cut -d '/' -f 5");
if (ping.first != "") {
float latency = strtof(ping.first.c_str(), 0);
if (latency <=80) {
return "good";
return "\uF1c8 " + _("good");
} else if (latency <= 150) {
return "medium";
return "\uF1c7 " + _("medium");
} else {
return "bad";
return "\uF1c6 " + _("bad");
}
} else {
return "unknown";
return "\uF1c9 " + _("unknown");
};
}
float GuiNetPlay::getButtonGridHeight() const
{
auto menuTheme = MenuThemeData::getInstance()->getCurrentTheme();
return (mButtonGrid ? mButtonGrid->getSize().y() : menuTheme->menuText.font->getHeight() + BUTTON_GRID_VERT_PADDING);
}
bool GuiNetPlay::input(InputConfig* config, Input input)
{
if (config->isMappedTo("a", input) && input.value != 0)
{
delete this;
}
return GuiComponent::input(config, input);
}
void GuiNetPlay::updateSize()
{
const float height = Renderer::getScreenHeight() * 0.7f;
const float width = Renderer::getScreenWidth() * 0.8f;
setSize(width, height);
}
void GuiNetPlay::onSizeChanged()
{
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-32, -32));
// update grid row/col sizes
mGrid.setRowHeightPerc(0, TITLE_HEIGHT / mSize.y());
mGrid.setRowHeightPerc(2, getButtonGridHeight() / mSize.y());
mGrid.setSize(mSize);
}
std::vector<HelpPrompt> GuiNetPlay::getHelpPrompts()
{
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
prompts.push_back(HelpPrompt("a", _("BACK")));
prompts.push_back(HelpPrompt("b", _("LAUNCH")));
return prompts;
}
void GuiNetPlay::update(int deltaTime) {
GuiComponent::update(deltaTime);
mBusyAnim.update(deltaTime);
if (!mLoaded) {
mLoading = true;
mHandle = new boost::thread(boost::bind(&GuiNetPlay::checkLobby, this));
mLoaded = true;
}
if (mLobbyChecked) {
populateGrid();
}
}
void GuiNetPlay::render(const Eigen::Affine3f &parentTrans) {
Eigen::Affine3f trans = parentTrans * getTransform();
renderChildren(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0.f, 0.f, mSize.x(), mSize.y(), 0x00000011);
if (mLoading)
mBusyAnim.render(trans);
}
\ No newline at end of file
......@@ -29,26 +29,15 @@ class GuiNetPlay : public GuiComponent
public:
GuiNetPlay(Window* window);
void onSizeChanged() override;
inline ~GuiNetPlay() { if (mList) mList->clear(); }
inline void addRow(const ComponentListRow& row, bool setCursorHere = false, bool updateGeometry = true) { mList->addRow(row, setCursorHere, updateGeometry); if (updateGeometry) updateSize(); }
bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const Eigen::Affine3f &parentTrans) override;
void populateGrid();
inline ~GuiNetPlay() { if (mList) mList->clear(); }
std::vector<HelpPrompt> getHelpPrompts() override;
void checkLobby();
bool parseLobby();
void checkLobby();
void populateGrid();
void populateGridMeta(int i);
......@@ -60,46 +49,49 @@ public:
std::pair<std::string, std::string> getCoreInfo(const std::string &name);
std::string pingLobbyHost(const std::string& ip);
void pingLobby();
private:
std::string pingHost(const std::string& ip);
float getButtonGridHeight() const;
void updateSize();
float getButtonGridHeight() const;
bool input(InputConfig* config, Input input) override;
std::vector<HelpPrompt> getHelpPrompts() override;
void onSizeChanged() override;
void update(int deltaTime) override;
void render(const Eigen::Affine3f &parentTrans) override;
private:
NinePatchComponent mBackground;
BusyComponent mBusyAnim;
ComponentGrid mGrid;
std::shared_ptr<MenuTheme> mMenuTheme;
std::shared_ptr<ComponentGrid> mGridMeta;
std::shared_ptr<ComponentGrid> mGridMetaRight;
std::shared_ptr<TextComponent> mTitle;
std::vector< std::shared_ptr<ButtonComponent> > mButtons;
std::shared_ptr<ComponentGrid> mButtonGrid;
std::vector< std::shared_ptr<ButtonComponent> > mButtons;
std::shared_ptr<TextComponent> mTitle;
std::shared_ptr<ComponentList> mList;
std::vector<FileData*> mGames;
std::vector<json::ptree::value_type> mRooms;
std::shared_ptr<TextComponent> mMetaText;
std::shared_ptr<TextComponent> mLaunchText;
//std::vector<std::string> mPings;
std::vector<FileData*> mGames;
std::vector<json::ptree::value_type> mRooms;
std::vector<std::string> mPings;
std::shared_ptr<MenuTheme> mMenuTheme;
boost::thread *mHandle;
bool mLoading;
bool mLoaded = false;
boost::thread *mHandle;
bool mLobbyLoaded;
BusyComponent mBusyAnim;
bool mLobbyChecked;
};
......
......@@ -1785,4 +1785,20 @@ msgstr ""
#:
msgid "Rom hash"
msgstr ""
#:
msgid "THIS COULD TAKE A WHILE, CONFIRM?"
msgstr ""
#:
msgid "good"
msgstr ""
#:
msgid "bad"
msgstr ""
#:
msgid "medium"
msgstr ""
\ No newline at end of file
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