Index: ps/trunk/source/network/scripting/JSInterface_Network.cpp
===================================================================
--- ps/trunk/source/network/scripting/JSInterface_Network.cpp (revision 20176)
+++ ps/trunk/source/network/scripting/JSInterface_Network.cpp (revision 20177)
@@ -1,230 +1,229 @@
/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "network/scripting/JSInterface_Network.h"
#include "lib/external_libraries/enet.h"
#include "lib/external_libraries/libsdl.h"
#include "lobby/IXmppClient.h"
#include "network/NetClient.h"
#include "network/NetMessage.h"
#include "network/NetServer.h"
#include "network/StunClient.h"
#include "ps/CLogger.h"
-#include "ps/CStr.h"
#include "ps/Game.h"
u16 JSI_Network::GetDefaultPort(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
{
return PS_DEFAULT_PORT;
}
JS::Value JSI_Network::FindStunEndpoint(ScriptInterface::CxPrivate* pCxPrivate, int port)
{
return StunClient::FindStunEndpointHost(*(pCxPrivate->pScriptInterface), port);
}
void JSI_Network::StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort)
{
ENSURE(!g_NetClient);
ENSURE(!g_NetServer);
ENSURE(!g_Game);
g_NetServer = new CNetServer();
if (!g_NetServer->SetupConnection(serverPort))
{
pCxPrivate->pScriptInterface->ReportError("Failed to start server");
SAFE_DELETE(g_NetServer);
return;
}
g_Game = new CGame();
g_NetClient = new CNetClient(g_Game, true);
g_NetClient->SetUserName(playerName);
if (!g_NetClient->SetupConnection("127.0.0.1", serverPort))
{
pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
SAFE_DELETE(g_NetClient);
SAFE_DELETE(g_Game);
}
}
void JSI_Network::StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID)
{
ENSURE(!g_NetClient);
ENSURE(!g_NetServer);
ENSURE(!g_Game);
ENetHost* enetClient = nullptr;
if (g_XmppClient && useSTUN)
{
// Find an unused port
for (int i = 0; i < 5 && !enetClient; ++i)
{
// Ports below 1024 are privileged on unix
u16 port = 1024 + rand() % (UINT16_MAX - 1024);
ENetAddress hostAddr{ENET_HOST_ANY, port};
enetClient = enet_host_create(&hostAddr, 1, 1, 0, 0);
++hostAddr.port;
}
if (!enetClient)
{
pCxPrivate->pScriptInterface->ReportError("Could not find an unused port for the enet STUN client");
return;
}
StunClient::StunEndpoint* stunEndpoint = StunClient::FindStunEndpointJoin(enetClient);
if (!stunEndpoint)
{
pCxPrivate->pScriptInterface->ReportError("Could not find the STUN endpoint");
return;
}
g_XmppClient->SendStunEndpointToHost(stunEndpoint, hostJID);
delete stunEndpoint;
SDL_Delay(1000);
}
g_Game = new CGame();
g_NetClient = new CNetClient(g_Game, false);
g_NetClient->SetUserName(playerName);
if (g_XmppClient && useSTUN)
StunClient::SendHolePunchingMessages(enetClient, serverAddress.c_str(), serverPort);
if (!g_NetClient->SetupConnection(serverAddress, serverPort, enetClient))
{
pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
SAFE_DELETE(g_NetClient);
SAFE_DELETE(g_Game);
}
}
void JSI_Network::DisconnectNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
{
// TODO: we ought to do async reliable disconnections
SAFE_DELETE(g_NetServer);
SAFE_DELETE(g_NetClient);
SAFE_DELETE(g_Game);
}
CStr JSI_Network::GetPlayerGUID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
{
if (!g_NetClient)
return "local";
return g_NetClient->GetGUID();
}
JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate)
{
if (!g_NetClient)
return JS::UndefinedValue();
// Convert from net client context to GUI script context
JSContext* cxNet = g_NetClient->GetScriptInterface().GetContext();
JSAutoRequest rqNet(cxNet);
JS::RootedValue pollNet(cxNet);
g_NetClient->GuiPoll(&pollNet);
return pCxPrivate->pScriptInterface->CloneValueFromOtherContext(g_NetClient->GetScriptInterface(), pollNet);
}
void JSI_Network::SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1)
{
ENSURE(g_NetClient);
// TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason).
JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
JSAutoRequest rq(cx);
JS::RootedValue attribs(cx, attribs1);
g_NetClient->SendGameSetupMessage(&attribs, *(pCxPrivate->pScriptInterface));
}
void JSI_Network::AssignNetworkPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int playerID, const CStr& guid)
{
ENSURE(g_NetClient);
g_NetClient->SendAssignPlayerMessage(playerID, guid);
}
void JSI_Network::KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& playerName, bool ban)
{
ENSURE(g_NetClient);
g_NetClient->SendKickPlayerMessage(playerName, ban);
}
void JSI_Network::SendNetworkChat(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& message)
{
ENSURE(g_NetClient);
g_NetClient->SendChatMessage(message);
}
void JSI_Network::SendNetworkReady(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int message)
{
ENSURE(g_NetClient);
g_NetClient->SendReadyMessage(message);
}
void JSI_Network::ClearAllPlayerReady (ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
{
ENSURE(g_NetClient);
g_NetClient->SendClearAllReadyMessage();
}
void JSI_Network::StartNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
{
ENSURE(g_NetClient);
g_NetClient->SendStartGameMessage();
}
void JSI_Network::SetTurnLength(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int length)
{
if (g_NetServer)
g_NetServer->SetTurnLength(length);
else
LOGERROR("Only network host can change turn length");
}
void JSI_Network::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
{
scriptInterface.RegisterFunction("GetDefaultPort");
scriptInterface.RegisterFunction("FindStunEndpoint");
scriptInterface.RegisterFunction("StartNetworkHost");
scriptInterface.RegisterFunction("StartNetworkJoin");
scriptInterface.RegisterFunction("DisconnectNetworkGame");
scriptInterface.RegisterFunction("GetPlayerGUID");
scriptInterface.RegisterFunction("PollNetworkClient");
scriptInterface.RegisterFunction("SetNetworkGameAttributes");
scriptInterface.RegisterFunction("AssignNetworkPlayer");
scriptInterface.RegisterFunction("KickPlayer");
scriptInterface.RegisterFunction("SendNetworkChat");
scriptInterface.RegisterFunction("SendNetworkReady");
scriptInterface.RegisterFunction("ClearAllPlayerReady");
scriptInterface.RegisterFunction("StartNetworkGame");
scriptInterface.RegisterFunction("SetTurnLength");
}
Index: ps/trunk/source/network/scripting/JSInterface_Network.h
===================================================================
--- ps/trunk/source/network/scripting/JSInterface_Network.h (revision 20176)
+++ ps/trunk/source/network/scripting/JSInterface_Network.h (revision 20177)
@@ -1,44 +1,45 @@
/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#ifndef INCLUDED_JSI_NETWORK
#define INCLUDED_JSI_NETWORK
+#include "ps/CStr.h"
#include "scriptinterface/ScriptInterface.h"
namespace JSI_Network
{
u16 GetDefaultPort(ScriptInterface::CxPrivate* pCxPrivate);
void StartNetworkGame(ScriptInterface::CxPrivate* pCxPrivate);
void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1);
void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort);
void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID);
JS::Value FindStunEndpoint(ScriptInterface::CxPrivate* pCxPrivate, int port);
void DisconnectNetworkGame(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate);
CStr GetPlayerGUID(ScriptInterface::CxPrivate* pCxPrivate);
void KickPlayer(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, bool ban);
void AssignNetworkPlayer(ScriptInterface::CxPrivate* pCxPrivate, int playerID, const CStr& guid);
void ClearAllPlayerReady (ScriptInterface::CxPrivate* pCxPrivate);
void SendNetworkChat(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& message);
void SendNetworkReady(ScriptInterface::CxPrivate* pCxPrivate, int message);
void SetTurnLength(ScriptInterface::CxPrivate* pCxPrivate, int length);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
}
#endif