PlayEveryWare / eos_plugin_for_unity

Repository for PlayEveryWare's EOS Plugin for Unity, bringing the functionality of Epic Online Services to the Unity Game Engine.
https://eospluginforunity.playeveryware.com
288 stars 56 forks source link

epicsandboxid arg not coming through at runtime on dev, stage or even local builds? #450

Closed sampenguin closed 11 months ago

sampenguin commented 11 months ago

Describe the bug I've configured Sandbox Deployment Overrides in the editor to correspond with the 3 standard environment sandbox and deployment IDs (the primary set is set to Dev, and the two overrides are set to Stage and Live respectively). As described here https://github.com/PlayEveryWare/eos_plugin_for_unity/blob/917c50eb09878837d63fa3bb5a26aa3c2601487c/docs/egs/egs_readme.md#overriding-sandbox-andor-deployment-id

However, I cannot seem to get the app to pickup the override IDs in two test cases:

  1. When I run from the Stage install via EGS launcher, the app is still using the Dev sandbox ID. I see no logging of any changing of IDs from EOSManager.cs, which looks like it should be happening around line 574 in Init(). I know it's Init'ing though, because auth and everything else still works (just pointing at Dev still). I display sandbox and deployment IDs in a debug window, and they are definitely pointing to Dev still.
  2. When I run locally with a windows .exe build, but try to manually pass in -epicsandboxid=**** with a shortcut on EOSBootstrapper.exe, same as above, no debug info visible for Init. Additionally, I can verify that the arg is being passed in and recognized by Debug.Logging EOSManager.Instance.GetCommandLineArgsFromEpicLauncher()... so it's just not being applied to loadedEOSConfig.sandboxID and thus the deployment ID also remains wrong. So is Init just not running or completing somehow?

When I run in the editor, I can see the debug output from EOSManager.cs Init, but I'm not sure how to simulate passing an argument in in that case (and the default sandbox ID points to Dev).

Am I missing something to grab the arg at runtime properly? The docs and the code seem to suggest the EOSManager will handle it but it does not appear to.

To Reproduce

  1. Specify sandbox deployment overrides
  2. Build and deploy to dev and stage artifacts on EGS launcher.
  3. Install dev and stage versions in different locations.
  4. Run stage and sandboxID is still listed as dev.

Expected behavior The sandbox and deployment IDs are collected and set correctly at runtime by EOSManager during Init() so all subsequent calls are pointing at the correct distribution target.

Screenshots Screenshot 2023-11-01 164759

Desktop (please complete the following information):

sampenguin commented 11 months ago

FWIW, it looks to me like the problem is prob related to the code just above where the override logic happens in EOSManager, specifically

if (GetEOSPlatformInterface() != null)
{
    print("Init completed with existing EOS PlatformInterface");
...
return;
}

Looks like it exits before the overrides are set. Is that intentional?

sampenguin commented 11 months ago

Confirmed the above. Was able to confirm that "Init completed with existing EOS PlatformInterface" was triggering and returning early before the override code got reached.

If I hack the Unity package cache for EOSManager.cs and move the code section that handles the overrides (starting with var epicArgs = GetCommandLineArgsFromEpicLauncher(); above the check for if (GetEOSPlatformInterface() != null), then the overrides get applied correctly as expected.

Sidenote: This would be a little easier to work around if the EOSManager class was either set up to be inherited or if a few key private members/methods were exposed publicly. Namely the EOSConfig is locked up as private with no ability to set anything in it, so there's no clean way to deal with it in a custom way.

public void Init(IEOSCoroutineOwner coroutineOwner, string configFileName)
{
    UnityEngine.Debug.Log("EOSManager.Init");

    string eosFinalConfigPath = System.IO.Path.Combine(Application.streamingAssetsPath, "EOS", configFileName);
    if (loadedEOSConfig == null)
    {
        loadedEOSConfig = LoadEOSConfigFileFromPath(eosFinalConfigPath);
    }

    var epicArgs = GetCommandLineArgsFromEpicLauncher();

    if (!string.IsNullOrWhiteSpace(epicArgs.epicSandboxID))
    {
        UnityEngine.Debug.Log("Sandbox ID override specified: " + epicArgs.epicSandboxID);
        loadedEOSConfig.sandboxID = epicArgs.epicSandboxID;
    }

    if (loadedEOSConfig.sandboxDeploymentOverrides != null)
    {
        //check if a deployment id override exists for sandbox id
        foreach (var deploymentOverride in loadedEOSConfig.sandboxDeploymentOverrides)
        {
            if (loadedEOSConfig.sandboxID == deploymentOverride.sandboxID)
            {
                UnityEngine.Debug.Log("Sandbox Deployment ID override specified: " + deploymentOverride.deploymentID);
                loadedEOSConfig.deploymentID = deploymentOverride.deploymentID;
            }
        }
    }

    if (!string.IsNullOrWhiteSpace(epicArgs.epicDeploymentID))
    {
        UnityEngine.Debug.Log("Deployment ID override specified: " + epicArgs.epicDeploymentID);
        loadedEOSConfig.deploymentID = epicArgs.epicDeploymentID;
    }

    if (GetEOSPlatformInterface() != null)
    {
        print("Init completed with existing EOS PlatformInterface");                
        UnityEngine.Debug.Log("Init completed with existing EOS PlatformInterface");

        if (!hasSetLoggingCallback)
        {
            Epic.OnlineServices.Logging.LoggingInterface.SetCallback(SimplePrintCallback);
            hasSetLoggingCallback = true;
        }
#if UNITY_EDITOR
        SetLogLevel(LogCategory.AllCategories, LogLevel.VeryVerbose);
#else
        SetLogLevel(LogCategory.AllCategories, LogLevel.Warning);
#endif

        InitializeOverlay(coroutineOwner);
        return;
    }
paulhazen commented 11 months ago

If I hack the Unity package cache for EOSManager.cs and move the code section that handles the overrides (starting with var epicArgs = GetCommandLineArgsFromEpicLauncher(); above the check for if (GetEOSPlatformInterface() != null), then the overrides get applied correctly as expected.

@sampenguin Nice catch! You are correct in your assessment, and that fix looks like it's spot on. Do you want to open a PR for this change? It would certainly be welcomed. If not that's fine - I can make the change and open a PR. Sometimes it's just fun to have the glory for the fix :D

Sidenote: This would be a little easier to work around if the EOSManager class was either set up to be inherited or if a few key private members/methods were exposed publicly. Namely the EOSConfig is locked up as private with no ability to set anything in it, so there's no clean way to deal with it in a custom way.

Although I tend to agree with you, (as with a ton of things in engineering) there are historical reasons why this wasn't originally done, and the ROI for refactoring has (at this time) been deemed to be too low. Although this issue certainly illustrates the merit of such an endeavor.

arthur740212 commented 11 months ago

Hi, how the IDs work sure is a bit complicated.

Here is how it works on local builds : Because local builds do not provide a sandboxID on its own. The app will use the SandboxID and DeploymentID in the configs to initialize the SDK. But if SandboxDeploymentOverrides.SandboxID matches SandboxID, the DeploymentID would be overridden by SandboxDeploymentOverrides.DeploymentID.

Running from EGS however, has a set sandboxID provided in the command line arguments, The SandboxDeploymentOverrides were intended to map a deploymentID to the EGS provided sandboxID

sampenguin commented 11 months ago

Do you want to open a PR for this change? It would certainly be welcomed. If not that's fine - I can make the change and open a PR. Sometimes it's just fun to have the glory for the fix :D

Great, thanks! No glory needed, I'm on other priorities at the moment (and I don't have a writeable/pushable repo of this setup currently) but would appreciate a fix being integrated. Thank you!

arthur740212 commented 11 months ago

On standalone builds, the overrides aren't ran in the C# code, they are actually ran in the GfxPluginNativeRender dll. We did some tests through Epic Launcher but didn't find it behaving weird. That probably indicates that the GfxPluginNativeRender dll, maybe is on a previous version. If that is the case we'll update it in the next release.

paulhazen commented 11 months ago

@sampenguin We are confident that this issue will be resolved in the next release, so we have marked this issue as "pending." Let us know in the meantime if there is anything we can do beyond the workaround you are using.

arthur740212 commented 11 months ago

Hi @sampenguin , we got some new discoveries here. We test builds from package 3.0.2 and there seems to be no issue with the overrides, this rules out GfxPluginNativeRender malfunction that we suspected earlier. Now one thing that could happen, is the upload not actually ran from Epic Launcher. We'd like to know when you uploaded the game with the build patch tool, did you set the AppLaunch argument to EOSBootStrapper.exe? Side note, for more detailed debug logs add ENABLE_DEBUG_EOSMANAGER in the scripting definition symbols, this should dish out all init related logs.

sampenguin commented 11 months ago

We'd like to know when you uploaded the game with the build patch tool, did you set the AppLaunch argument to EOSBootStrapper.exe?

Ah, no. It's set to my app exe. My (apparently incorrect) interpretation was that EOSBootStrapper.exe was just for running standalone outside of the EGS Launcher, but after going back and looking through docs I guess EOSBootStrapper.exe should be the exe to launch in all cases outside of running from Unity editor?

arthur740212 commented 11 months ago

Actually, you might be right that EOSBootStrapper.exe is just for standalone without EGS Launcher, we always used EOSBootStrapper.exe so the alternative wasn't really tested. With this opportunity, it would great to know the truth of the mysterious EOSBootStrapper.exe, and if it actually does fix your problem. Would you mind running us through your setups again?

  1. How the EOS Unity Plugin was introduced in your project.
  2. How and where you uploaded your application, making sure the artifact matches the sandboxID argument that the app is providing.
  3. How your configurations looked like.
  4. Any extra logs
sampenguin commented 11 months ago

I just pushed out a new build to EGS Launcher with EOSBootStrapper.exe and it works as expected, although I looked back at the source code and my hack is still present in the EOSManager.cs (I assumed it would have been reset after an editor reload, which usually happens when I do things like that), so I can't confirm 100% yet if switching to the bootstrapper would solve it as well. I can do a more thorough test next week, I'm falling asleep at the computer right now... been a long week with lots of late nights for me. :)

  1. I imported via package manager with git URL (so it currently lives in Unity's package cache essentially).
  2. I do a StandaloneWindows64 build from Unity, that then gets run through Epic's BuildPatch Tool flow to upload an artifact to the EGS dashboard. I then deploy that to my Dev and Stage sandboxes.
  3. Which configurations are you referring to? The screenshot in my original post shows the basics, I don't think I did much beyond that unless there's a file or something you'd like me to send.
  4. Happy to send any log that you'd find useful, just point me in the direction to find them.
arthur740212 commented 11 months ago
  1. I imported via package manager with git URL (so it currently lives in Unity's package cache essentially).
  2. I do a StandaloneWindows64 build from Unity, that then gets run through Epic's BuildPatch Tool flow to upload an artifact to the EGS dashboard. I then deploy that to my Dev and Stage sandboxes.

This looks pretty much right. One thing to ask for a little bit more clarity. Was the game assigned to your account, and the game was run from the account? In other words, the game is in EGS standalone, not standalone standalone?

  1. Which configurations are you referring to? The screenshot in my original post shows the basics, I don't think I did much beyond that unless there's a file or something you'd like me to send.

Yes, that was the config we were looking for. One extra you could do is to make sure the config in the actual build folder looks the same.

  1. Happy to send any log that you'd find useful, just point me in the direction to find them.

The player logs should give us the most information, it could be found here. %USERPROFILE%\AppData\LocalLow\CompanyName\ProductName\Player.log

paulhazen commented 11 months ago

Hi @sampenguin Is this still an issue for you? I see that a couple weeks ago @arthur740212 asked some follow-up questions that could help us further diagnose the problem. Is that information you're able to provide, or has the problem been resolved for you?

paulhazen commented 11 months ago

I'm going to go ahead and close this issue. If anyone is still experiencing this problem, please re-open with the details of your problem, and any additional context that this thread asks for or otherwise discusses.