/* PIP - Platform Independent Primitives PICloud dispatcher Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "pip.h" #include "picrypt.h" #include "piiostream.h" #include "dispatcherserver.h" using namespace PICoutManipulators; void usage() { piCout << Bold << "PIP Cloud Dispatcher"; piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine; piCout << Green << Bold << "Usage:" << Default << "\"picloud [-hsv] [-i ] [-p ]\"" << NewLine; piCout << Green << Bold << "Details:"; piCout << "-h --help " << Green << "- display this message and exit"; piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\""; piCout << "-p --port " << Green << "- listen port, default 10101"; piCout << "-s --screen " << Green << "- start with console UI"; piCout << "-v --verbose" << Green << "- print state (--screen ignore this flag)"; } PIString confDir() { return #ifdef WINDOWS PIDir::home().path() + "/AppData/Local" #elif defined(MAC_OS) PIDir::home().path() + "/Library/Preferences" #elif defined(ANDROID) PIString(".") #else PIDir::home().path() + "/.config" #endif + "/SHS"; } int main (int argc, char * argv[]) { PICLI cli(argc, argv); cli.addArgument("help"); cli.addArgument("ip", true); cli.addArgument("port", true); cli.addArgument("screen"); cli.addArgument("verbose"); if (cli.hasArgument("help")) { usage(); return 0; } PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101); PIString conf_path = confDir(); PIDir::make(conf_path); conf_path += "/picloud.conf"; uint max_connections = 1000; if (!PIFile::isExists(conf_path)) { PIFile f(conf_path, PIIODevice::ReadWrite); PIIOTextStream ts(&f); ts << "ip = " << addr.ipString() << "\n" << "port = " << addr.port() << "\n" << "max_connections = " << max_connections << "\n"; } { PIConfig conf(conf_path, PIIODevice::ReadOnly); addr.setIP(conf.getValue("ip", addr.ipString()).toString()); addr.setPort(conf.getValue("port", addr.port()).toUShort()); max_connections = conf.getValue("max_connections", max_connections).toUInt(); } PITimer status_timer; if (cli.hasArgument("ip")) addr.setIP(cli.argumentValue("ip")); if (cli.hasArgument("port")) addr.setPort(cli.argumentValue("port").toInt()); DispatcherServer server(addr); server.setMaxConnections(max_connections); if (cli.hasArgument("screen")) { PISet sel_servers; PIScreen screen(false); PIScreenTile maintile("PICloud Dispatcher", PIScreenTypes::Horizontal, PIScreenTypes::Expanding); PIScreenTile tls[3]; TileList conn_tl(PIString(), TileList::MultiSelection); TileList server_tl(PIString(), TileList::MultiSelection); TileList client_tl(PIString(), TileList::MultiSelection); tls[0].addTile(new TileSimple(TileSimple::Row("Connections", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse)))); tls[0].addTile(&conn_tl); tls[1].addTile(new TileSimple(TileSimple::Row("Servers", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse)))); tls[1].addTile(&server_tl); tls[2].addTile(new TileSimple(TileSimple::Row("Clients", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse)))); tls[2].addTile(&client_tl); CONNECTL(&screen, tileEvent, ([&](PIScreenTile * t, PIScreenTypes::TileEvent e){ if (t == (PIScreenTile *)&server_tl) { if (e.type == TileList::SelectionChanged) { sel_servers = server.getServers(server_tl.selected); } } if (t == (PIScreenTile *)&conn_tl) { if (e.type == TileList::RowPressed) { sel_servers.clear(); server_tl.selected.clear(); const DispatcherClient * dc = server.getServer(e.data.toInt()); if (dc) sel_servers << dc; } } })); for (auto & a : tls) { a.children()[0]->size_policy = PIScreenTypes::Fixed; maintile.addTile(&a); } CONNECTL(&status_timer, tickEvent, [&](void *, int){ screen.lock(); server.updateConnectionsTile(&conn_tl); server.updateServersTile(&server_tl, sel_servers); server.updateClientsTile(&client_tl, server.getServers(server_tl.selected)); screen.unlock(); }); screen.enableExitCapture(PIKbdListener::F10); screen.rootTile()->addTile(new TileSimple(TileSimple::Row("PICloud Dispatcher " + addr.toString(), PIScreenTypes::CellFormat(PIScreenTypes::Yellow, PIScreenTypes::Default, PIScreenTypes::Bold)))); screen.rootTile()->addTile(&maintile); screen.rootTile()->addTile(new TilePICout()); screen.start(); server.start(); status_timer.start(100); screen.waitForFinish(); } else { PIKbdListener ls; ls.enableExitCapture(PIKbdListener::F10); ls.start(); server.start(); if (cli.hasArgument("verbose")) { CONNECTU(&status_timer, tickEvent, &server, picoutStatus); status_timer.start(1000); } WAIT_FOR_EXIT } return 0; }