Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6916cfd0de | ||
|
|
bae92c6c95 | ||
|
|
c8de19a3b6 | ||
|
|
1da8f371aa | ||
|
|
cb55a02599 | ||
|
|
dc820bdbf6 | ||
|
|
106960cbb5 | ||
|
|
3c92a79fe2 | ||
|
|
2c2f275c3d | ||
|
|
156940cc5b | ||
|
|
a835cf43a5 | ||
|
|
18b704b85a | ||
|
|
cd4adae22b | ||
|
|
ef59e2858b | ||
|
|
218c0d7385 | ||
|
|
e7f03cfa93 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+9
-4
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||||
xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension">
|
xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension"
|
||||||
|
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||||
<Product Id="*" Name="Moonlight Internet Streaming Helper" Language="1033" Version="!(bind.fileVersion.MistExe)"
|
<Product Id="*" Name="Moonlight Internet Streaming Helper" Language="1033" Version="!(bind.fileVersion.MistExe)"
|
||||||
Manufacturer="Moonlight Game Streaming Project" UpgradeCode="cfc2fb53-88e2-4867-851d-9ed9fe7ab2a3">
|
Manufacturer="Moonlight Game Streaming Project" UpgradeCode="cfc2fb53-88e2-4867-851d-9ed9fe7ab2a3">
|
||||||
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />
|
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />
|
||||||
@@ -38,16 +39,20 @@
|
|||||||
Scope="any"
|
Scope="any"
|
||||||
Name="Moonlight Internet Streaming Service"/>
|
Name="Moonlight Internet Streaming Service"/>
|
||||||
</File>
|
</File>
|
||||||
<CreateFolder Directory="MISSLogFolder" />
|
<CreateFolder Directory="MISSLogFolder">
|
||||||
|
<util:PermissionEx User="NT SERVICE\MISS" GenericAll="yes" />
|
||||||
|
</CreateFolder>
|
||||||
<ServiceInstall Type="ownProcess"
|
<ServiceInstall Type="ownProcess"
|
||||||
Name="MISS"
|
Name="MISS"
|
||||||
DisplayName="Moonlight Internet Streaming Service"
|
DisplayName="Moonlight Internet Streaming Service"
|
||||||
Description="Automatically manages router port forwarding rules required to use Moonlight over the Internet"
|
Description="Automatically manages router port forwarding rules required to use Moonlight over the Internet"
|
||||||
Start="auto"
|
Start="auto"
|
||||||
Account="LocalSystem"
|
Account="NT AUTHORITY\LocalService"
|
||||||
ErrorControl="ignore"
|
ErrorControl="ignore"
|
||||||
Interactive="no">
|
Interactive="no">
|
||||||
<ServiceConfig DelayedAutoStart="no" OnInstall="yes" OnReinstall="yes" />
|
<ServiceConfig DelayedAutoStart="no" OnInstall="yes" OnReinstall="yes" ServiceSid="restricted">
|
||||||
|
<RequiredPrivilege>SeChangeNotifyPrivilege</RequiredPrivilege>
|
||||||
|
</ServiceConfig>
|
||||||
</ServiceInstall>
|
</ServiceInstall>
|
||||||
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="MISS" Wait="yes" />
|
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="MISS" Wait="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|||||||
@@ -48,6 +48,10 @@
|
|||||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||||
<Name>WixUIExtension</Name>
|
<Name>WixUIExtension</Name>
|
||||||
</WixExtension>
|
</WixExtension>
|
||||||
|
<WixExtension Include="WixUtilExtension">
|
||||||
|
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
|
||||||
|
<Name>WixUtilExtension</Name>
|
||||||
|
</WixExtension>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
||||||
|
|||||||
@@ -244,6 +244,10 @@ bool PCPMapPort(PSOCKADDR_STORAGE localAddr, int localAddrLen, PSOCKADDR_STORAGE
|
|||||||
printf("PCP message truncated: %d\n", bytesRead);
|
printf("PCP message truncated: %d\n", bytesRead);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
else if (resp.hdr.hdr.version != PCP_VERSION) {
|
||||||
|
printf("PCP version mismatch: %x\n", resp.hdr.hdr.version);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
else if (resp.hdr.hdr.opcode != OPCODE_MAP_RESPONSE) {
|
else if (resp.hdr.hdr.opcode != OPCODE_MAP_RESPONSE) {
|
||||||
printf("PCP message type mismatch: %x\n", resp.hdr.hdr.opcode);
|
printf("PCP message type mismatch: %x\n", resp.hdr.hdr.opcode);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|||||||
+83
-28
@@ -22,6 +22,55 @@ static const char* k_SsdpSearchFormatString =
|
|||||||
"MX: 5\r\n"
|
"MX: 5\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
// Based on logic in https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/minissdpc.c
|
||||||
|
static void
|
||||||
|
parseReply(const char* reply, int size,
|
||||||
|
const char** location, int *locationsize,
|
||||||
|
const char** st, int* stsize,
|
||||||
|
const char** usn, int* usnsize)
|
||||||
|
{
|
||||||
|
int lineStartIdx = 0;
|
||||||
|
int headerEndIdx = 0;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
switch (reply[i])
|
||||||
|
{
|
||||||
|
case ':':
|
||||||
|
// Stop parsing the header at the first colon, but ignore subsequent colons
|
||||||
|
if (headerEndIdx == 0) {
|
||||||
|
headerEndIdx = i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
if (headerEndIdx != 0) {
|
||||||
|
// Skip the colon and spaces
|
||||||
|
do { headerEndIdx++; } while (reply[headerEndIdx] == ' ');
|
||||||
|
|
||||||
|
// Check if it's one of the values we care about
|
||||||
|
if (!_strnicmp(reply + lineStartIdx, "location:", 9)) {
|
||||||
|
*location = reply + headerEndIdx;
|
||||||
|
*locationsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
else if (!_strnicmp(reply + lineStartIdx, "st:", 3)) {
|
||||||
|
*st = reply + headerEndIdx;
|
||||||
|
*stsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
else if (!_strnicmp(reply + lineStartIdx, "usn:", 4)) {
|
||||||
|
*usn = reply + headerEndIdx;
|
||||||
|
*usnsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move on to the next header value
|
||||||
|
headerEndIdx = 0;
|
||||||
|
}
|
||||||
|
lineStartIdx = i + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
||||||
{
|
{
|
||||||
SOCKET s;
|
SOCKET s;
|
||||||
@@ -47,6 +96,13 @@ struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We will be reading all responses at the end, so ensure we have ample buffer space
|
||||||
|
// to allow responses to accumulate without loss.
|
||||||
|
int recvBufferSize = 65535;
|
||||||
|
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&recvBufferSize, sizeof(recvBufferSize)) == SOCKET_ERROR) {
|
||||||
|
printf("setsockopt() failed: %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
// Send the first search message with HOST set properly
|
// Send the first search message with HOST set properly
|
||||||
chars = snprintf(searchBuffer, ARRAYSIZE(searchBuffer), k_SsdpSearchFormatString, inet_ntoa(address));
|
chars = snprintf(searchBuffer, ARRAYSIZE(searchBuffer), k_SsdpSearchFormatString, inet_ntoa(address));
|
||||||
if (send(s, searchBuffer, chars, 0) == SOCKET_ERROR) {
|
if (send(s, searchBuffer, chars, 0) == SOCKET_ERROR) {
|
||||||
@@ -115,38 +171,37 @@ struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the header options
|
// Parse the header options
|
||||||
// SERVER: FreeBSD/11.2-RELEASE-p2 UPnP/1.1 MiniUPnPd/2.0\r\n
|
char* remainder = strtok(nullptr, "");
|
||||||
char* location = nullptr;
|
const char* loc = nullptr;
|
||||||
char* st = nullptr;
|
const char* st = nullptr;
|
||||||
while (char* headerName = strtok(nullptr, "\r\n:")) {
|
const char* usn = ""; // Initialize to empty since it's optional
|
||||||
char* headerValue = strtok(nullptr, "\r");
|
int locSize = 0;
|
||||||
if (headerValue == nullptr) {
|
int stSize = 0;
|
||||||
printf("Unexpected end of SSDP header\n");
|
int usnSize = 0;
|
||||||
break;
|
parseReply(remainder, strlen(remainder),
|
||||||
}
|
&loc, &locSize, &st, &stSize, &usn, &usnSize);
|
||||||
|
|
||||||
// Skip leading spaces
|
if (!loc || locSize == 0 || !st || stSize == 0) {
|
||||||
while (*headerValue == ' ') headerValue++;
|
printf("Required value missing: %d %d\n", locSize, stSize);
|
||||||
|
|
||||||
if (!_stricmp(headerName, "LOCATION")) {
|
|
||||||
location = headerValue;
|
|
||||||
}
|
|
||||||
else if (!_stricmp(headerName, "ST")) {
|
|
||||||
st = headerValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!location || location[0] == 0 || !st || st[0] == 0) {
|
|
||||||
printf("Required value missing: \"%s\" \"%s\"\n", location, st);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UPNPDev* newDev = (struct UPNPDev*)malloc(sizeof(*newDev) + strlen(location) + strlen(st) + 2);
|
struct UPNPDev* newDev = (struct UPNPDev*)malloc(sizeof(*newDev) + usnSize + locSize + stSize + 3);
|
||||||
|
|
||||||
newDev->pNext = deviceList;
|
newDev->pNext = deviceList;
|
||||||
newDev->usn = &newDev->buffer[0]; newDev->buffer[0] = 0;
|
|
||||||
newDev->descURL = strcpy(newDev->usn + strlen(newDev->usn) + 1, location);
|
newDev->usn = &newDev->buffer[0];
|
||||||
newDev->st = strcpy(newDev->descURL + strlen(newDev->descURL) + 1, st);
|
memcpy(newDev->usn, usn, usnSize);
|
||||||
|
newDev->usn[usnSize] = 0;
|
||||||
|
|
||||||
|
newDev->descURL = newDev->usn + usnSize + 1;
|
||||||
|
memcpy(newDev->descURL, loc, locSize);
|
||||||
|
newDev->descURL[locSize] = 0;
|
||||||
|
|
||||||
|
newDev->st = newDev->descURL + locSize + 1;
|
||||||
|
memcpy(newDev->st, st, stSize);
|
||||||
|
newDev->st[stSize] = 0;
|
||||||
|
|
||||||
newDev->scope_id = 0; // IPv6 only
|
newDev->scope_id = 0; // IPv6 only
|
||||||
|
|
||||||
deviceList = newDev;
|
deviceList = newDev;
|
||||||
@@ -170,7 +225,7 @@ bool getHopsIP4(IN_ADDR* hopAddress, int* hopAddressCount)
|
|||||||
char replyBuffer[128];
|
char replyBuffer[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
host = gethostbyname("google.com");
|
host = gethostbyname("moonlight-stream.org");
|
||||||
if (host == nullptr) {
|
if (host == nullptr) {
|
||||||
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+58
-36
@@ -52,7 +52,20 @@ enum MessagePriority {
|
|||||||
MpError
|
MpError
|
||||||
};
|
};
|
||||||
|
|
||||||
void DisplayMessage(const char* message, MessagePriority priority = MpError, bool terminal = true)
|
VOID CALLBACK MsgBoxHelpCallback(LPHELPINFO lpHelpInfo)
|
||||||
|
{
|
||||||
|
const char* helpUrl = (const char*)lpHelpInfo->dwContextId;
|
||||||
|
|
||||||
|
if (!helpUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's recommended to initialize COM before calling ShellExecute()
|
||||||
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||||
|
ShellExecuteA(nullptr, "open", helpUrl, nullptr, nullptr, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayMessage(const char* message, const char* helpUrl = nullptr, MessagePriority priority = MpError, bool terminal = true)
|
||||||
{
|
{
|
||||||
printf("%s\n", message);
|
printf("%s\n", message);
|
||||||
|
|
||||||
@@ -77,23 +90,34 @@ void DisplayMessage(const char* message, MessagePriority priority = MpError, boo
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSGBOXPARAMSA msgParams;
|
||||||
DWORD flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND;
|
msgParams.cbSize = sizeof(msgParams);
|
||||||
|
msgParams.hwndOwner = nullptr;
|
||||||
|
msgParams.hInstance = nullptr;
|
||||||
|
msgParams.lpszText = message;
|
||||||
|
msgParams.lpszCaption = "Moonlight Internet Streaming Tester";
|
||||||
|
msgParams.dwStyle = MB_OK | MB_TOPMOST | MB_SETFOREGROUND;
|
||||||
|
if (helpUrl) {
|
||||||
|
msgParams.dwStyle |= MB_HELP;
|
||||||
|
}
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
case MpInfo:
|
case MpInfo:
|
||||||
flags |= MB_ICONINFORMATION;
|
msgParams.dwStyle |= MB_ICONINFORMATION;
|
||||||
break;
|
break;
|
||||||
case MpWarn:
|
case MpWarn:
|
||||||
flags |= MB_ICONWARNING;
|
msgParams.dwStyle |= MB_ICONWARNING;
|
||||||
break;
|
break;
|
||||||
case MpError:
|
case MpError:
|
||||||
flags |= MB_ICONERROR;
|
msgParams.dwStyle |= MB_ICONERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
MessageBoxA(nullptr, message, "Moonlight Internet Streaming Tester", flags);
|
msgParams.lpfnMsgBoxCallback = MsgBoxHelpCallback;
|
||||||
|
msgParams.dwContextHelpId = (DWORD_PTR)helpUrl;
|
||||||
|
msgParams.dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
||||||
|
MessageBoxIndirectA(&msgParams);
|
||||||
|
|
||||||
if (priority != MpInfo && terminal) {
|
if (priority != MpInfo && terminal) {
|
||||||
flags = MB_YESNO | MB_TOPMOST | MB_SETFOREGROUND | MB_ICONINFORMATION;
|
UINT flags = MB_YESNO | MB_TOPMOST | MB_SETFOREGROUND | MB_ICONINFORMATION;
|
||||||
switch (MessageBoxA(nullptr, "Would you like to view the troubleshooting log?",
|
switch (MessageBoxA(nullptr, "Would you like to view the troubleshooting log?",
|
||||||
"Moonlight Internet Streaming Tester", flags))
|
"Moonlight Internet Streaming Tester", flags))
|
||||||
{
|
{
|
||||||
@@ -116,7 +140,8 @@ bool IsGameStreamEnabled()
|
|||||||
error = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\NVIDIA Corporation\\NvStream", 0, KEY_READ | KEY_WOW64_64KEY, &key);
|
error = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\NVIDIA Corporation\\NvStream", 0, KEY_READ | KEY_WOW64_64KEY, &key);
|
||||||
if (error != ERROR_SUCCESS) {
|
if (error != ERROR_SUCCESS) {
|
||||||
printf("RegOpenKeyEx() failed: %d\n", error);
|
printf("RegOpenKeyEx() failed: %d\n", error);
|
||||||
DisplayMessage("GeForce Experience was not detected on this PC. Make sure you're installing this utility on your GeForce GameStream-compatible PC, not the device running Moonlight.");
|
DisplayMessage("GeForce Experience was not detected on this PC. Make sure you're installing this utility on your GeForce GameStream-compatible PC, not the device running Moonlight.",
|
||||||
|
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +153,8 @@ bool IsGameStreamEnabled()
|
|||||||
if (error != ERROR_SUCCESS) {
|
if (error != ERROR_SUCCESS) {
|
||||||
printf("RegQueryValueExA() failed: %d\n", error);
|
printf("RegQueryValueExA() failed: %d\n", error);
|
||||||
}
|
}
|
||||||
DisplayMessage("GameStream is not enabled in GeForce Experience. Please open GeForce Experience settings, navigate to the Shield tab, and turn GameStream on.");
|
DisplayMessage("GameStream is not enabled in GeForce Experience. Please open GeForce Experience settings, navigate to the Shield tab, and turn GameStream on.",
|
||||||
|
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -324,7 +350,7 @@ bool FindLocalInterfaceIP4Address(PSOCKADDR_IN addr)
|
|||||||
|
|
||||||
printf("Finding local IP address...");
|
printf("Finding local IP address...");
|
||||||
|
|
||||||
host = gethostbyname("google.com");
|
host = gethostbyname("moonlight-stream.org");
|
||||||
if (host == nullptr) {
|
if (host == nullptr) {
|
||||||
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
||||||
return false;
|
return false;
|
||||||
@@ -460,10 +486,10 @@ bool CheckWANAccess(PSOCKADDR_IN wanAddr, PSOCKADDR_IN reportedWanAddr, bool* fo
|
|||||||
printf("Detecting WAN IP address via UPnP...");
|
printf("Detecting WAN IP address via UPnP...");
|
||||||
ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddrStr);
|
ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddrStr);
|
||||||
if (ret == UPNPCOMMAND_SUCCESS && strlen(wanAddrStr) > 0) {
|
if (ret == UPNPCOMMAND_SUCCESS && strlen(wanAddrStr) > 0) {
|
||||||
reportedWanAddr->sin_addr.S_un.S_addr = wanAddr->sin_addr.S_un.S_addr = inet_addr(wanAddrStr);
|
reportedWanAddr->sin_addr.S_un.S_addr = inet_addr(wanAddrStr);
|
||||||
printf("%s\n", wanAddrStr);
|
printf("%s\n", wanAddrStr);
|
||||||
|
|
||||||
if (wanAddr->sin_addr.S_un.S_addr != 0) {
|
if (reportedWanAddr->sin_addr.S_un.S_addr != 0) {
|
||||||
gotReportedWanAddress = true;
|
gotReportedWanAddress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,10 +540,10 @@ bool CheckWANAccess(PSOCKADDR_IN wanAddr, PSOCKADDR_IN reportedWanAddr, bool* fo
|
|||||||
|
|
||||||
if (natPmpErr == 0) {
|
if (natPmpErr == 0) {
|
||||||
char addrStr[64];
|
char addrStr[64];
|
||||||
reportedWanAddr->sin_addr = wanAddr->sin_addr = response.pnu.publicaddress.addr;
|
reportedWanAddr->sin_addr = response.pnu.publicaddress.addr;
|
||||||
inet_ntop(AF_INET, &response.pnu.publicaddress.addr, addrStr, sizeof(addrStr));
|
inet_ntop(AF_INET, &response.pnu.publicaddress.addr, addrStr, sizeof(addrStr));
|
||||||
printf("%s\n", addrStr);
|
printf("%s\n", addrStr);
|
||||||
if (wanAddr->sin_addr.S_un.S_addr != 0) {
|
if (reportedWanAddr->sin_addr.S_un.S_addr != 0) {
|
||||||
gotReportedWanAddress = true;
|
gotReportedWanAddress = true;
|
||||||
|
|
||||||
if (!foundUpnpIgd) {
|
if (!foundUpnpIgd) {
|
||||||
@@ -533,11 +559,9 @@ bool CheckWANAccess(PSOCKADDR_IN wanAddr, PSOCKADDR_IN reportedWanAddr, bool* fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Detecting WAN IP address via STUN...");
|
printf("Detecting WAN IP address via STUN...");
|
||||||
if (!getExternalAddressPortIP4(IPPROTO_UDP, 0, wanAddr)) {
|
if (!getExternalAddressPortIP4(IPPROTO_UDP, 0, wanAddr) && !getExternalAddressPortIP4(IPPROTO_TCP, 0, wanAddr)) {
|
||||||
if (!gotReportedWanAddress) {
|
DisplayMessage("Unable to determine your public IP address. Please check your Internet connection or try again in a few minutes.");
|
||||||
DisplayMessage("Unable to determine your public IP address. Please check your Internet connection.");
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char addrStr[64];
|
char addrStr[64];
|
||||||
@@ -638,7 +662,7 @@ int main(int argc, char* argv[])
|
|||||||
snprintf(msgBuf, sizeof(msgBuf),
|
snprintf(msgBuf, sizeof(msgBuf),
|
||||||
"Local GameStream connectivity check failed. Please try reinstalling GeForce Experience.\n\nThe following ports were not working:\n%s",
|
"Local GameStream connectivity check failed. Please try reinstalling GeForce Experience.\n\nThe following ports were not working:\n%s",
|
||||||
portMsgBuf);
|
portMsgBuf);
|
||||||
DisplayMessage(msgBuf);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +679,7 @@ int main(int argc, char* argv[])
|
|||||||
snprintf(msgBuf, sizeof(msgBuf),
|
snprintf(msgBuf, sizeof(msgBuf),
|
||||||
"Local network GameStream connectivity check failed. Try temporarily disabling your firewall software or adding firewall exceptions for the following ports:\n%s",
|
"Local network GameStream connectivity check failed. Try temporarily disabling your firewall software or adding firewall exceptions for the following ports:\n%s",
|
||||||
portMsgBuf);
|
portMsgBuf);
|
||||||
DisplayMessage(msgBuf);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,33 +710,31 @@ int main(int argc, char* argv[])
|
|||||||
// Try to connect via WAN IPv4 address
|
// Try to connect via WAN IPv4 address
|
||||||
printf("Testing GameStream ports via STUN-reported WAN address\n");
|
printf("Testing GameStream ports via STUN-reported WAN address\n");
|
||||||
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf))) {
|
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf))) {
|
||||||
if (IsDoubleNAT(&locallyReportedWanAddr)) {
|
// Many UPnP devices report IGD disconnected when double-NATed. If it was really offline,
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Your router appears be connected to the Internet through another router. Make sure both routers have UPnP or NAT-PMP enabled, or better yet, switch one of the routers into bridge/AP mode.");
|
// we probably would not have even gotten past STUN.
|
||||||
DisplayMessage(msgBuf);
|
if (IsDoubleNAT(&locallyReportedWanAddr) || igdDisconnected) {
|
||||||
|
snprintf(msgBuf, sizeof(msgBuf), "Your router appears be connected to the Internet through another router. Click the Help button for guidance on fixing this issue.");
|
||||||
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#connected-through-another-router-error");
|
||||||
}
|
}
|
||||||
else if (IsPossibleCGN(&locallyReportedWanAddr)) {
|
else if (IsPossibleCGN(&locallyReportedWanAddr)) {
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Your ISP is running a Carrier-Grade NAT that is preventing you from hosting services like Moonlight on the Internet. Contact your ISP and ask for a dedicated public IP address.");
|
snprintf(msgBuf, sizeof(msgBuf), "Your ISP is running a Carrier-Grade NAT that is preventing you from hosting services like Moonlight on the Internet. Click the Help button for guidance on fixing this issue.");
|
||||||
DisplayMessage(msgBuf);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#carrier-grade-nat-error");
|
||||||
}
|
|
||||||
else if (igdDisconnected) {
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed. Make sure you don't have two devices acting as routers connected together.");
|
|
||||||
DisplayMessage(msgBuf);
|
|
||||||
}
|
}
|
||||||
else if (rulesFound) {
|
else if (rulesFound) {
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Manual Internet streaming test required!\n\n"
|
snprintf(msgBuf, sizeof(msgBuf), "Manual Internet streaming test required!\n\n"
|
||||||
"Connect your client device to a different network or cellular data (it MUST NOT on be the same network as this PC for testing!). If Moonlight doesn't automatically connect, you can type the following address into Moonlight's Add PC dialog: %s\n\n"
|
"Connect your client device to a different network or cellular data (it MUST NOT on be the same network as this PC for testing!). If Moonlight doesn't automatically connect, you can type the following address into Moonlight's Add PC dialog: %s\n\n"
|
||||||
"If that doesn't work, check your router settings for any existing Moonlight port forwarding entries and delete them or try restarting your router.", wanAddrStr);
|
"If that doesn't work, click the Help button for guidance on fixing this issue.", wanAddrStr);
|
||||||
DisplayMessage(msgBuf, MpWarn);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#manual-internet-streaming-test-fails", MpWarn);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed. Make sure UPnP or NAT-PMP is enabled in your router settings.\n\nThe following ports were not forwarded properly:\n%s", portMsgBuf);
|
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed. Click the Help button for guidance on fixing this issue.\n\nThe following ports were not forwarded properly:\n%s", portMsgBuf);
|
||||||
DisplayMessage(msgBuf);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#internet-gamestream-connectivity-check-error");
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "All tests passed! If Moonlight doesn't automatically connect outside your network, you can type the following address into Moonlight's Add PC dialog: %s", wanAddrStr);
|
snprintf(msgBuf, sizeof(msgBuf), "All tests passed! If Moonlight doesn't automatically connect outside your network, you can type the following address into Moonlight's Add PC dialog: %s", wanAddrStr);
|
||||||
DisplayMessage(msgBuf, MpInfo);
|
DisplayMessage(msgBuf, nullptr, MpInfo);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
+4
-3
@@ -61,7 +61,7 @@ bool getExternalAddressPortIP4(int proto, unsigned short localPort, PSOCKADDR_IN
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
} resp;
|
} resp;
|
||||||
|
|
||||||
host = gethostbyname("stun.stunprotocol.org");
|
host = gethostbyname("stun.moonlight-stream.org");
|
||||||
if (host == nullptr) {
|
if (host == nullptr) {
|
||||||
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
printf("gethostbyname() failed: %d\n", WSAGetLastError());
|
||||||
return false;
|
return false;
|
||||||
@@ -112,7 +112,7 @@ bool getExternalAddressPortIP4(int proto, unsigned short localPort, PSOCKADDR_IN
|
|||||||
timeout = 1;
|
timeout = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesRead = SOCKET_ERROR;
|
bytesRead = 0;
|
||||||
for (i = 0; i < tries; i++) {
|
for (i = 0; i < tries; i++) {
|
||||||
// Retransmit the request every second until the timeout elapses
|
// Retransmit the request every second until the timeout elapses
|
||||||
if (send(sock, (char *)&reqMsg, sizeof(reqMsg), 0) == SOCKET_ERROR) {
|
if (send(sock, (char *)&reqMsg, sizeof(reqMsg), 0) == SOCKET_ERROR) {
|
||||||
@@ -179,7 +179,8 @@ bool getExternalAddressPortIP4(int proto, unsigned short localPort, PSOCKADDR_IN
|
|||||||
printf("STUN attribute out of bounds: %d\n", htons(attribute->length));
|
printf("STUN attribute out of bounds: %d\n", htons(attribute->length));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (htons(attribute->type) != STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS) {
|
// Mask off the comprehension bit
|
||||||
|
else if ((htons(attribute->type) & 0x7FFF) != STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS) {
|
||||||
// Continue searching if this wasn't our address
|
// Continue searching if this wasn't our address
|
||||||
bytesRead -= sizeof(*attribute) + htons(attribute->length);
|
bytesRead -= sizeof(*attribute) + htons(attribute->length);
|
||||||
attribute = (PSTUN_ATTRIBUTE_HEADER)(((char*)attribute) + sizeof(*attribute) + htons(attribute->length));
|
attribute = (PSTUN_ATTRIBUTE_HEADER)(((char*)attribute) + sizeof(*attribute) + htons(attribute->length));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VER_VERSION 2,1,0,0
|
#define VER_VERSION 2,3,0,0
|
||||||
#define VER_VERSION_STR "2.1.0.0"
|
#define VER_VERSION_STR "2.3.0.0"
|
||||||
|
|
||||||
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
|
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
|
||||||
#define VER_PRODUCTNAME_STR "Moonlight Internet Streaming Helper"
|
#define VER_PRODUCTNAME_STR "Moonlight Internet Streaming Helper"
|
||||||
|
|||||||
Reference in New Issue
Block a user