radistmorse / PEPatch

Multiplayer patch for Planet Explorers
GNU General Public License v3.0
9 stars 4 forks source link

Linux Patch Support? #1

Open Erwan13430 opened 4 years ago

Erwan13430 commented 4 years ago

I'm actually on Linux and I would like to know if linux support was planned? indeed, when I put the pach files in the game folders, I don't have the Multiplayer button. Waiting for your answer.

Falling_Knife

radistmorse commented 4 years ago

As I wrote in the steam discussion, the patch itself should be multiplatform. Unity Doorstop, on the other hand, is not. There is a linux/macOS version of the unity doorstop available here: https://github.com/NeighTools/UnityDoorstop.Unix You can try it and see if it works.

But this only applies to the client patch, the server patch is different, since it includes steamworks, which is not multiplatform. You need to rebundle the steamworks libraries and rebuild the project. I don't think I will do it. The patch doesn't seem to be that popular to spend much time with it.

glabifrons commented 3 years ago

Add me (and my entire family) to the list of people who would love to see Linux support (we don't run Windows and don't have Macs). I'd be surprised if there weren't a lot more that just weren't speaking up. Sadly, I can't get it to run under Proton (Steam's Wine implementation), else I'd run the Windows version.

Either way, thank you very much for releasing this and keeping this game alive. I was really surprised to find it, as I didn't even look at the game for a very long time after their announcement about losing their server source code (obviously, since I only just learned of your work).

I've been experimenting with your suggestion and almost have the client side working.

After testing lots of combinations (since I have no idea how to use UnityDoorstop), I figured out that pointing it at PE_Launcher was the wrong answer, and instead went with PE_Client. Steam launches PE_Launcher (a simple script), which in turn runs PE_Launcher.x86 (whether you're running a 32 or 64 bit machine). PE_Launcher.x86 is only a simple GUI to select some very basic configs (resolution and that's about it, the others have only one "choice"). Once you click the "Start" button, it executes PE_Client. PE_Client then determines if you're 32 or 64 bit, and launches the PE_Client.x86 or PE_Client.x86_64 binary, respectively.

Because the run.sh script from UnityDoorstop.Unix and PE_Client did very similar things, I merged them. It took some iterations to figure out that it's the PEPatch.dll file that Doorstop wanted for the DOORSTOP_INVOKE_DLL_PATH variable. Here's the script, as I currently have it:

#!/usr/bin/env bash

export LANG=en

GAMENAME="PE_Client"
ARCH="x86"
if [ `getconf LONG_BIT` = "64" ]
then
ARCH="x86_64"
fi

doorstop_libname="libdoorstop_$ARCH.so"
doorstop_dir="$PWD"

export LD_LIBRARY_PATH="${doorstop_dir}":./"$GAMENAME"_Data/Plugins/"$ARCH"/:"$LD_LIBRARY_PATH"
export LD_PRELOAD="$doorstop_libname";

export DOORSTOP_ENABLE=TRUE;
# What .NET assembly to execute. Valid value is a path to a .NET DLL that mono can execute.
#export DOORSTOP_INVOKE_DLL_PATH="$doorstop_dir"/winhttp.dll;
#export DOORSTOP_INVOKE_DLL_PATH="$doorstop_dir"/0Harmony.dll;
export DOORSTOP_INVOKE_DLL_PATH="$doorstop_dir"/PEPatch.dll;

exec "./"$GAMENAME"."$ARCH "$@"

I'm wondering if the 0Harmony.dll and winhttp.dll file are somehow referenced by PEPatch.dll, as I don't see how else they're used (there are no other references to them than the above commented lines).

The end result is: I can get to the character configuration screen after the multiplayer button is pressed, but as soon as you hit the "Select" button (I think that's what it's called) to get past character design, the entire window goes away. Oddly enough, it doesn't stop running, it just isn't displayed anymore. I found the process still running, and when I ran strace on it, it was polling fd3. File descriptor 3 pointed to a socket, so it was just idling waiting for something to talk to it.

I apologize for my lack of knowledge about UnityDoorstop, and hope you can nudge me in the right direction. I'll write up everything I've done in detail so others can follow it if we can get this working.

radistmorse commented 3 years ago

winhttp should not be needed. It's a part of unity doorstop for windows. Well, actually, it IS unity doorstop for linux, since it's the library that unity tries to load if it is present, and that's how unity doorstop injects its code.

For linux, I also have no idea how doorstop works, LD_PRELOAD suggests that you just forcibly load a library, but who knows. My guess would be that winhhtp is not needed there. 0Harmony, on the other hand, is. PEPatch references it and is actually based on it.

As for weird polling and hanging, that may be because of steamworks.NET. There were some compile swichs for win/linux in it, which I hardcoded to win (https://github.com/radistmorse/PEPatch/blob/master/PEServerPatch/PEServerPatch.csproj#L29 although that's the server patch and not the client, but who knows). So first step would be to try the previous version of the patch (1.4) which doesn't use steam services. If it works, and if you do need steam services, we could work something out about compiling the linux version of that lib.

glabifrons commented 3 years ago

Thanks for the quick reply! You are exactly correct: LD_PRELOAD defines what libraries should be loaded before all others. That's why I merged the UnityDoorstop.Unix run.sh script with PE_Client, as PE_Client would have overridden that variable with other libraries in front.

I don't need Steam services for this, as I plan to run a server only for my family (so, LAN play). I switched to the 1.4 release as you suggested, and it no longer hangs in the background, but it still exits immediately when hitting the "Enter" button (sorry I couldn't remember what it said last time). Unfortunately, it lacks in debugging information, as least on STDOUT. I ran Steam from a shell and grabbed this when it PE crashed:

Game removed: AppID 237870 "", ProcID 11708 
Game 237870 created interface STEAMAPPLIST_INTERFACE_VERSION001 / AppList
Game 237870 created interface STEAMAPPS_INTERFACE_VERSION007 / Apps
Game 237870 created interface STEAMCONTROLLER_INTERFACE_VERSION / Controller
Game 237870 created interface STEAMHTMLSURFACE_INTERFACE_VERSION_003 / HTMLSurface
Game 237870 created interface STEAMHTTP_INTERFACE_VERSION002 / HTTP
Game 237870 created interface STEAMINVENTORY_INTERFACE_V001 / Inventory
Game 237870 created interface STEAMMUSICREMOTE_INTERFACE_VERSION001 / MusicRemote
Game 237870 created interface STEAMMUSIC_INTERFACE_VERSION001 / Music
Game 237870 created interface STEAMREMOTESTORAGE_INTERFACE_VERSION012 / RemoteStorage
Game 237870 created interface STEAMSCREENSHOTS_INTERFACE_VERSION002 / Screenshots
Game 237870 created interface STEAMUGC_INTERFACE_VERSION007 / UGC
Game 237870 created interface STEAMUNIFIEDMESSAGES_INTERFACE_VERSION001 / UnifiedMessages
Game 237870 created interface STEAMUSERSTATS_INTERFACE_VERSION011 / UserStats
Game 237870 created interface STEAMVIDEO_INTERFACE_V001 / Video
Game 237870 created interface SteamFriends015 / Friends
Game 237870 created interface SteamMatchMaking009 / Matchmaking
Game 237870 created interface SteamMatchMakingServers002 / MatchmakingServers
Game 237870 created interface SteamNetworking005 / Networking
Game 237870 created interface SteamUser018 / User
Game 237870 created interface SteamUtils007 / Utils
Game 237870 method call count for IClientRemoteStorage::SetCloudEnabledForApp : 1
Game 237870 method call count for IClientUserStats::GetAchievementDisplayAttribute : 16
Game 237870 method call count for IClientUserStats::GetAchievement : 17
Game 237870 method call count for IClientUserStats::RequestCurrentStats : 1
Game 237870 method call count for IClientApps::GetAppData : 2
Game 237870 method call count for IClientUtils::RecordSteamInterfaceCreation : 43
Game 237870 method call count for IClientUtils::GetAppID : 48
Game 237870 method call count for IClientUtils::GetImageRGBA : 3
Game 237870 method call count for IClientUtils::GetImageSize : 3
Game 237870 method call count for IClientFriends::GetFriendPersonaName_Public : 3
Game 237870 method call count for IClientFriends::SetListenForFriendsMessages : 1
Game 237870 method call count for IClientFriends::GetFriendGamePlayed : 3
Game 237870 method call count for IClientFriends::GetFriendByIndex : 1
Game 237870 method call count for IClientFriends::GetFriendCount : 1
Game 237870 method call count for IClientFriends::GetSmallFriendAvatar : 3
Game 237870 method call count for IClientFriends::GetFriendPersonaState : 3
Game 237870 method call count for IClientFriends::GetPersonaName : 1
Game 237870 method call count for IClientUser::GetSteamID : 2
Uploaded AppInterfaceStats to Steam
Exiting app 237870
No cached sticky mapping in ActivateActionSet.
(process:11874): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed

Note that I think that last line might not be related, as it seems to lag everything else by 1-2 seconds. I get the same error when launching nvidia-settings, and that works fine. Googling hasn't helped with that one (lots of reports going back over a decade, nothing resolved and appears harmless).

Do you know of a way to get debug info out of games launched within Steam?

Edit: Added the below.

I modified PA_Client to redirect STDOUT & STDERR (of that process) to files and got the below. I'm not sure if it's relevant though, as it's entirely printed before I even click the Multiplayer button.

Set current directory to /home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers
Found path: /home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers/PE_Client.x86_64
Mono path[0] = '/home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers/PE_Client_Data/Managed'
Mono path[1] = '/home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers/PE_Client_Data/Mono'
Mono config path = '/home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers/PE_Client_Data/Mono/etc'
No override (or failed to find), unsetting.
Managed dir: /home/glabifrons/.local/share/Steam/steamapps/common/Planet Explorers/PE_Client_Data/Managed
Got image: 0x2aa1ce0 
displaymanager : xrandr version warning. 1.6
client has 4 screens
displaymanager screen (0)(DP-0): 3840 x 2160
Using libudev for joystick management

Importing game controller configs

The other output still gets printed in the shell used to launch Steam, so it seems that it redirects STDOUT & STDERR at some point after launching.

radistmorse commented 3 years ago

GLib-GObject is definitely not related, it's from gnome. After you hit "enter" the char should be saved on disk. I tried not to use any windows-specific things for that, but I actually have no idea if the game uses the same code for disk operations on different OSes. Try to find the save folder and see if the char files get created. Also, the logs should be in the unity logfile. I don't know where unity stores its logs on linux, but it's probably something standard for all unity games.

mz1193 commented 1 year ago

Add me to the list of people who would like a Linux version. I've had success running the Windows version of PE with Proton, and the patch here seems to work (or at least at one point, did work) but as of now it seems like either people aren't hosting servers anymore, or there's some kind of problem (I'm unable to get my own server to show up in the list, for instance.) If there's a possibility for this patch to still work in general, it would be nice having a native option as well.