Changeset View
Changeset View
Standalone View
Standalone View
source/network/scripting/JSInterface_Network.cpp
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName) | ||||
ENSURE(!g_NetClient); | ENSURE(!g_NetClient); | ||||
ENSURE(!g_NetServer); | ENSURE(!g_NetServer); | ||||
ENSURE(!g_Game); | ENSURE(!g_Game); | ||||
// Always use lobby authentication for lobby matches to prevent impersonation and smurfing, in particular through mods that implemented an UI for arbitrary or other players nicknames. | // Always use lobby authentication for lobby matches to prevent impersonation and smurfing, in particular through mods that implemented an UI for arbitrary or other players nicknames. | ||||
g_NetServer = new CNetServer(static_cast<bool>(g_XmppClient)); | g_NetServer = new CNetServer(static_cast<bool>(g_XmppClient)); | ||||
if (!g_NetServer->SetupConnection(serverPort)) | if (!g_NetServer->SetupConnection(serverPort)) | ||||
{ | { | ||||
pCmptPrivate->pScriptInterface->ReportError("Failed to start server"); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
ScriptException::Raise(rq, "Failed to start server"); | |||||
SAFE_DELETE(g_NetServer); | SAFE_DELETE(g_NetServer); | ||||
return; | return; | ||||
} | } | ||||
g_Game = new CGame(true); | g_Game = new CGame(true); | ||||
g_NetClient = new CNetClient(g_Game, true); | g_NetClient = new CNetClient(g_Game, true); | ||||
g_NetClient->SetUserName(playerName); | g_NetClient->SetUserName(playerName); | ||||
g_NetClient->SetHostingPlayerName(hostLobbyName); | g_NetClient->SetHostingPlayerName(hostLobbyName); | ||||
if (!g_NetClient->SetupConnection("127.0.0.1", serverPort, nullptr)) | if (!g_NetClient->SetupConnection("127.0.0.1", serverPort, nullptr)) | ||||
{ | { | ||||
pCmptPrivate->pScriptInterface->ReportError("Failed to connect to server"); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
ScriptException::Raise(rq, "Failed to connect to server"); | |||||
SAFE_DELETE(g_NetClient); | SAFE_DELETE(g_NetClient); | ||||
SAFE_DELETE(g_Game); | SAFE_DELETE(g_Game); | ||||
} | } | ||||
} | } | ||||
void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID) | void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID) | ||||
{ | { | ||||
ENSURE(!g_NetClient); | ENSURE(!g_NetClient); | ||||
Show All 10 Lines | for (int i = 0; i < 5 && !enetClient; ++i) | ||||
u16 port = 1024 + rand() % (UINT16_MAX - 1024); | u16 port = 1024 + rand() % (UINT16_MAX - 1024); | ||||
ENetAddress hostAddr{ENET_HOST_ANY, port}; | ENetAddress hostAddr{ENET_HOST_ANY, port}; | ||||
enetClient = enet_host_create(&hostAddr, 1, 1, 0, 0); | enetClient = enet_host_create(&hostAddr, 1, 1, 0, 0); | ||||
++hostAddr.port; | ++hostAddr.port; | ||||
} | } | ||||
if (!enetClient) | if (!enetClient) | ||||
{ | { | ||||
pCmptPrivate->pScriptInterface->ReportError("Could not find an unused port for the enet STUN client"); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
ScriptException::Raise(rq, "Could not find an unused port for the enet STUN client"); | |||||
return; | return; | ||||
} | } | ||||
StunClient::StunEndpoint stunEndpoint; | StunClient::StunEndpoint stunEndpoint; | ||||
if (!StunClient::FindStunEndpointJoin(*enetClient, stunEndpoint)) | if (!StunClient::FindStunEndpointJoin(*enetClient, stunEndpoint)) | ||||
{ | { | ||||
pCmptPrivate->pScriptInterface->ReportError("Could not find the STUN endpoint"); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
ScriptException::Raise(rq, "Could not find the STUN endpoint"); | |||||
return; | return; | ||||
} | } | ||||
g_XmppClient->SendStunEndpointToHost(stunEndpoint, hostJID); | g_XmppClient->SendStunEndpointToHost(stunEndpoint, hostJID); | ||||
SDL_Delay(1000); | SDL_Delay(1000); | ||||
} | } | ||||
g_Game = new CGame(true); | g_Game = new CGame(true); | ||||
g_NetClient = new CNetClient(g_Game, false); | g_NetClient = new CNetClient(g_Game, false); | ||||
g_NetClient->SetUserName(playerName); | g_NetClient->SetUserName(playerName); | ||||
g_NetClient->SetHostingPlayerName(hostJID.substr(0, hostJID.find("@"))); | g_NetClient->SetHostingPlayerName(hostJID.substr(0, hostJID.find("@"))); | ||||
if (g_XmppClient && useSTUN) | if (g_XmppClient && useSTUN) | ||||
StunClient::SendHolePunchingMessages(*enetClient, serverAddress, serverPort); | StunClient::SendHolePunchingMessages(*enetClient, serverAddress, serverPort); | ||||
if (!g_NetClient->SetupConnection(serverAddress, serverPort, enetClient)) | if (!g_NetClient->SetupConnection(serverAddress, serverPort, enetClient)) | ||||
{ | { | ||||
pCmptPrivate->pScriptInterface->ReportError("Failed to connect to server"); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
ScriptException::Raise(rq, "Failed to connect to server"); | |||||
SAFE_DELETE(g_NetClient); | SAFE_DELETE(g_NetClient); | ||||
SAFE_DELETE(g_Game); | SAFE_DELETE(g_Game); | ||||
} | } | ||||
} | } | ||||
void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) | void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) | ||||
{ | { | ||||
// TODO: we ought to do async reliable disconnections | // TODO: we ought to do async reliable disconnections | ||||
Show All 12 Lines | |||||
} | } | ||||
JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate) | JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate) | ||||
{ | { | ||||
if (!g_NetClient) | if (!g_NetClient) | ||||
return JS::UndefinedValue(); | return JS::UndefinedValue(); | ||||
// Convert from net client context to GUI script context | // Convert from net client context to GUI script context | ||||
ScriptInterface::Request rqNet(g_NetClient->GetScriptInterface()); | ScriptRequest rqNet(g_NetClient->GetScriptInterface()); | ||||
JS::RootedValue pollNet(rqNet.cx); | JS::RootedValue pollNet(rqNet.cx); | ||||
g_NetClient->GuiPoll(&pollNet); | g_NetClient->GuiPoll(&pollNet); | ||||
return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet); | return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet); | ||||
} | } | ||||
void JSI_Network::SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1) | void JSI_Network::SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1) | ||||
{ | { | ||||
ENSURE(g_NetClient); | ENSURE(g_NetClient); | ||||
// TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason). | // TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason). | ||||
ScriptInterface::Request rq(pCmptPrivate); | ScriptRequest rq(pCmptPrivate->pScriptInterface); | ||||
JS::RootedValue attribs(rq.cx, attribs1); | JS::RootedValue attribs(rq.cx, attribs1); | ||||
g_NetClient->SendGameSetupMessage(&attribs, *(pCmptPrivate->pScriptInterface)); | g_NetClient->SendGameSetupMessage(&attribs, *(pCmptPrivate->pScriptInterface)); | ||||
} | } | ||||
void JSI_Network::AssignNetworkPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int playerID, const CStr& guid) | void JSI_Network::AssignNetworkPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int playerID, const CStr& guid) | ||||
{ | { | ||||
ENSURE(g_NetClient); | ENSURE(g_NetClient); | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator