ValveSoftware / Proton

Compatibility tool for Steam Play based on Wine and additional components
Other
24.29k stars 1.06k forks source link

The Good Life Demo (1741410) #5195

Open popsUlfr opened 3 years ago

popsUlfr commented 3 years ago

Compatibility Report

System Information

I confirm:

Symptoms

Ahead of its release, I was checking out the demo for The Good Life, but starting a new game results in a black screen related to its intro video. I'm assuming at this point that problem will persist with the full release.

Looking into the Unity Player.log we have something peculiar happening here :

WindowsVideoMedia error 0x80004001 while reading http://localhost:16700/seQ7ZUZ0kT6R4_FZ3hZ_HSybUCpHCZ4v
Context: Creating DXGI DeviceManager
Error details: Not implemented.
WindowsVideoMedia error 0x80070003 while reading http://localhost:16700/seQ7ZUZ0kT6R4_FZ3hZ_HSybUCpHCZ4v
Context: MFCreateSourceReaderFromURL
Error details: Path not found.

The game is serving the video file over http for some reason (??), so during the black screen I can go to the url and watch the video in the browser. Looking into the mfplat wine code and debugging the process a bit, I'm not sure if the http: scheme is actually implemented and it is falling back to the file: protocol instead ? Trying to access file://localhost:16700/seQ7ZUZ0kT6R4_FZ3hZ_HSybUCpHCZ4v maybe and failing ? The video files are located at ~/.local/share/Steam/steamapps/common/The Good Life Demo/StandaloneWindows64_Data/StreamingAssets and are encoded using vp8 so I'm pretty sure they'd have played fine if loaded directly by the game.

I attached a save file (SAV0.sav) that's right after the intro cutscene to test the game after that. Beyond the video issue the game seems to play fine until the next video cutscene that is which results in a black screen block.

Glorious Eggroll Proton has the same issue.

Reproduction

  1. Install The Good Life Demo: https://store.steampowered.com/app/1452500/The_Good_Life/
  2. Launch the game with Proton Experimental
  3. Start A New Game
  4. Get stuck on a black screen
Learning5Life commented 3 years ago

I can confirm that the same problem exists with Proton 6.3-7.

popsUlfr commented 3 years ago

Finally found some time to go deeper into it. I hacked the wine source code like this:

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 519fa23cd23..26c367a72de 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -6268,6 +6268,12 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa
     if (!url || !obj_type || !object)
         return E_POINTER;

+    /* popsulfr stuff */
+    if (!memcmp(url, L"http:", sizeof(WCHAR)*5))
+    {
+        url = L"file:///home/popsulfr/.local/share/Steam/steamapps/common/The Good Life Demo/StandaloneWindows64_Data/StreamingAssets/fe3fb7324c2bb55a";
+    }
+
     if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler)))
         return hr;

@@ -6309,6 +6315,12 @@ static HRESULT WINAPI source_resolver_CreateObjectFromByteStream(IMFSourceResolv
     if (!stream || !obj_type || !object)
         return E_POINTER;

+    /* popsulfr stuff */
+    if (!memcmp(url, L"http:", sizeof(WCHAR)*5))
+    {
+        url = L"file:///home/popsulfr/.local/share/Steam/steamapps/common/The Good Life Demo/StandaloneWindows64_Data/StreamingAssets/fe3fb7324c2bb55a";
+    }
+    
     if (FAILED(hr = resolver_get_bytestream_handler(stream, url, flags, &handler)))
         return MF_E_UNSUPPORTED_BYTESTREAM_TYPE;

so that whenever it encounters a http: protocol scheme it just loads the intro video using file:

Now it complains about missing vp8

0304:warn:mfplat:media_source_constructor Failed to construct MFMediaSource, hr 0x80004005.
winegstreamer error: decodebin0: Your GStreamer installation is missing a plug-in.
0304:trace:mfplat:media_source_Release 00000001332802D0, refcount 0.
winegstreamer error: decodebin0: ../src-gst_base/gst/playback/gstdecodebin2.c(4719): gst_decode_bin_expose (): /GstBin:bin0/GstDecodeBin:decodebin0:
no suitable plugins found:
Missing decoder: VP8 (video/x-vp8, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive)

If I drop my hacked mfplat.dll into the Glorious Eggroll Proton e.g.: ~/.local/share/Steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/mfplat.dll

The intro video plays and the game can be played normally!

So there's a missing http: scheme handler + official proton is unable to decode vp8. (I converted fe3fb7324c2bb55a to vp9 and it's the same deal)

Swizzler121 commented 3 years ago

I can confirm this issue persists in the full game, booted it up last night and tried using the latest stable proton, experimental proton, and Glorious eggroll, issue existed in all 3

popsUlfr commented 3 years ago

Yeah a http_scheme_handler for mfplat needs to be implemented. Maybe as a hacky workaround, if any http: scheme is encountered the video could just be downloaded to /tmp to get a classic file: url. Let's see how hard that is...

popsUlfr commented 3 years ago

EDIT3: don't use this workaround attempt, look further down for the content-length workaround.

EDIT2:

