mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Lobby works
This commit is contained in:
parent
7b6d9c23b3
commit
97e5fc8a07
@ -202,7 +202,13 @@ int main(int argc, char * argv[])
|
||||
("serverport", po::value<si64>(), "override port specified in config file")
|
||||
("saveprefix", po::value<std::string>(), "prefix for auto save files")
|
||||
("savefrequency", po::value<si64>(), "limit auto save creation to each N days")
|
||||
("lobby", po::value<std::array<std::string, 3>>(), "parameters to connect ro remote lobby session");
|
||||
("lobby", "parameters address, port, uuid to connect ro remote lobby session")
|
||||
("lobby-address", po::value<std::string>(), "address to remote lobby")
|
||||
("lobby-port", po::value<ui16>(), "port to remote lobby")
|
||||
("lobby-host", "if this client hosts session")
|
||||
("lobby-uuid", po::value<std::string>(), "uuid to the server")
|
||||
("lobby-connections", po::value<std::string>(), "connections of server")
|
||||
("uuid", po::value<std::string>(), "uuid for the client");
|
||||
|
||||
if(argc > 1)
|
||||
{
|
||||
@ -485,14 +491,20 @@ int main(int argc, char * argv[])
|
||||
session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
|
||||
session["aiSolo"].Bool() = false;
|
||||
|
||||
session["lobby"] = false;
|
||||
session["lobby"].Bool() = false;
|
||||
if(vm.count("lobby"))
|
||||
{
|
||||
auto lobbyParams = vc["lobby"].as<std::array<std::string, 3>>();
|
||||
session["lobby"].Bool() = true;
|
||||
session["address"].String() = lobbyParams[0];
|
||||
session["port"].Integer() = std::stoi(lobbyParams[1]);
|
||||
session["uuid"].String() = lobbyParams[2];
|
||||
session["host"].Bool() = false;
|
||||
session["address"].String() = vm["lobby-address"].as<std::string>();
|
||||
CSH->uuid = vm["uuid"].as<std::string>();
|
||||
session["port"].Integer() = vm["lobby-port"].as<ui16>();
|
||||
if(vm.count("lobby-host"))
|
||||
{
|
||||
session["host"].Bool() = true;
|
||||
session["hostConnections"].String() = vm["lobby-connections"].as<std::string>();
|
||||
session["hostUuid"].String() = vm["lobby-uuid"].as<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
if(vm.count("testmap"))
|
||||
|
@ -117,9 +117,9 @@ extern std::string NAME;
|
||||
CServerHandler::CServerHandler()
|
||||
: state(EClientState::NONE), mx(std::make_shared<boost::recursive_mutex>()), client(nullptr), loadMode(0), campaignStateToSend(nullptr), campaignServerRestartLock(false)
|
||||
{
|
||||
if(settings["server"]["uuid"].isNull() || settings["server"]["uuid"].String().empty())
|
||||
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
|
||||
else
|
||||
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
|
||||
//read from file to restore last session
|
||||
if(!settings["server"]["uuid"].isNull() && !settings["server"]["uuid"].String().empty())
|
||||
uuid = settings["server"]["uuid"].String();
|
||||
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
|
||||
registerTypesLobbyPacks(*applier);
|
||||
@ -262,8 +262,8 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
||||
{
|
||||
logNetwork->info("Establishing connection...");
|
||||
c = std::make_shared<CConnection>(
|
||||
addr.size() ? addr : settings["server"]["server"].String(),
|
||||
port ? port : getDefaultPort(),
|
||||
addr.size() ? addr : getHostAddress(),
|
||||
port ? port : getHostPort(),
|
||||
NAME, uuid);
|
||||
}
|
||||
catch(...)
|
||||
@ -281,12 +281,12 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
||||
|
||||
c->handler = std::make_shared<boost::thread>(&CServerHandler::threadHandleConnection, this);
|
||||
|
||||
if(!addr.empty() && addr != localhostAddress)
|
||||
if(!addr.empty() && addr != getHostAddress())
|
||||
{
|
||||
Settings serverAddress = settings.write["server"]["server"];
|
||||
serverAddress->String() = addr;
|
||||
}
|
||||
if(port && port != getDefaultPort())
|
||||
if(port && port != getHostPort())
|
||||
{
|
||||
Settings serverPort = settings.write["server"]["port"];
|
||||
serverPort->Integer() = port;
|
||||
@ -369,6 +369,28 @@ std::string CServerHandler::getDefaultPortStr()
|
||||
return boost::lexical_cast<std::string>(getDefaultPort());
|
||||
}
|
||||
|
||||
std::string CServerHandler::getHostAddress() const
|
||||
{
|
||||
if(settings["session"]["lobby"].isNull() || !settings["session"]["lobby"].Bool())
|
||||
return settings["server"]["server"].String();
|
||||
|
||||
if(settings["session"]["host"].Bool())
|
||||
return localhostAddress;
|
||||
|
||||
return settings["session"]["address"].String();
|
||||
}
|
||||
|
||||
ui16 CServerHandler::getHostPort() const
|
||||
{
|
||||
if(settings["session"]["lobby"].isNull() || !settings["session"]["lobby"].Bool())
|
||||
return getDefaultPort();
|
||||
|
||||
if(settings["session"]["host"].Bool())
|
||||
return getDefaultPort();
|
||||
|
||||
return settings["session"]["port"].Integer();
|
||||
}
|
||||
|
||||
void CServerHandler::sendClientConnecting() const
|
||||
{
|
||||
LobbyClientConnected lcc;
|
||||
@ -813,9 +835,17 @@ void CServerHandler::threadRunServer()
|
||||
setThreadName("CServerHandler::threadRunServer");
|
||||
const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string();
|
||||
std::string comm = VCMIDirs::get().serverPath().string()
|
||||
+ " --port=" + getDefaultPortStr()
|
||||
+ " --port=" + boost::lexical_cast<std::string>(getHostPort())
|
||||
+ " --run-by-client"
|
||||
+ " --uuid=" + uuid;
|
||||
if(settings["session"]["lobby"].Bool() && settings["session"]["host"].Bool())
|
||||
{
|
||||
comm += " --lobby=" + settings["session"]["address"].String();
|
||||
comm += " --connections=" + settings["session"]["hostConnections"].String();
|
||||
comm += " --lobby-port=" + boost::lexical_cast<std::string>(settings["session"]["port"].Integer());
|
||||
comm += " --lobby-uuid=" + settings["session"]["hostUuid"].String();
|
||||
}
|
||||
|
||||
if(shm)
|
||||
{
|
||||
comm += " --enable-shm";
|
||||
|
@ -111,6 +111,9 @@ public:
|
||||
static const std::string localhostAddress;
|
||||
|
||||
CServerHandler();
|
||||
|
||||
std::string getHostAddress() const;
|
||||
ui16 getHostPort() const;
|
||||
|
||||
void resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names = nullptr);
|
||||
void startLocalServerAndConnect();
|
||||
|
@ -481,8 +481,8 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
|
||||
|
||||
inputAddress->giveFocus();
|
||||
}
|
||||
inputAddress->setText(host ? CServerHandler::localhostAddress : settings["server"]["server"].String(), true);
|
||||
inputPort->setText(CServerHandler::getDefaultPortStr(), true);
|
||||
inputAddress->setText(host ? CServerHandler::localhostAddress : CSH->getHostAddress(), true);
|
||||
inputPort->setText(boost::lexical_cast<std::string>(CSH->getHostPort()), true);
|
||||
|
||||
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE);
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(Rect(7, 186, 218, 18), 0));
|
||||
|
@ -253,7 +253,7 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default": {},
|
||||
"required" : [ "server", "port", "serverport", "localInformation", "playerAI", "friendlyAI","neutralAI", "enemyAI", "reconnect", "uuid", "names", "lobby", "host" ],
|
||||
"required" : [ "server", "port", "localInformation", "playerAI", "friendlyAI","neutralAI", "enemyAI", "reconnect", "uuid", "names" ],
|
||||
"properties" : {
|
||||
"server" : {
|
||||
"type":"string",
|
||||
@ -263,10 +263,6 @@
|
||||
"type" : "number",
|
||||
"default" : 3030
|
||||
},
|
||||
"serverport" : {
|
||||
"type" : "number",
|
||||
"default" : 5002
|
||||
},
|
||||
"localInformation" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
@ -295,20 +291,6 @@
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
},
|
||||
"host" : {
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" :
|
||||
{
|
||||
"host" : true
|
||||
},
|
||||
"required" : [ "host", "uuid", "connections" ],
|
||||
"properties" : {
|
||||
"uuid" : { "type" : "string" },
|
||||
"connections" : { "type" : "number" },
|
||||
"host" : {"type" : "boolean", "default" : false}
|
||||
}
|
||||
},
|
||||
"names" : {
|
||||
"type" : "array",
|
||||
"default" : [],
|
||||
@ -317,10 +299,6 @@
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
}
|
||||
},
|
||||
"lobby" : {
|
||||
"type" : "boolean",
|
||||
"default" : false
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -435,7 +413,7 @@
|
||||
},
|
||||
"lobbyUrl" : {
|
||||
"type" : "string",
|
||||
"default" : "127.0.0.1"
|
||||
"default" : "beholder.vcmi.eu"
|
||||
},
|
||||
"lobbyPort" : {
|
||||
"type" : "number",
|
||||
|
@ -119,6 +119,10 @@ Lobby::Lobby(QWidget *parent) :
|
||||
connect(&socketLobby, SIGNAL(text(QString)), this, SLOT(chatMessage(QString)));
|
||||
connect(&socketLobby, SIGNAL(receive(QString)), this, SLOT(dispatchMessage(QString)));
|
||||
connect(&socketLobby, SIGNAL(disconnect()), this, SLOT(onDisconnected()));
|
||||
|
||||
ui->hostEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUrl"].String()));
|
||||
ui->portEdit->setText(QString::number(settings["launcher"]["lobbyPort"].Integer()));
|
||||
ui->userEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUsername"].String()));
|
||||
}
|
||||
|
||||
Lobby::~Lobby()
|
||||
@ -209,17 +213,11 @@ void Lobby::serverCommand(const ServerCommand & command) try
|
||||
case START: {
|
||||
protocolAssert(args.size() == 1);
|
||||
//actually start game
|
||||
//Settings node = settings.write["server"];
|
||||
gameArguments.clear();
|
||||
gameArguments << "--lobby";
|
||||
gameArguments << ui->hostEdit->text();
|
||||
gameArguments << ui->portEdit->text();
|
||||
gameArguments << args[0];
|
||||
/*node["lobby"].Bool() = true;
|
||||
node["server"].String() = ui->hostEdit->text().toStdString();
|
||||
node["serverport"].Integer() = ui->portEdit->text().toInt();
|
||||
node["uuid"].String() = args[0].toStdString();*/
|
||||
startGame = true;
|
||||
gameArgs << "--lobby";
|
||||
gameArgs << "--lobby-address" << ui->hostEdit->text();
|
||||
gameArgs << "--lobby-port" << ui->portEdit->text();
|
||||
gameArgs << "--uuid" << args[0];
|
||||
qobject_cast<MainWindow *>(qApp->activeWindow())->startGame(gameArgs);
|
||||
//on_startGameButton_clicked
|
||||
//node["names"].Vector().clear();
|
||||
//node["names"].Vector().pushBack(username.toStdString());
|
||||
@ -229,9 +227,9 @@ void Lobby::serverCommand(const ServerCommand & command) try
|
||||
|
||||
case HOST: {
|
||||
protocolAssert(args.size() == 2);
|
||||
Settings node = settings.write["server"]["host"];
|
||||
node["uuid"].String() = args[0].toStdString();
|
||||
node["connections"].Integer() = args[1].toInt();
|
||||
gameArgs << "--lobby-host";
|
||||
gameArgs << "--lobby-uuid" << args[0];
|
||||
gameArgs << "--lobby-connections" << args[1];
|
||||
break;
|
||||
}
|
||||
|
||||
@ -267,9 +265,6 @@ void Lobby::dispatchMessage(QString txt) try
|
||||
ServerCommand cmd(ctype, parseArgs);
|
||||
serverCommand(cmd);
|
||||
}
|
||||
|
||||
if(startGame)
|
||||
qobject_cast<MainWindow *>(qApp->activeWindow())->startGame(gameArguments);
|
||||
}
|
||||
catch(const ProtocolError & e)
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ private:
|
||||
QString session;
|
||||
QString username;
|
||||
bool startGame = false;
|
||||
QStringList gameArguments;
|
||||
QStringList gameArgs;
|
||||
|
||||
private:
|
||||
void protocolAssert(bool);
|
||||
|
@ -122,8 +122,10 @@ void MainWindow::startGame(const QStringList & args)
|
||||
const char * s = args[i].toLocal8Bit().constData();
|
||||
__argv[i] = new char[strlen(s)];
|
||||
strcpy(__argv[i], s);
|
||||
|
||||
}
|
||||
|
||||
logGlobal->warn("Starting game with the arguments: %s", args.join(" ").toStdString());
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
qApp->quit();
|
||||
#else
|
||||
|
@ -59,7 +59,7 @@ class Session:
|
||||
protected = False # if True, password is required to join to the session
|
||||
name: str # name of session
|
||||
host: socket # player socket who created the session (lobby mode)
|
||||
host_uuid: str # uuid of vcmiserver for hosting player
|
||||
token: str # uuid of vcmiserver for hosting player
|
||||
players = [] # list of sockets of players, joined to the session
|
||||
connections = [] # list of GameConnections for vcmiclient (game mode)
|
||||
started = False # True - game mode, False - lobby mode
|
||||
@ -216,16 +216,21 @@ def dispatch(client: socket, sender: dict, arr: bytes):
|
||||
if arr == None or len(arr) == 0:
|
||||
return
|
||||
|
||||
print(f"[{sender['address']}] dispatching message")
|
||||
|
||||
#check for game mode connection
|
||||
msg = str(arr)
|
||||
if msg.find("Aiya!") != -1:
|
||||
sender["pipe"] = True #switch to pipe mode
|
||||
print(" vcmi recognized")
|
||||
|
||||
if sender["pipe"]:
|
||||
if sender["game"]: #if already playing - sending raw bytes as is
|
||||
sender["prevmessages"].append(arr)
|
||||
print(" storing message")
|
||||
else:
|
||||
sender["prevmessages"].append(struct.pack('<I', len(arr)) + arr) #pack message
|
||||
print(" packing message")
|
||||
#search fo application type in the message
|
||||
match = re.search(r"\((\w+)\)", msg)
|
||||
_appType = ''
|
||||
@ -235,12 +240,14 @@ def dispatch(client: socket, sender: dict, arr: bytes):
|
||||
|
||||
#extract uuid from message
|
||||
_uuid = arr.decode()
|
||||
print(f" decoding {_uuid}")
|
||||
if not _uuid == '' and not sender["apptype"] == '':
|
||||
#search for uuid
|
||||
for session in sessions.values():
|
||||
if session.started:
|
||||
#verify uuid of connected application
|
||||
if _uuid.find(session.host_uuid) != -1 and sender["apptype"] == "server":
|
||||
print(f" apptype {sender['apptype']} uuid {_uuid}")
|
||||
session.addConnection(client, True)
|
||||
sender["session"] = session
|
||||
sender["game"] = True
|
||||
@ -248,11 +255,13 @@ def dispatch(client: socket, sender: dict, arr: bytes):
|
||||
# this is workaround to send only one remaining byte
|
||||
# WARNING: reversed byte order is not supported
|
||||
sender["prevmessages"].append(client.recv(1))
|
||||
print(f" binding server connection to session {session.name}")
|
||||
return
|
||||
|
||||
if sender["apptype"] == "client":
|
||||
for p in session.players:
|
||||
if _uuid.find(client_sockets[p]["uuid"]) != -1:
|
||||
print(f" apptype {sender['apptype']} uuid {_uuid}")
|
||||
#client connection
|
||||
session.addConnection(client, False)
|
||||
sender["session"] = session
|
||||
@ -261,10 +270,12 @@ def dispatch(client: socket, sender: dict, arr: bytes):
|
||||
# this is workaround to send only one remaining byte
|
||||
# WARNING: reversed byte order is not supported
|
||||
sender["prevmessages"].append(client.recv(1))
|
||||
print(f" binding client connection to session {session.name}")
|
||||
break
|
||||
|
||||
#game mode
|
||||
if sender["pipe"] and sender["game"] and sender["session"].validPipe(client):
|
||||
print(f" pipe for {sender['session'].name}")
|
||||
#send messages from queue
|
||||
opposite = sender["session"].getPipe(client)
|
||||
for x in client_sockets[opposite]["prevmessages"]:
|
||||
@ -283,6 +294,7 @@ def dispatch(client: socket, sender: dict, arr: bytes):
|
||||
|
||||
#we are in pipe mode but game still not started - waiting other clients to connect
|
||||
if sender["pipe"]:
|
||||
print(f" waiting other clients")
|
||||
return
|
||||
|
||||
#lobby mode
|
||||
|
@ -170,11 +170,9 @@ void CVCMIServer::run()
|
||||
#endif
|
||||
|
||||
startAsyncAccept();
|
||||
if(!remoteConnectionsThread && !settings["server"]["lobby"].isNull() && settings["server"]["lobby"].Bool())
|
||||
if(!remoteConnectionsThread && cmdLineOptions.count("lobby"))
|
||||
{
|
||||
remoteConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::establishRemoteConnections, this);
|
||||
Settings node = settings.write["server"]["lobby"];
|
||||
node->Bool() = false;
|
||||
}
|
||||
|
||||
#if defined(VCMI_ANDROID)
|
||||
@ -203,10 +201,10 @@ void CVCMIServer::run()
|
||||
|
||||
void CVCMIServer::establishRemoteConnections()
|
||||
{
|
||||
uuid = settings["server"]["host"]["uuid"].String();
|
||||
int numOfConnections = settings["server"]["host"]["connections"].Integer();
|
||||
auto address = settings["server"]["server"].String();
|
||||
int port = settings["server"]["serverport"].Integer();
|
||||
uuid = cmdLineOptions["lobby-uuid"].as<std::string>();
|
||||
int numOfConnections = cmdLineOptions["connections"].as<ui8>();
|
||||
auto address = cmdLineOptions["lobby"].as<std::string>();
|
||||
int port = cmdLineOptions["lobby-port"].as<ui16>();
|
||||
|
||||
for(int i = 0; i < numOfConnections; ++i)
|
||||
connectToRemote(address, port);
|
||||
@ -1001,7 +999,11 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
|
||||
("uuid", po::value<std::string>(), "")
|
||||
("enable-shm-uuid", "use UUID for shared memory identifier")
|
||||
("enable-shm", "enable usage of shared memory")
|
||||
("port", po::value<ui16>(), "port at which server will listen to connections from client");
|
||||
("port", po::value<ui16>(), "port at which server will listen to connections from client")
|
||||
("lobby", po::value<std::string>(), "address to remote lobby")
|
||||
("lobby-port", po::value<ui16>(), "port at which server connect to remote lobby")
|
||||
("lobby-uuid", po::value<std::string>(), "")
|
||||
("connections", po::value<ui8>(), "amount of connections to remote lobby");
|
||||
|
||||
if(argc > 1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user