Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 95 additions & 3 deletions .github/workflows/run-tests-and-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
runs-on: [ubuntu-latest]
needs: []
timeout-minutes: 10
# Skip push events on ci/* branches (let pull_request handle them to avoid duplicates)
if: github.event_name != 'push' || !startsWith(github.ref, 'refs/heads/ci/')
env:
LL_USE_STAGE: false
strategy:
Expand Down Expand Up @@ -95,6 +97,21 @@ jobs:
restore-keys: |
${{ matrix.targetPlatform }}-Library-unity-sdk-smoketest-project
Library-
- name: Setup Unity environment
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Run Smoke Tests ${{ matrix.unityVersion }}-${{ matrix.testMode }}
id: editor-smoke-tests-gameci
uses: game-ci/unity-test-runner@v4.3.1
Expand All @@ -114,7 +131,6 @@ jobs:
name: Test SDK in StandaloneLinux64 build
runs-on: [ubuntu-latest]
needs: [editor-smoke-test]
if: false
timeout-minutes: 10
env:
LL_USE_STAGE: false
Expand Down Expand Up @@ -149,6 +165,21 @@ jobs:
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- name: Setup Unity environment for all builds
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Select stage keys
if: ${{ env.LL_USE_STAGE == 'true' }}
run: |
Expand Down Expand Up @@ -227,7 +258,7 @@ jobs:
runs-on: [ubuntu-latest]
needs: [editor-smoke-test]
timeout-minutes: 20
if: false && (startsWith(github.ref, 'refs/pull') && endsWith(github.base_ref, 'main')) || startsWith(github.ref, 'refs/tags/v') || (startsWith(github.ref, 'refs/heads') && endsWith(github.ref, 'main'))
if: (startsWith(github.ref, 'refs/pull') && endsWith(github.base_ref, 'main')) || startsWith(github.ref, 'refs/tags/v') || (startsWith(github.ref, 'refs/heads') && endsWith(github.ref, 'main')) || (startsWith(github.ref, 'refs/heads/ci'))
env:
LL_USE_STAGE: false
strategy:
Expand Down Expand Up @@ -261,6 +292,21 @@ jobs:
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- name: Setup Unity environment for WebGL build
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Select stage keys
if: ${{ env.LL_USE_STAGE == 'true' }}
run: |
Expand Down Expand Up @@ -505,6 +551,22 @@ jobs:
path: tests~/Library
key: Library-${{ matrix.unityVersion }}-${{ ENV.JSON_LIBRARY }}
restore-keys: Library-
- name: Setup Unity environment for integration tests
if: ${{ vars.ENABLE_INTEGRATION_TESTS == 'true' }}
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Run tests in ${{ matrix.unityVersion }} towards ${{ ENV.TARGET_ENVIRONMENT }} environment with json library ${{ ENV.JSON_LIBRARY }}
uses: game-ci/unity-test-runner@v4.3.1
if: ${{ vars.ENABLE_INTEGRATION_TESTS == 'true' }}
Expand Down Expand Up @@ -598,6 +660,21 @@ jobs:
restore-keys: |
${{ matrix.targetPlatform }}-Library-unity-sdk-sample-tester
Library-
- name: Setup Unity environment for sample tests
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Compile and run all sample scenes ${{ matrix.unityVersion }}
id: test-samples
uses: game-ci/unity-test-runner@v4.3.1
Expand All @@ -615,7 +692,7 @@ jobs:
validate-sdk:
name: Validate SDK
runs-on: [ubuntu-latest]
if: ${{ true == false }}
if: (startsWith(github.ref, 'refs/pull') && endsWith(github.base_ref, 'main')) || startsWith(github.ref, 'refs/tags/v') || (startsWith(github.ref, 'refs/heads') && endsWith(github.ref, 'main')) || (startsWith(github.ref, 'refs/heads/ci'))
needs: [editor-smoke-test]
timeout-minutes: 8
env:
Expand Down Expand Up @@ -736,6 +813,21 @@ jobs:
restore-keys: |
${{ matrix.targetPlatform }}-Library-unity-sdk-packager
Library-
- name: Setup Unity environment for packaging
run: |
# Install required system packages
sudo apt-get update
sudo apt-get install -y xvfb libx11-6 libxcursor1 libxrandr2 libasound2-dev
# Create Unity cache directory with proper permissions
sudo mkdir -p /root/.cache/unity3d
sudo chmod -R 777 /root/.cache/unity3d
# Start virtual framebuffer for headless Unity
export DISPLAY=:99
echo "DISPLAY=:99" >> $GITHUB_ENV
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 3
# Verify Xvfb is running
ps aux | grep Xvfb
- name: Package SDK for ${{ matrix.unityVersion }}
id: package-sdk-gameci
uses: game-ci/unity-test-runner@v4.3.1
Expand Down
36 changes: 32 additions & 4 deletions Runtime/Client/EndPointClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,50 @@ public EndPointClass(string endPoint, LootLockerHTTPMethod httpMethod, LootLocke

public string WithPathParameter(object arg0)
{
return string.Format(endPoint, WebUtility.UrlEncode(arg0.ToString()));
try {
return string.Format(endPoint, WebUtility.UrlEncode(arg0?.ToString() ?? "null"));
}
catch (FormatException e)
{
LootLockerLogger.Log($"Error formatting endpoint \"{endPoint}\" with path parameter \"{WebUtility.UrlEncode(arg0?.ToString() ?? "null")}\": {e}", LootLockerLogger.LogLevel.Error);
return endPoint;
}
}

public string WithPathParameters(object arg0, object arg1)
{
return string.Format(endPoint, WebUtility.UrlEncode(arg0.ToString()), WebUtility.UrlEncode(arg1.ToString()));
try {
return string.Format(endPoint, WebUtility.UrlEncode(arg0?.ToString() ?? "null"), WebUtility.UrlEncode(arg1?.ToString() ?? "null"));
}
catch (FormatException e)
{
LootLockerLogger.Log($"Error formatting endpoint \"{endPoint}\" with path parameters \"{WebUtility.UrlEncode(arg0?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg1?.ToString() ?? "null")}\": {e}", LootLockerLogger.LogLevel.Error);
return endPoint;
}
}

public string WithPathParameters(object arg0, object arg1, object arg2)
{
return string.Format(endPoint, WebUtility.UrlEncode(arg0.ToString()), WebUtility.UrlEncode(arg1.ToString()), WebUtility.UrlEncode(arg2.ToString()));
try {
return string.Format(endPoint, WebUtility.UrlEncode(arg0?.ToString() ?? "null"), WebUtility.UrlEncode(arg1?.ToString() ?? "null"), WebUtility.UrlEncode(arg2?.ToString() ?? "null"));
}
catch (FormatException e)
{
LootLockerLogger.Log($"Error formatting endpoint \"{endPoint}\" with path parameters \"{WebUtility.UrlEncode(arg0?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg1?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg2?.ToString() ?? "null")}\": {e}", LootLockerLogger.LogLevel.Error);
return endPoint;
}
}

public string WithPathParameters(object arg0, object arg1, object arg2, object arg3)
{
return string.Format(endPoint, WebUtility.UrlEncode(arg0.ToString()), WebUtility.UrlEncode(arg1.ToString()), WebUtility.UrlEncode(arg2.ToString()), WebUtility.UrlEncode(arg3.ToString()));
try {
return string.Format(endPoint, WebUtility.UrlEncode(arg0?.ToString() ?? "null"), WebUtility.UrlEncode(arg1?.ToString() ?? "null"), WebUtility.UrlEncode(arg2?.ToString() ?? "null"), WebUtility.UrlEncode(arg3?.ToString() ?? "null"));
}
catch (FormatException e)
{
LootLockerLogger.Log($"Error formatting endpoint \"{endPoint}\" with path parameters \"{WebUtility.UrlEncode(arg0?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg1?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg2?.ToString() ?? "null")}\", \"{WebUtility.UrlEncode(arg3?.ToString() ?? "null")}\": {e}", LootLockerLogger.LogLevel.Error);
return endPoint;
}
}
}
}
2 changes: 1 addition & 1 deletion Runtime/Client/LootLockerEndPoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public class LootLockerEndPoints
[Header("Catalogs")]
public static EndPointClass listCatalogs = new EndPointClass("catalogs", LootLockerHTTPMethod.GET);
public static EndPointClass deprecatedListCatalogItemsByKey = new EndPointClass("catalog/key/{0}/prices", LootLockerHTTPMethod.GET);
public static EndPointClass listCatalogItemsByKey = new EndPointClass("catalogs/inspired-ibex/v1/catalog/key/{key}/list", LootLockerHTTPMethod.GET);
public static EndPointClass listCatalogItemsByKey = new EndPointClass("catalogs/inspired-ibex/v1/catalog/key/{0}/list", LootLockerHTTPMethod.GET);