oh wait, removing ~/.local/share/Steam/steamapps/compatdata/1741410/pfx/drive_c/users/steamuser/AppData/Local/Microsoft/Windows/{INetCache,INetCookies}, ~/.local/share/Steam/steamapps/compatdata/1741410/pfx/drive_c/users/steamuser/Temp/* between runs seems to make it work every time.

EDIT1:

Here's the latest attempt but it doesn't seem reliable for some reason, I thought it was something to do with the url lifecycle but I'm really not sure. It worked the first time for me on a clean install of the demo but subsequent new games would make the game freeze at random points during the videos. I think there's no way around properly implementing the http scheme to get this working reliably.

diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in
index 9e5c607deae..543e7ddeb08 100644
--- a/dlls/mfplat/Makefile.in
+++ b/dlls/mfplat/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = mfplat.dll
 IMPORTLIB = mfplat
-IMPORTS   = advapi32 ole32 mfuuid propsys rtworkq
+IMPORTS   = advapi32 ole32 mfuuid propsys rtworkq urlmon

 EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 519fa23cd23..cb035462f40 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -46,6 +46,8 @@
 #include "strsafe.h"
 #undef INITGUID
 #include "evr.h"
+#include "urlmon.h"
+#include "fileapi.h"

 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);

@@ -6254,6 +6256,38 @@ static ULONG WINAPI source_resolver_Release(IMFSourceResolver *iface)
     return refcount;
 }

+/* downloads urls with http: scheme to a temporary file */
+static const WCHAR * workaround_http_scheme_handler(const WCHAR *url)
+{
+    WCHAR temp_path_buffer[MAX_PATH], temp_file_path_buffer[MAX_PATH], *new_url;
+    DWORD ret;
+    int len;
+
+    if (lstrlenW(url) < 5 || memcmp(url, L"http:", sizeof(WCHAR)*5))
+        return url;
+
+    ret = GetTempPathW(MAX_PATH, temp_path_buffer);
+    if (!ret || ret > MAX_PATH)
+        return url;
+
+    if (!GetTempFileNameW(temp_path_buffer, L"MFP", 0, temp_file_path_buffer))
+        return url;
+
+    if (FAILED(URLDownloadToFileW(NULL, url, temp_file_path_buffer, 0, NULL)))
+        return url;
+
+    len = lstrlenW(temp_file_path_buffer);
+    /* memory leak! */
+    new_url = malloc((len + 1) * sizeof(WCHAR));
+    if (!new_url)
+        return url;
+
+    memcpy(new_url, temp_file_path_buffer, len * sizeof(WCHAR));
+    new_url[len] = 0;
+
+    return new_url;
+}
+
 static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *iface, const WCHAR *url,
         DWORD flags, IPropertyStore *props, MF_OBJECT_TYPE *obj_type, IUnknown **object)
 {
@@ -6268,6 +6302,10 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa
     if (!url || !obj_type || !object)
         return E_POINTER;

+    url = workaround_http_scheme_handler(url);
+
+    TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object);
+
     if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler)))
         return hr;

@@ -6309,6 +6347,10 @@ static HRESULT WINAPI source_resolver_CreateObjectFromByteStream(IMFSourceResolv
     if (!stream || !obj_type || !object)
         return E_POINTER;

+    url = workaround_http_scheme_handler(url);
+
+    TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface, stream, debugstr_w(url), flags, props, obj_type, object);
+
     if (FAILED(hr = resolver_get_bytestream_handler(stream, url, flags, &handler)))
         return MF_E_UNSUPPORTED_BYTESTREAM_TYPE;

@@ -6347,6 +6389,10 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromURL(IMFSourceResolver

     TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state);

+    url = workaround_http_scheme_handler(url);
+
+    TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state);
+
     if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler)))
         return hr;
Old attempt The following makes the videos play with Glorious Eggrolls Proton but there's still something wrong as the game still doesn't reach the in-game state after the two videos... It's compiled using the official proton source so maybe I need to pull Glorious Eggroll's and recompile it there. Or I am just using `URLDownloadToCacheFileW` wrong ? ```diff diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in index 9e5c607deae..543e7ddeb08 100644 --- a/dlls/mfplat/Makefile.in +++ b/dlls/mfplat/Makefile.in @@ -1,6 +1,6 @@ MODULE = mfplat.dll IMPORTLIB = mfplat -IMPORTS = advapi32 ole32 mfuuid propsys rtworkq +IMPORTS = advapi32 ole32 mfuuid propsys rtworkq urlmon EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 519fa23cd23..3d1da4834f6 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -46,6 +46,7 @@ #include "strsafe.h" #undef INITGUID #include "evr.h" +#include "urlmon.h" WINE_DEFAULT_DEBUG_CHANNEL(mfplat); @@ -6254,6 +6255,18 @@ static ULONG WINAPI source_resolver_Release(IMFSourceResolver *iface) return refcount; } +/* downloads urls with http: scheme to a temporary file */ +static const WCHAR * workaround_http_scheme_handler(const WCHAR *url, WCHAR *out, DWORD outsize) +{ + if (lstrlenW(url) < 5 || memcmp(url, L"http:", sizeof(WCHAR)*5)) + return url; + + if (FAILED(URLDownloadToCacheFileW(NULL, url, out, outsize, 0, NULL))) + return url; + + return out; +} + static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *iface, const WCHAR *url, DWORD flags, IPropertyStore *props, MF_OBJECT_TYPE *obj_type, IUnknown **object) { @@ -6262,12 +6275,17 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa IRtwqAsyncResult *result; RTWQASYNCRESULT *data; HRESULT hr; + WCHAR buffer[MAX_PATH]; TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object); if (!url || !obj_type || !object) return E_POINTER; + url = workaround_http_scheme_handler(url, buffer, MAX_PATH*sizeof(WCHAR)); + + TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object); + if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler))) return hr; @@ -6344,6 +6362,11 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromURL(IMFSourceResolver IUnknown *inner_cookie = NULL; IRtwqAsyncResult *result; HRESULT hr; + WCHAR buffer[MAX_PATH]; + + TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state); + + url = workaround_http_scheme_handler(url, buffer, MAX_PATH*sizeof(WCHAR)); TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state); ``` Backup the original `mfplat.dll`: ``` mv ~/.local/share/Steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/{mfplat.dll,mfplat.dll.backup} ``` Place the one with the workaround at `~/.local/share/Steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/mfplat.dll` - [mfplat.dll.gz](https://github.com/ValveSoftware/Proton/files/7354470/mfplat.dll.gz)
Swizzler121 commented 3 years ago

With your fixes I was able to play through the first day, but when night hit and I went to the town square, the game locked up. I'm guessing this is due to the need to clear out those temp files each run? it appears that is even the case between cutscenes in the same play session!

Also, in the full game, the folder is 1452500 instead of 1741410

Player.log

And here is my last save, although its about 20 minutes before the crash, as I wasn't expecting the cutscene, so didn't save. I'll update with a closer save later when I can play up to the crash again. SAV2.tar.gz

Swizzler121 commented 3 years ago

Hmm... even clearing the temp data before triggering the cutscene causes a hang. I don't know how to pull all the logs you did, I'll see if I can figure it out and add them as I go, but here's what I got:

Save file right before walking into town at night (second cutscene) SAV3.tar.gz

Player.log

Proton Log file steam-1452500.log

popsUlfr commented 3 years ago

For debugging and more precisely log things I put in the launch options of the game

PROTON_DUMP_DEBUG_COMMANDS=1 %command%

This creates a directory at /tmp/proton_<username> in which you can run the game or attach a debugger. I edit WINEDEBUG= to log mfplat WINEDEBUG="+mfplat" and/or WINEDEBUG="+mfplat,+relay,+seh"

It's maybe a timing issue, the time it takes to download the video and then supply its path to the decoder.

But... it's so baffling they are doing this. Creating a http server to serve themselves their own video file they could have just opened normally as a file, this is pretty insane.

Looking at the curl headers output when fetching a video:

$ curl -v http://localhost:16700/scKuNR_abc-ylAi3WwBng_X7xyVI1nLb
*   Trying 127.0.0.1:16700...
* Connected to localhost (127.0.0.1) port 16700 (#0)
> GET /scKuNR_abc-ylAi3WwBng_X7xyVI1nLb HTTP/1.1
> Host: localhost:16700
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: video/.webm; charset=utf-8
< Accept-Ranges: bytes
< Content-Length: 22002493
<

Could maybe only grab the response header and match the Content-Length to the file with the same length in the StreamingAssets folder for a dirty/hacky workaround. xP

Might be quicker at this point to just implement http scheme though, guess I'll give it a shot (no promises though).

popsUlfr commented 3 years ago

Ok I did it xD. This grabs the files directly from the disk by matching their sizes with the content-length of the http response header. It seems to work reliably on my end! \o/

diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in
index 9e5c607deae..bc5e13aaa7f 100644
--- a/dlls/mfplat/Makefile.in
+++ b/dlls/mfplat/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = mfplat.dll
 IMPORTLIB = mfplat
-IMPORTS   = advapi32 ole32 mfuuid propsys rtworkq
+IMPORTS   = advapi32 ole32 mfuuid propsys rtworkq kernelbase wininet

 EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 519fa23cd23..aa4d3dec50d 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -46,6 +46,7 @@
 #include "strsafe.h"
 #undef INITGUID
 #include "evr.h"
+#include "wininet.h"

 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);

@@ -6254,6 +6255,120 @@ static ULONG WINAPI source_resolver_Release(IMFSourceResolver *iface)
     return refcount;
 }

