From c6c4e5102c138810d7c7fc1c8ccfeb2fba8edef9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 1 Apr 2016 00:31:32 -0400 Subject: [PATCH 1/2] Fix build with new moonlight-common-c source layout --- CMakeLists.txt | 2 +- libgamestream/CMakeLists.txt | 5 ++--- libgamestream/client.c | 2 +- libgamestream/client.h | 2 +- libgamestream/sps.h | 2 +- src/audio.h | 2 +- src/config.h | 2 +- src/connection.h | 2 +- src/input/cec.c | 2 +- src/input/evdev.c | 2 +- src/input/sdlinput.c | 2 +- src/main.c | 2 +- src/platform.h | 2 +- src/sdl.c | 2 +- src/video/aml.c | 2 +- src/video/fake.c | 2 +- src/video/ffmpeg.c | 2 +- src/video/imx.c | 2 +- src/video/pi.c | 2 +- src/video/sdl.c | 2 +- 20 files changed, 21 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e2b6251..9e8013e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ else() set(SOFTWARE_FOUND FALSE) endif() -SET(MOONLIGHT_COMMON_INCLUDE_DIR ./third_party/moonlight-common-c) +SET(MOONLIGHT_COMMON_INCLUDE_DIR ./third_party/moonlight-common-c/src) SET(GAMESTREAM_INCLUDE_DIR ./libgamestream) if(CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/libgamestream/CMakeLists.txt b/libgamestream/CMakeLists.txt index 5a958cc..97ded6f 100644 --- a/libgamestream/CMakeLists.txt +++ b/libgamestream/CMakeLists.txt @@ -10,8 +10,7 @@ pkg_check_modules(ENET REQUIRED libenet) aux_source_directory(./ GAMESTREAM_SRC_LIST) aux_source_directory(../third_party/h264bitstream GAMESTREAM_SRC_LIST) -aux_source_directory(../third_party/moonlight-common-c/limelight-common MOONLIGHT_COMMON_SRC_LIST) -aux_source_directory(../third_party/moonlight-common-c/limelight-common/OpenAES MOONLIGHT_COMMON_SRC_LIST) +aux_source_directory(../third_party/moonlight-common-c/src MOONLIGHT_COMMON_SRC_LIST) add_library(moonlight-common SHARED ${MOONLIGHT_COMMON_SRC_LIST}) @@ -22,7 +21,7 @@ target_link_libraries(gamestream moonlight-common) set_target_properties(gamestream PROPERTIES SOVERSION 0 VERSION ${MOONLIGHT_VERSION}) set_target_properties(moonlight-common PROPERTIES SOVERSION 0 VERSION ${MOONLIGHT_VERSION}) -target_include_directories(gamestream PRIVATE ../third_party/moonlight-common-c ../third_party/h264bitstream ${AVAHI_INCLUDE_DIRS} ${LIBUUID_INCLUDE_DIRS}) +target_include_directories(gamestream PRIVATE ../third_party/moonlight-common-c/src ../third_party/h264bitstream ${AVAHI_INCLUDE_DIRS} ${LIBUUID_INCLUDE_DIRS}) target_include_directories(moonlight-common PRIVATE ${ENET_INCLUDE_DIRS}) target_link_libraries(gamestream ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${AVAHI_LIBRARIES} ${LIBUUID_LIBRARIES}) target_link_libraries(moonlight-common ${ENET_LIBRARIES}) diff --git a/libgamestream/client.c b/libgamestream/client.c index e4eb2e7..820ce86 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -23,7 +23,7 @@ #include "client.h" #include "errors.h" -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/libgamestream/client.h b/libgamestream/client.h index 548690a..10b78f6 100644 --- a/libgamestream/client.h +++ b/libgamestream/client.h @@ -21,7 +21,7 @@ #include "xml.h" -#include "limelight-common/Limelight.h" +#include #include diff --git a/libgamestream/sps.h b/libgamestream/sps.h index bd2cf46..9123b6f 100644 --- a/libgamestream/sps.h +++ b/libgamestream/sps.h @@ -17,7 +17,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #define GS_SPS_BITSTREAM_FIXUP 0x01 #define GS_SPS_BASELINE_HACK 0x02 diff --git a/src/audio.h b/src/audio.h index de7aece..3981212 100644 --- a/src/audio.h +++ b/src/audio.h @@ -19,7 +19,7 @@ #include -#include "limelight-common/Limelight.h" +#include extern const char* audio_device; diff --git a/src/config.h b/src/config.h index 9b88b5c..e2225ab 100644 --- a/src/config.h +++ b/src/config.h @@ -17,7 +17,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #include diff --git a/src/connection.h b/src/connection.h index e11537c..8b985b6 100644 --- a/src/connection.h +++ b/src/connection.h @@ -17,6 +17,6 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include extern CONNECTION_LISTENER_CALLBACKS connection_callbacks; diff --git a/src/input/cec.c b/src/input/cec.c index 854a0e2..8c3892e 100644 --- a/src/input/cec.c +++ b/src/input/cec.c @@ -19,7 +19,7 @@ #ifdef HAVE_LIBCEC -#include "limelight-common/Limelight.h" +#include #include diff --git a/src/input/evdev.c b/src/input/evdev.c index 245105f..ea3ea7a 100644 --- a/src/input/evdev.c +++ b/src/input/evdev.c @@ -24,7 +24,7 @@ #include "mapping.h" #include "libevdev/libevdev.h" -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/input/sdlinput.c b/src/input/sdlinput.c index da6a6b7..2c95fb1 100644 --- a/src/input/sdlinput.c +++ b/src/input/sdlinput.c @@ -22,7 +22,7 @@ #include "sdlinput.h" #include "../sdl.h" -#include "limelight-common/Limelight.h" +#include #define ACTION_MODIFIERS (MODIFIER_SHIFT|MODIFIER_ALT|MODIFIER_CTRL) #define QUIT_KEY SDLK_q diff --git a/src/main.c b/src/main.c index e1a5213..2463912 100644 --- a/src/main.c +++ b/src/main.c @@ -33,7 +33,7 @@ #include "input/cec.h" #include "input/sdlinput.h" -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/platform.h b/src/platform.h index 9a0cf5d..ed0e786 100644 --- a/src/platform.h +++ b/src/platform.h @@ -17,7 +17,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/sdl.c b/src/sdl.c index b48999e..6552748 100644 --- a/src/sdl.c +++ b/src/sdl.c @@ -22,7 +22,7 @@ #include "sdl.h" #include "input/sdlinput.h" -#include "limelight-common/Limelight.h" +#include static bool done; static int fullscreen_flags; diff --git a/src/video/aml.c b/src/video/aml.c index 673747d..2057d2e 100644 --- a/src/video/aml.c +++ b/src/video/aml.c @@ -18,7 +18,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/video/fake.c b/src/video/fake.c index 163fa37..a9e3e3d 100644 --- a/src/video/fake.c +++ b/src/video/fake.c @@ -17,7 +17,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #include diff --git a/src/video/ffmpeg.c b/src/video/ffmpeg.c index 3027617..7de31e5 100644 --- a/src/video/ffmpeg.c +++ b/src/video/ffmpeg.c @@ -23,7 +23,7 @@ #include "ffmpeg_vdpau.h" #endif -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/video/imx.c b/src/video/imx.c index 3d83f32..2cf4daa 100644 --- a/src/video/imx.c +++ b/src/video/imx.c @@ -17,7 +17,7 @@ * along with Moonlight; if not, see . */ -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/video/pi.c b/src/video/pi.c index d5b87e9..c433e08 100644 --- a/src/video/pi.c +++ b/src/video/pi.c @@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "sps.h" -#include "limelight-common/Limelight.h" +#include #include #include diff --git a/src/video/sdl.c b/src/video/sdl.c index a988870..583c5ce 100644 --- a/src/video/sdl.c +++ b/src/video/sdl.c @@ -21,7 +21,7 @@ #include "../sdl.h" #include "ffmpeg.h" -#include "limelight-common/Limelight.h" +#include #include #include From 86532497ef510b75592f27d0e9ce1e6bac4538d1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 1 Apr 2016 01:30:37 -0400 Subject: [PATCH 2/2] Fix pairing and streaming from Gen 7 servers --- libgamestream/client.c | 148 +++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 64 deletions(-) diff --git a/libgamestream/client.c b/libgamestream/client.c index 820ce86..844a450 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -166,87 +166,107 @@ static int load_cert(const char* keyDirectory) { } static int load_server_status(PSERVER_DATA server) { - char *pairedText = NULL; - char *currentGameText = NULL; - char *versionText = NULL; - char *stateText = NULL; - char *heightText = NULL; - char *serverCodecModeSupportText = NULL; uuid_t uuid; char uuid_str[37]; - - int ret = GS_INVALID; + + int ret; char url[4096]; - uuid_generate_random(uuid); - uuid_unparse(uuid, uuid_str); - sprintf(url, "https://%s:47984/serverinfo?uniqueid=%s&uuid=%s", server->address, unique_id, uuid_str); + int i; - PHTTP_DATA data = http_create_data(); - if (data == NULL) { - ret = GS_OUT_OF_MEMORY; - goto cleanup; - } - if (http_request(url, data) != GS_OK) { - ret = GS_IO_ERROR; - goto cleanup; - } + i = 0; + do { + char *pairedText = NULL; + char *currentGameText = NULL; + char *versionText = NULL; + char *stateText = NULL; + char *heightText = NULL; + char *serverCodecModeSupportText = NULL; - if (xml_search(data->memory, data->size, "currentgame", ¤tGameText) != GS_OK) { - goto cleanup; - } + ret = GS_INVALID; - if (xml_search(data->memory, data->size, "PairStatus", &pairedText) != GS_OK) - goto cleanup; + uuid_generate_random(uuid); + uuid_unparse(uuid, uuid_str); - if (xml_search(data->memory, data->size, "appversion", &versionText) != GS_OK) - goto cleanup; + // Modern GFE versions don't allow serverinfo to be fetched over HTTPS if the client + // is not already paired. Since we can't pair without knowing the server version, we + // make another request over HTTP if the HTTPS request fails. We can't just use HTTP + // for everything because it doesn't accurately tell us if we're paired. + sprintf(url, "%s://%s:%d/serverinfo?uniqueid=%s&uuid=%s", + i == 0 ? "https" : "http", server->address, i == 0 ? 47984 : 47989, unique_id, uuid_str); - if (xml_search(data->memory, data->size, "state", &stateText) != GS_OK) - goto cleanup; + PHTTP_DATA data = http_create_data(); + if (data == NULL) { + ret = GS_OUT_OF_MEMORY; + goto cleanup; + } + if (http_request(url, data) != GS_OK) { + ret = GS_IO_ERROR; + goto cleanup; + } - if (xml_search(data->memory, data->size, "Height", &heightText) != GS_OK) - goto cleanup; + if (xml_search(data->memory, data->size, "currentgame", ¤tGameText) != GS_OK) { + goto cleanup; + } - if (xml_search(data->memory, data->size, "ServerCodecModeSupport", &serverCodecModeSupportText) != GS_OK) - goto cleanup; + if (xml_search(data->memory, data->size, "PairStatus", &pairedText) != GS_OK) + goto cleanup; - if (xml_search(data->memory, data->size, "gputype", &server->gpuType) != GS_OK) - goto cleanup; + if (xml_search(data->memory, data->size, "appversion", &versionText) != GS_OK) + goto cleanup; - if (xml_search(data->memory, data->size, "GfeVersion", &server->gfeVersion) != GS_OK) - goto cleanup; + if (xml_search(data->memory, data->size, "state", &stateText) != GS_OK) + goto cleanup; - server->paired = pairedText != NULL && strcmp(pairedText, "1") == 0; - server->currentGame = currentGameText == NULL ? 0 : atoi(currentGameText); - server->supports4K = heightText != NULL && serverCodecModeSupportText != NULL && atoi(heightText) >= 2160; - server->serverMajorVersion = atoi(versionText); - if (strstr(stateText, "_SERVER_AVAILABLE")) { - // After GFE 2.8, current game remains set even after streaming - // has ended. We emulate the old behavior by forcing it to zero - // if streaming is not active. - server->currentGame = 0; - } - ret = GS_OK; + if (xml_search(data->memory, data->size, "Height", &heightText) != GS_OK) + goto cleanup; - cleanup: - if (data != NULL) - http_free_data(data); + if (xml_search(data->memory, data->size, "ServerCodecModeSupport", &serverCodecModeSupportText) != GS_OK) + goto cleanup; - if (pairedText != NULL) - free(pairedText); + if (xml_search(data->memory, data->size, "gputype", &server->gpuType) != GS_OK) + goto cleanup; - if (currentGameText != NULL) - free(currentGameText); + if (xml_search(data->memory, data->size, "GfeVersion", &server->gfeVersion) != GS_OK) + goto cleanup; - if (versionText != NULL) - free(versionText); + // These fields are present on all version of GFE that this client supports + if (!strlen(currentGameText) || !strlen(pairedText) || !strlen(versionText) || !strlen(stateText)) + goto cleanup; - if (heightText != NULL) - free(heightText); + server->paired = pairedText != NULL && strcmp(pairedText, "1") == 0; + server->currentGame = currentGameText == NULL ? 0 : atoi(currentGameText); + server->supports4K = heightText != NULL && serverCodecModeSupportText != NULL && atoi(heightText) >= 2160; + server->serverMajorVersion = atoi(versionText); + if (strstr(stateText, "_SERVER_AVAILABLE")) { + // After GFE 2.8, current game remains set even after streaming + // has ended. We emulate the old behavior by forcing it to zero + // if streaming is not active. + server->currentGame = 0; + } + ret = GS_OK; - if (serverCodecModeSupportText != NULL) - free(serverCodecModeSupportText); + cleanup: + if (data != NULL) + http_free_data(data); + + if (pairedText != NULL) + free(pairedText); + + if (currentGameText != NULL) + free(currentGameText); + + if (versionText != NULL) + free(versionText); + + if (heightText != NULL) + free(heightText); + + if (serverCodecModeSupportText != NULL) + free(serverCodecModeSupportText); + + i++; + } while (ret != GS_OK && i < 2); return ret; } @@ -561,7 +581,7 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b srand(time(NULL)); char url[4096]; - u_int32_t rikeyid = 1; + u_int32_t rikeyid = 0; char rikey_hex[33]; bytes_to_hex(config->remoteInputAesKey, rikey_hex, 16); @@ -583,10 +603,10 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b else goto cleanup; - if ((ret = xml_search(data->memory, data->size, "cancel", &result)) != GS_OK) + if ((ret = xml_search(data->memory, data->size, "gamesession", &result)) != GS_OK) goto cleanup; - if (atoi(result) == 0) { + if (!strcmp(result, "0")) { ret = GS_FAILED; goto cleanup; }