// Misc
[Header("Misc")]
Expand Down
9 changes: 6 additions & 3 deletions Runtime/Client/LootLockerHTTPClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,11 @@ private void CallListenersAndMarkDone(LootLockerHTTPExecutionQueueItem execution
executionItem.Done = true;
response.requestContext = new LootLockerRequestContext(executionItem.RequestData.ForPlayerWithUlid, executionItem.RequestData.RequestStartTime);
executionItem.Response = response;
if (!CompletedRequestIDs.Contains(executionItem.RequestData.RequestId))
{
CompletedRequestIDs.Add(executionItem.RequestData.RequestId);
}
executionItem.RequestData.CallListenersWithResult(response);
CompletedRequestIDs.Add(executionItem.RequestData.RequestId);
}

private IEnumerator RefreshSession(string refreshForPlayerUlid, string forExecutionItemId, Action<LootLockerSessionResponse, string, string> onSessionRefreshedCallback)
Expand Down Expand Up @@ -647,8 +650,6 @@ private IEnumerator RefreshSession(string refreshForPlayerUlid, string forExecut
}, refreshForPlayerUlid);
}
break;
case LL_AuthPlatforms.PlayStationNetwork:
case LL_AuthPlatforms.XboxOne:
case LL_AuthPlatforms.AmazonLuna:
{
LootLockerSDKManager.StartAmazonLunaSession(playerData.Identifier, (response) =>
Expand All @@ -658,6 +659,8 @@ private IEnumerator RefreshSession(string refreshForPlayerUlid, string forExecut
}, playerData.SessionOptionals);
}
break;
case LL_AuthPlatforms.PlayStationNetwork:
case LL_AuthPlatforms.XboxOne:
case LL_AuthPlatforms.NintendoSwitch:
case LL_AuthPlatforms.Steam:
{
Expand Down
9 changes: 8 additions & 1 deletion Runtime/Client/LootLockerHttpRequestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,14 @@ public void CallListenersWithResult(LootLockerResponse response)
{
foreach(var listener in Listeners)
{
listener?.Invoke(response);
try
{
listener?.Invoke(response);
}
catch (Exception e)
{
LootLockerLogger.Log($"Exception thrown in HTTP request listener for request id {RequestId}. Exception was: {e}.", LootLockerLogger.LogLevel.Error);
}
}
HaveListenersBeenInvoked = true;
}
Expand Down
9 changes: 8 additions & 1 deletion Runtime/Client/LootLockerStateData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ public static LootLockerPlayerData GetStateForPlayerOrDefaultStateOrEmpty(string
}
string playerULIDToGetDataFor = string.IsNullOrEmpty(playerULID) ? ActiveMetaData.DefaultPlayer : playerULID;

// Make this player the default for requests if there is no default yet or if the current default is not currently active
bool shouldBeMadeDefault = ActivePlayerData.Count == 0 && !playerULIDToGetDataFor.Equals(ActiveMetaData.DefaultPlayer, StringComparison.OrdinalIgnoreCase);

if (ActivePlayerData.TryGetValue(playerULIDToGetDataFor, out var data))
{
return data;
Expand All @@ -204,6 +207,10 @@ public static LootLockerPlayerData GetStateForPlayerOrDefaultStateOrEmpty(string
{
if (ActivePlayerData.TryGetValue(playerULIDToGetDataFor, out var data2))
{
if (shouldBeMadeDefault)
{
SetDefaultPlayerULID(data2.ULID);
}
return data2;
}
}
Expand Down Expand Up @@ -264,7 +271,7 @@ public static bool SetPlayerData(LootLockerPlayerData updatedPlayerData)
{
ActiveMetaData.WhiteLabelEmailToPlayerUlidMap[updatedPlayerData.WhiteLabelEmail] = updatedPlayerData.ULID;
}
if (string.IsNullOrEmpty(ActiveMetaData.DefaultPlayer))
if (string.IsNullOrEmpty(ActiveMetaData.DefaultPlayer) || !ActivePlayerData.ContainsKey(ActiveMetaData.DefaultPlayer))
{
SetDefaultPlayerULID(updatedPlayerData.ULID);
}
Expand Down
Loading
Loading