+/* match urls with http: scheme to the appropriate files */
+static const WCHAR * workaround_http_scheme_handler(const WCHAR *url, WCHAR *url_buffer)
+{
+    static const WCHAR* acccept_types[] = { L"*/*", NULL };
+    WIN32_FIND_DATAW find_file_data;
+    HANDLE hfind;
+    DWORDLONG size, file_size;
+    HINTERNET hinternet, hconnect, hrequest;
+    URL_COMPONENTSW url_components;
+    WCHAR content_length[24];
+    DWORD content_length_size;
+
+    content_length_size = sizeof(content_length);
+
+    if (lstrlenW(url) < 5 || memcmp(url, L"http:", sizeof(WCHAR)*5))
+        return url;
+
+    memset(&url_components, 0, sizeof(URL_COMPONENTSW));
+    url_components.dwStructSize = sizeof(URL_COMPONENTSW);
+    url_components.dwHostNameLength = 1;
+    url_components.dwUserNameLength = 1;
+    url_components.dwPasswordLength = 1;
+    url_components.dwUrlPathLength = 1;
+    url_components.dwExtraInfoLength = 1;
+
+    if (!(InternetCrackUrlW(url, lstrlenW(url), 0, &url_components)))
+        return url;
+
+    url_components.lpszHostName = memcpy(url_buffer, url_components.lpszHostName,
+        url_components.dwHostNameLength * sizeof(WCHAR));
+    url_components.lpszHostName[url_components.dwHostNameLength] = 0;
+    url_components.lpszUserName = memcpy(&url_components.lpszHostName[url_components.dwHostNameLength+1],
+        url_components.lpszUserName, url_components.dwUserNameLength * sizeof(WCHAR));
+    url_components.lpszUserName[url_components.dwUserNameLength] = 0;
+    url_components.lpszPassword = memcpy(&url_components.lpszUserName[url_components.dwUserNameLength+1],
+        url_components.lpszPassword, url_components.dwPasswordLength * sizeof(WCHAR));
+    url_components.lpszPassword[url_components.dwPasswordLength] = 0;
+    url_components.lpszUrlPath = memcpy(&url_components.lpszPassword[url_components.dwPasswordLength+1],
+        url_components.lpszUrlPath, (url_components.dwUrlPathLength + url_components.dwExtraInfoLength) * sizeof(WCHAR));
+    url_components.lpszUrlPath[url_components.dwUrlPathLength + url_components.dwExtraInfoLength] = 0;
+
+    if (!(hinternet = InternetOpenW(L"wininet", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0)))
+        return url;
+
+    if (!(hconnect = InternetConnectW(hinternet, url_components.lpszHostName, url_components.nPort,
+        url_components.lpszUserName, url_components.lpszPassword, INTERNET_SERVICE_HTTP, 0, 0)))
+    {
+        InternetCloseHandle(hinternet);
+        return url;
+    }
+
+    if (!(hrequest = HttpOpenRequestW(hconnect, L"GET", url_components.lpszUrlPath,
+        NULL, NULL,
+        acccept_types,
+        INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_NO_UI|INTERNET_FLAG_RELOAD, 0)))
+    {
+        InternetCloseHandle(hconnect);
+        InternetCloseHandle(hinternet);
+        return url;
+    }
+
+    if (!HttpSendRequestW(hrequest, NULL, 0, NULL, 0))
+    {
+        InternetCloseHandle(hrequest);
+        InternetCloseHandle(hconnect);
+        InternetCloseHandle(hinternet);
+        return url;
+    }
+
+    if (!HttpQueryInfoW(hrequest, HTTP_QUERY_CONTENT_LENGTH, content_length, &content_length_size, NULL) || !content_length_size)
+    {
+        InternetCloseHandle(hrequest);
+        InternetCloseHandle(hconnect);
+        InternetCloseHandle(hinternet);
+        return url;
+    }
+
+    size = wcstoul(content_length, NULL, 10);
+
+    InternetCloseHandle(hrequest);
+    InternetCloseHandle(hconnect);
+    InternetCloseHandle(hinternet);
+
+    if (!size)
+        return url;
+
+    if (!GetModuleFileNameW(NULL, url_buffer, MAX_PATH * sizeof(WCHAR)))
+        return url;
+
+    PathRemoveFileSpecW(url_buffer);
+    PathAppendW(url_buffer, L"StandaloneWindows64_Data\\StreamingAssets\\*");
+
+    if ((hfind = FindFirstFileW(url_buffer, &find_file_data)) == INVALID_HANDLE_VALUE)
+        return url;
+
+    do
+    {
+        if (find_file_data.nFileSizeHigh > 0)
+            file_size = (find_file_data.nFileSizeHigh * (MAXDWORD+1)) + find_file_data.nFileSizeLow;
+        else
+            file_size = find_file_data.nFileSizeLow;
+        if (file_size != size)
+            continue;
+        PathRemoveFileSpecW(url_buffer);
+        PathAppendW(url_buffer, find_file_data.cFileName);
+        url = url_buffer;
+        break;
+    }
+    while (FindNextFileW(hfind, &find_file_data));
+    FindClose(hfind);
+
+    return url;
+}
+
 static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *iface, const WCHAR *url,
         DWORD flags, IPropertyStore *props, MF_OBJECT_TYPE *obj_type, IUnknown **object)
 {
@@ -6262,12 +6377,17 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa
     IRtwqAsyncResult *result;
     RTWQASYNCRESULT *data;
     HRESULT hr;
+    WCHAR url_buffer[MAX_PATH];

     TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object);

     if (!url || !obj_type || !object)
         return E_POINTER;

+    url = workaround_http_scheme_handler(url, url_buffer);
+
+    TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object);
+
     if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler)))
         return hr;

@@ -6303,12 +6423,17 @@ static HRESULT WINAPI source_resolver_CreateObjectFromByteStream(IMFSourceResolv
     IRtwqAsyncResult *result;
     RTWQASYNCRESULT *data;
     HRESULT hr;
+    WCHAR url_buffer[MAX_PATH];

     TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface, stream, debugstr_w(url), flags, props, obj_type, object);

     if (!stream || !obj_type || !object)
         return E_POINTER;

+    url = workaround_http_scheme_handler(url, url_buffer);
+
+    TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface, stream, debugstr_w(url), flags, props, obj_type, object);
+
     if (FAILED(hr = resolver_get_bytestream_handler(stream, url, flags, &handler)))
         return MF_E_UNSUPPORTED_BYTESTREAM_TYPE;

@@ -6344,6 +6469,11 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
     IUnknown *inner_cookie = NULL;
     IRtwqAsyncResult *result;
     HRESULT hr;
+    WCHAR url_buffer[MAX_PATH];
+
+    TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state);
+
+    url = workaround_http_scheme_handler(url, url_buffer);

     TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state);
Swizzler121 commented 3 years ago

Weird. I don't know what happened with my install, but after I got past that first set of cutscenes using your mfplat.dll it just refuses to load any more, I even tried a new game and it refuses to load cutscenes. I'm wiping and reinstalling the game to see if that helps with a fresh install.

Here's my logs before the wipe: StandaloneWindows64_d3d11.log

StandaloneWindows64_dxgi.log

Player.log

(No new save, using the same one I uploaded previously, and I can't upload my full steam-1452500.log, it's 1.3gb, these are just the last 10000 lines.

10000-steam-1452500.tar.gz

GarethCorvine commented 3 years ago

Hello, I downloaded the latest version of Proton ( 6.19-GE-2 ) and replaced that dll file with your custom version, but the problem still seems to persist... ? The game will launch ( title screen, options menu etc. ), but I still get a black screen & freeze instead of the intro video. Am I missing anything?

Thanks for the work you're doing on this, by the way!

Swizzler121 commented 3 years ago

After a clean install still can't start a new game with your modified dll... There's something different about your setup that is letting you load the cutscenes.

Player.log

10000-steam-1452500.tar.gz

StandaloneWindows64_dxgi.log

StandaloneWindows64_d3d11.log

popsUlfr commented 3 years ago

@Swizzler121 @GarethCorvine Could you check for me that the workaround works with the demo on your end ? (1741410)

I can only say for certain that the workaround fixes the cutscenes on my end in the demo. I didn't want to purchase the full game until the problem was fixed but it seems the full game has something different.

GarethCorvine commented 3 years ago

I just wanted to test it, but it seems like you can't download the demo if you already bought the full version of a game... ? I even uninstalled the full game, but when I click on the demo download Steam will attempt to download the full game again. I usually don't download demo versions from Steam, so I don't know if this is normal.

popsUlfr commented 3 years ago

Try

steam steam://rungameid/1741410

in a terminal. It should download and run the demo.

Swizzler121 commented 3 years ago

Try

steam steam://rungameid/1741410

in a terminal. It should download and run the demo.

No dice here, just corrects it to the full title and downloads that.

EDIT: Interestingly, many people are having issues playing cutscenes in what I assume is windows according to their bug thread. Maybe there's more to this issue than just proton?

https://steamcommunity.com/app/1452500/discussions/0/2957167122119025921/

popsUlfr commented 3 years ago

EDIT: Interestingly, many people are having issues playing cutscenes in what I assume is windows according to their bug thread. Maybe there's more to this issue than just proton?

https://steamcommunity.com/app/1452500/discussions/0/2957167122119025921/

It's the missing vp8 decoder that causes the problem for those users. Glorious Eggroll's Proton has it working, so the remaining issue is the missing http: protocol scheme for mfplat in wine.

popsUlfr commented 3 years ago

@Swizzler121 @GarethCorvine I just bit the bullet and purchased the game and my workaround works for me in the full version too :/

Can you link me your full system information (like the steam report about the specs) ?

Could you launch the game with the following launch options

PROTON_DUMP_DEBUG_COMMANDS=1 %command%

Close the game then go to /tmp/proton_${USER} and edit the run script where WINEDEBUG="-all" to WINEDEBUG="+mfplat,+seh" and run the script like this:

./run |& tee wine.log

And upload the wine.log here.

EDIT: Here's the mfplat.dll compiled from the Glorious Eggroll Proton sources, I don't know if that makes any difference as they both work for me.

Swizzler121 commented 3 years ago

OS: Manjaro Linux x86_64 Kernel: 5.13.19-2-MANJARO Resolution: 2560x1440 (i've been running the game windowed) DE: Plasma 5.22.5 CPU: AMD Ryzen 7 3700X (16) @ 3.600GHz GPU: AMD ATI Radeon RX 580 (detects as 480 lots of places due to them all sharing the same driver) Memory: 32029MiB

Here's the log running the last dll, I'll try the new one and edit in my log/results from that. wine.log

full system info: sysinfo.tar.gz

EDIT: yeah, no change with the new DLL wine.log

popsUlfr commented 3 years ago

In the second log, the http request for second video fails for some reason

0168:err:wininet:open_http_connection create_netconn failed: 12029

Do you know if the port 16700 is user by something on your system ? (it's the one the game uses to serve its videos)

In the system info you seem to have your steamlibrary on another drive /mnt/gamedrv/games/steamapps, is that formatted using a linux filesystem, or ntfs/fat/exfat ? Is the wine prefix for the game (steamapps/compatdata/1452500) also located on that drive ?

I'am also seeing that your Steam Runtime 2 (soldier) is at build_id 0.20210920.0 while mine is at 0.20211013.0. I'm not really sure it helps the problem switching to the beta branch (maybe latest gstreamer dependencies?), if you want to try switching set your steam client to the beta branch then go to your tools section in your library and search for steam linux runtime. Install Steam Linux Runtime - Soldier and go to its properties > Betas > select client_beta.

Other difference is AMD vs Nvidia. Looking at the logs it manages to find the right file (except that wininet error), so it seems that there's something going on at the decoding stage.

I've been playing the game for hours already without issues using the workaround, hope we can get to the bottom of why it's not doing it for you.

kisak-valve commented 3 years ago

Hello @popsUlfr, in this context, only Steam Linux Runtime - Soldier would be relevant. The other runtime containers are not currently used by Proton.

popsUlfr commented 3 years ago

@kisak-valve Thanks for clearing that up! I went with the shotgun approach on that suggestion haha

Swizzler121 commented 3 years ago

Do you know if the port 16700 is user by something on your system ? (it's the one the game uses to serve its videos)

It's not as far as I can tell, I checked listening ports and it's not listed.

In the system info you seem to have your steamlibrary on another drive /mnt/gamedrv/games/steamapps, is that formatted using a linux filesystem, or ntfs/fat/exfat ?

It is using btrfs, where my main linux install drive is ext4. So it's a different filesystem, but still a linux one.

Is the wine prefix for the game (steamapps/compatdata/1452500) also located on that drive ?

No it's not, but I can attempt moving it if needed

I'am also seeing that your Steam Runtime 2 (soldier) is at build_id 0.20210920.0 while mine is at 0.20211013.0. I'm not really sure it helps the problem switching to the beta branch (maybe latest gstreamer dependencies?), if you want to try switching set your steam client to the beta branch then go to your tools section in your library and search for steam linux runtime. Install Steam Linux Runtime - Soldier and go to its properties > Betas > select client_beta.

I'll switch over and edit with the result. Another question, are we still needing to delete the temp files listed in your earlier post between runs, or is that issue solved?

EDIT: switched to the beta for soldier (verified build id match in system information after adding the beta and restarting steam, didn't change before restart), still not loading cutscenes

wine.tar.gz

popsUlfr commented 3 years ago

I'll switch over and edit with the result. Another question, are we still needing to delete the temp files listed in your earlier post between runs, or is that issue solved?

It's not downloading the files, so there shouldn't be any temp files to clean. It grabs the http response headers and uses the content-length to find the real file directly on the filesystem.

EDIT: switched to the beta for soldier (verified build id match in system information after adding the beta and restarting steam, didn't change before restart), still not loading cutscenes

Your log file only has 3 lines, can you do one with the WINEDEBUG properly set ?

Swizzler121 commented 3 years ago

Sorry! I didn't even notice it reset when I changed the version wine.tar.gz

popsUlfr commented 3 years ago

It's weird, in the first part it seems to successfully open and read the video so it should play, then it opens another one and that's where the connection fails.

You only get a black screen when starting a New Game and don't see the first video at all ?

Swizzler121 commented 3 years ago

You only get a black screen when starting a New Game and don't see the first video at all ?

correct, it shows the loading symbol, then when that fades away it just hangs on a black screen until i terminate the application.

popsUlfr commented 3 years ago

I just did a fresh steam install on my laptop (xps 13) (steam was never installed beforehand) with intel integrated graphics. Stock steam client (no beta), downloaded and extracted Proton-6.19-GE-2, replaced the mfplat.dll and the videos play fine.

Could you maybe create a new user account where you start steam fresh and use only the stock settings ? No external steamlibrary, install the game into ~/.local/share/Steam/steamapps/common.

Swizzler121 commented 3 years ago

i've done this, and it worked fine. So it appears it doesn't like that my library is on an external drive?

wine.tar.gz

popsUlfr commented 3 years ago

i've done this, and it worked fine. So it appears it doesn't like that my library is on an external drive?

Awesome news!

I can't see why using an external drive would cause issues in this instance. From your fresh steam install as the new user, try to add your external drive now with a different folder (like maybe something like /mnt/gamedrv/games2) so as to not reuse the existing one that already has games in it. Reinstall The Good Life to your external drive and retest. (or you can just move the game to the other drive using the storage manager in Steam Settings > Downloads > Steam Library Folders)

EDIT: Ok, "good" news I can reproduce it now on my end. I added an external drive and get the black screen issue. Btw, moving the game nukes all settings and saves (I backed them up fortunately), it recreates the prefix on the external drive from scratch. Actually, the prefix still exists on the initial drive.

Swizzler121 commented 3 years ago

Ok, "good" news I can reproduce it now on my end. I added an external drive and get the black screen issue.

cool, yeah I moved it to an external drive and the issue started again. interesting about the prefix, i'll see if I can figure anything out there by poking around at it.

popsUlfr commented 3 years ago

This looks like a general issue with Glorious Eggroll's Proton regarding mfplat (maybe also the official proton but I can't tell since the vp8 decoding seems non functional right now) and cross device steam library folders.

The game needs to be installed in the base steamlibrary folder in order to work. Custom proton versions can only be installed in the primary steam folder, so it might be related to that fact for some reason. I mean, if not for mfplat, proton seems to be fully functional for cross device steam libraries.

GarethCorvine commented 3 years ago

OK, I normally use a separate SSD specifically for my game installations. Because of what you discussed in the last few posts, I tried installing The Good Life in my main Steam folder, on my OS drive. ( Some ) progress: I could watch the intro video for the first time, but right at the end of the video the game froze again. ( This time the "skip" button was still visible, instead of a fully black screen. ) I launched the game again and tried to skip the video, right at the start, but this also resulted in a freeze ( this time with some of the video subtitles still visible/frozen ).

Swizzler121 commented 3 years ago

Okay! I've put about 4 hours into the game now after moving the game off my game drive, fix appears to be working. I did run into one oddity i'll try and reproduce: I died once, but instead of dying, it had the death dialog, then it just sat there. Animations were still playing, but it didn't actually progress and I had to forcequit the game. not sure if that's just a game bug or a proton thing.

Swizzler121 commented 3 years ago

OK, I normally use a separate SSD specifically for my game installations. Because of what you discussed in the last few posts, I tried installing The Good Life in my main Steam folder, on my OS drive. ( Some ) progress: I could watch the intro video for the first time, but right at the end of the video the game froze again. ( This time the "skip" button was still visible, instead of a fully black screen. ) I launched the game again and tried to skip the video, right at the start, but this also resulted in a freeze ( this time with some of the video subtitles still visible/frozen ).

Make sure you're using the newest version of the modified mfplat.dll provided above also make sure you're using Proton 6.19 GE 2 as the normal proton doesn't have the right media codecs yet. and if those don't work switch to the beta soldier as detailed above as we're both running the beta now. If all those fixes don't work upload the logs, popsUlfr gave a pretty detailed guide on how to set them all up above, if a dummy like me can figure it out anyway.

GarethCorvine commented 3 years ago

I did run into one oddity i'll try and reproduce: I died once, but instead of dying, it had the death dialog, then it just sat there. Animations were still playing, but it didn't actually progress and I had to forcequit the game. not sure if that's just a game bug or a proton thing.

It's a Swery game, so I'm sure there's bugs, aside from Proton related issues. :D

As for my issue with the game, I have the latest Proton GE version, should also have the correct DLL file, and use the latest version of the soldier runtime.

I'm currently trying the wine log thing, but I'm stuck at this step: ./run |& tee wine.log -- What exactly am I supposed to with this? I'm still fairly new to Linux and Wine. I opened the folder with the scripts in a terminal window and tried to enter these commands, but that didn't work. Do I need to do something else with it?

Swizzler121 commented 3 years ago

It's a Swery game, so I'm sure there's bugs, aside from Proton related issues. :D

true, I haven't been able to replicate it and have died with no hang since, so probably just a game issue.

I'm currently trying the wine log thing, but I'm stuck at this step: ./run |& tee wine.log

In your terminal, navigate to /tmp/proton{USER} (where user is your pc username) or if your explorer supports it, navigate to the directory in that, right click and open a terminal in that directory, then run that command, exactly as it's written. It runs the modified run file (be sure to edit it with the flags he specifies) in a terminal behind the game. When it crashes, exit the game, then press ctrl+c in the terminal to exit it, then upload the log which will be in that same /tmp/proton{USER} folder named wine.log, you might need to compress it as they get big FAST. If it's too big to upload even after compressing, you can try running tail to just grab the last several thousand lines or so.

popsUlfr commented 3 years ago

Wait the following is way easier to get a log:

In the launch options for the game (Properties... > General > Launch Options) put

PROTON_LOG=1 WINEDEBUG="+mfplat,+seh" %command%

It will create a ~/steam-1452500.log. You can compress it with gzip to reduce size:

gzip -9 ~/steam-1452500.log

@GarethCorvine As already stated, make sure you use the mfplat from this post https://github.com/ValveSoftware/Proton/issues/5195#issuecomment-945063078

GarethCorvine commented 3 years ago

I think I got everything right, but I get the same error message as before:

wine: could not load ntdll.so: /home/user/.steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib//wine/ntdll.so: cannot open shared object file: No such file or directory

Seems to me like it's looking for the file in the wine main folder, while it should target the sub-folder "i386-windows"? At least I found an ntdll.dll there. Is this some configuration issue, or am I missing some important wine files, for this type of troubleshooting?

GarethCorvine commented 3 years ago

Yes, I have the correct mfplat.dll -- Just checked again. Currently trying that alternate log method. Where does it place the log files when done?

GarethCorvine commented 3 years ago

Here you go, I hope it worked properly: steam-1452500.log.gz

I started the game and left it running until it froze again, after the intro scene.

popsUlfr commented 3 years ago

wine: could not load ntdll.so: /home/user/.steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib//wine/ntdll.so: cannot open shared object file: No such file or directory

Seems to me like it's looking for the file in the wine main folder, while it should target the sub-folder "i386-windows"? At least I found an ntdll.dll there. Is this some configuration issue, or am I missing some important wine files, for this type of troubleshooting?

That doesn't look right at all. Delete the whole Proton-6.19-GE-2 and extract it again from the archive. Remove the compatdata folder for the game too for good measure : steamapps/compatdata/1452500 Make sure the mfplat.dll is at Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/mfplat.dll.

Yes, I have the correct mfplat.dll -- Just checked again. Currently trying that alternate log method. Where does it place the log files when done?

It's placed in your user folder by default.

I started the game and left it running until it froze again, after the intro scene.

It's weird because it's logging the decoding process just fine, so a video should be playing. Are you using flatpak steam ?

GarethCorvine commented 3 years ago

Yep, replaced the Proton GE folder, placed the custom DLL, deleted and rebuilt the compatdata folder, and just gave it another try, but as expected it's still the same problem. The intro video plays just fine, but then after it always freezes with a black screen.

I use Linux Mint, and I think I installed Steam with the built-in software manager. That seems to be flatpak based? Is that version of Steam different somehow? I mean, all my other games work fine, and the client itself does frequent automatic updates, so it should be recent as well.

popsUlfr commented 3 years ago

Can you share your steam system report ?

Copying the steps from the issue template:

  1. You can find your driver and Linux version, as well as your graphics processor's name in the system information report of Steam.
  2. You can retrieve a full system information report by clicking Help > System Information in the Steam client on your machine.
  3. Please copy it to your clipboard by pressing Ctrl+A and then Ctrl+C. Then paste it in a Gist and post the link in this issue.
GarethCorvine commented 3 years ago

Replying to https://github.com/ValveSoftware/Proton/issues/5195#issuecomment-945661087

Here: https://gist.github.com/GarethCorvine/88dd721260b48aa31044e3c08307d7a4

Can you access it via this link, or do I need to make it "public"?

popsUlfr commented 3 years ago

Can you access it via this link, or do I need to make it "public"?

Yes, thanks. It's not secret anymore when you link it :)

Kernel Version:  4.15.0-20-generic

That's quite the old kernel. We are at 5.14 currently, it also doesn't have the futex2 patches which leaves a bit of performance on the table. Maybe look into using the xanmod kernel: https://xanmod.org/

The nvidia driver is also quite old at this point (450.80.02 vs 470.74) which is higher priority in updating I would say.

GarethCorvine commented 3 years ago

Yes, I think I haven't made any kernel upgrades ever since I originally set up this PC. As I mentioned, I'm not very experienced with Linux, so I didn't want to mess around too much with the OS. I was planning to upgrade the kernel once I manage to get my hands on a new GPU. Is that kernel you linked compatible with Linux Mint? I guess the distributions like Mint essentially just provide the outer appearance and QOL aspects of the OS?

And I just upgraded the display driver to version 460 ( I tried 470 at first, but it gave me an error message, while 460 worked right away ). Just tried running the game again, but it still freezes. Do you think it could be display driver related? It didn't really occur to me, as I've been running other recent, more "high-end" games recently without issues. And The Good Life looks so simple and outdated in comparison, but maybe that doesn't mean much.

popsUlfr commented 3 years ago

I think you should also try checking with a fresh user account. You create a new user account and launch steam fresh, install proton ge and the game in the primary steam library.

Other than that you would surely benefit from upgrading your distribution especially for gaming, there are so many updates every week that help the various games to run. I can't say for certain it will help this particular problem, but I'm not seeing anything wrong in the log.

KGOrphanides commented 3 years ago
* [mfplat.dll.gz](https://github.com/ValveSoftware/Proton/files/7359801/mfplat.dll.gz)
* sha256sum: `a4826df09499c105d45df1cbb7c3ff43fbe7a65a97376839a9e24d7d8cc66a11`
* `~/.local/share/Steam/compatibilitytools.d/Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/mfplat.dll`

This worked for me to render the full game playable (at least past the first two cutscenes so far) on Pop!_OS 21.04. Thank you very much @popsUlfr

On a second attempt - think I borked Proton-6.19-GE-2 by accidentally copying mfplat over the wrong file the first time. Quitting Steam, deleting Proton-6.19-GE-2, putting a fresh copy in and copying the revised file over ~/.steam/root/compatibilitytools.d/Proton-6.19-GE-2/files/lib64/wine/x86_64-windows/mfplat.dll

My system in case anyone needs to compare notes: https://gist.github.com/KGOrphanides/f65f3a0cae51864e3f770f3f31f138ab

Edit: I have an second steam drive mounted but the game is on my primary drive.

GarethCorvine commented 3 years ago

OK, made some progress and got some new info to work with. I managed to switch the GPU driver to version 470, so it should be up to date now. Tried to run the game again, but skipping the intro video or watching it until the end still results in a freeze/black screen. So I tried something else -- I downloaded the save games you guys posted earlier in this thread, and sure enough, the game runs smoothly and seems stable! However, as soon as I encountered another pre-rendered video sequence, the game froze again ( at the end of the video ).

So the GPU driver is fine, and the in-game graphics work, but there still seems to be something fishy about the video sequences, and how the game handles them?