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
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,15 @@ private void ProcessUserInformation(LoginResponse response)
void CreateNewAPIKey()
{
int gameId = LootLockerEditorData.GetSelectedGame();
if (gameId == 0)
if (gameId == 0 || !gameData.ContainsKey(gameId))
{
ShowPopup("Error", "No active Game found!");
return;
}

if (isStage && gameData.ContainsKey(gameId))
{
gameId = gameData[gameId].development.id;
}

ShowLoadingAndExecute(() =>
{
LootLockerAdminManager.GenerateKey(gameId, newApiKeyName.value, "game", (onComplete) =>
LootLockerAdminManager.GenerateKey(gameData[gameId].development.id, newApiKeyName.value, "game", (onComplete) =>
{
if (!onComplete.success)
{
Expand All @@ -168,16 +163,15 @@ public void RefreshAPIKeys()
if (apiKeyList != null) apiKeyList.Clear();

int gameID = LootLockerEditorData.GetSelectedGame();
if (isStage && gameData.ContainsKey(gameID))
if (gameID == 0 || !gameData.ContainsKey(gameID))
{
gameID = gameData[gameID].development.id;
ShowPopup("Error", "No active Game found!");
return;
}

isLoadingKeys = true;

ShowLoadingAndExecute(() =>
{
LootLockerAdminManager.GetAllKeys(gameID, (onComplete) =>
LootLockerAdminManager.GetAllKeys(gameData[gameID].development.id, (onComplete) =>
{
if (!onComplete.success)
{
Expand All @@ -190,8 +184,6 @@ public void RefreshAPIKeys()
{
APIKeyTemplate(key);
}

isLoadingKeys = false;
HideLoading();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ private void OnGameSelected(EventBase e)
gameName.text = selectedGameData.name;
UpdateLicenseCountdownUI();

LootLockerEditorData.SetEnvironmentStage();
isStage = true;

ShowLoadingAndExecute(() =>
{
LootLockerAdminManager.GetGameDomainKey(LootLockerEditorData.GetSelectedGame(), (onComplete) =>
Expand All @@ -96,7 +93,7 @@ private void OnAPIKeySelected(EventBase e)

LootLockerConfig.current.apiKey = target.name;
SwapNewSelectedKey();
ShowPopup("API Key Selected", $"API Key {target.name} is now active.");
ShowPopup("API Key Selected", $"API Key {target.name} is now active.", Color.green);
}

private void LicenseCountdownIconClick(MouseDownEvent evt)
Expand Down Expand Up @@ -125,9 +122,10 @@ private void OnEditorUpdate()
EditorApplication.QueuePlayerLoopUpdate();
}

private void ShowPopup(string title, string message)
private void ShowPopup(string title, string message, Color? titleColor = null)
{
if (popupTitle != null) popupTitle.text = title;
if (titleColor.HasValue && popupTitle != null) popupTitle.style.color = titleColor.Value;
if (popupMessage != null) popupMessage.text = message;
if (popup != null) popup.style.display = DisplayStyle.Flex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void APIKeyTemplate(KeyResponse key)
if (button.name == LootLockerConfig.current.apiKey)
{
button.style.borderRightColor = button.style.borderLeftColor =
button.style.borderTopColor = button.style.borderBottomColor = stage;
button.style.borderTopColor = button.style.borderBottomColor = new Color(0.094f, 0.749f, 0.352f, 1);
button.style.backgroundColor = new StyleColor(new Color(0.2f, 0.5f, 0.2f, 1f));
}

Expand Down Expand Up @@ -106,7 +106,7 @@ void SwapNewSelectedKey()
if (key.name == LootLockerConfig.current.apiKey)
{
key.style.borderRightColor = key.style.borderLeftColor =
key.style.borderTopColor = key.style.borderBottomColor = stage;
key.style.borderTopColor = key.style.borderBottomColor = new Color(0.094f, 0.749f, 0.352f, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you extract this to a variable instead?
If we extend on this in the future, we would most likely want to reuse this color and not want to type it in manually.

key.style.backgroundColor = new StyleColor(new Color(0.2f, 0.5f, 0.2f, 1f));
}
else
Expand Down
39 changes: 1 addition & 38 deletions Runtime/Editor/Editor UI/LootLockerAdminExtension.UI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void InitializeUIElements()
if (visualTree == null)
{
// Try to load from Packages
visualTree = EditorGUIUtility.Load("Packages/com.lootlocker.lootlockersdk/Runtime/Editor UI/LootLockerAdminExtension.uxml") as VisualTreeAsset;
visualTree = EditorGUIUtility.Load("Packages/com.lootlocker.lootlockersdk/Runtime/Editor/Editor UI/LootLockerAdminExtension.uxml") as VisualTreeAsset;
}
if (visualTree == null)
{
Expand All @@ -53,7 +53,6 @@ public void InitializeUIElements()
InitializeStyleColors();
InitializeUIReferences(root);
InitializeEventHandlers();
InitializeEnvironmentUI();
InitializeLoadingIcon(root);
InitializeLicenseCountdownUI(root);
}
Expand All @@ -69,19 +68,11 @@ private void CreateSecurityWarning(VisualElement root)

private void InitializeStyleColors()
{
live.value = new Color(0.749f, 0.325f, 0.098f, 1);
stage.value = new Color(0.094f, 0.749f, 0.352f, 1);
defaultButton.value = new Color(0.345f, 0.345f, 0.345f, 1);
}

private void InitializeUIReferences(VisualElement root)
{
// Environment
environmentBackground = root.Q<VisualElement>("SwitchBackground");
environmentHandle = root.Q<VisualElement>("Handle");
environmentElement = root.Q<VisualElement>("Environment");
environmentTitle = root.Q<Label>("EnvironmentTitle");

// Basic UI elements
gameName = root.Q<Label>("GameName");
menu = root.Q<VisualElement>("MenuBar");
Expand Down Expand Up @@ -157,7 +148,6 @@ private void InitializeUIReferences(VisualElement root)
private void SetInitialDisplayStates()
{
if (menuLogoutBtn != null) menuLogoutBtn.style.display = DisplayStyle.None;
if (environmentElement != null) environmentElement.style.display = DisplayStyle.None;
if (menu != null) menu.style.display = DisplayStyle.None;
if (loginFlow != null) loginFlow.style.display = DisplayStyle.None;
if (mfaFlow != null) mfaFlow.style.display = DisplayStyle.None;
Expand All @@ -169,9 +159,6 @@ private void SetInitialDisplayStates()

private void InitializeEventHandlers()
{
// Environment switcher
if (environmentBackground != null) environmentBackground.AddManipulator(new Clickable(evt => SwapEnvironment()));
if (environmentHandle != null) environmentHandle.AddManipulator(new Clickable(evt => SwapEnvironment()));

// Menu buttons
if (menuLogoutBtn != null) menuLogoutBtn.clickable.clicked += ConfirmLogout;
Expand Down Expand Up @@ -215,14 +202,6 @@ private void InitializeSettingsEventHandlers()
if (allowTokenRefreshToggle != null) allowTokenRefreshToggle.RegisterValueChangedCallback(evt => SaveAllowTokenRefresh(evt.newValue));
}

private void InitializeEnvironmentUI()
{
if (environmentBackground != null) environmentBackground.tooltip = "Stage";

isStage = LootLockerEditorData.IsEnvironmentStage();
UpdateEnvironmentUI();
}

private void InitializeLoadingIcon(VisualElement root)
{
loadingPage = root.Q<VisualElement>("LoadingBackground");
Expand Down Expand Up @@ -261,22 +240,6 @@ private void InitializeLicenseCountdownUI(VisualElement root)
if (licenseCountdownContainer != null) licenseCountdownContainer.style.display = DisplayStyle.None;
}

public void UpdateEnvironmentUI()
{
if (isStage)
{
if (environmentHandle != null) environmentHandle.style.alignSelf = Align.FlexStart;
if (environmentBackground != null) environmentBackground.style.backgroundColor = stage;
if (environmentTitle != null) environmentTitle.text = "Environment: Stage";
}
else
{
if (environmentHandle != null) environmentHandle.style.alignSelf = Align.FlexEnd;
if (environmentBackground != null) environmentBackground.style.backgroundColor = live;
if (environmentTitle != null) environmentTitle.text = "Environment: Live";
}
}

public void SetupSettingsButton()
{
if (settingsBtn != null)
Expand Down
61 changes: 0 additions & 61 deletions Runtime/Editor/Editor UI/LootLockerAdminExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace LootLocker.Extension
public partial class LootLockerAdminExtension : EditorWindow
{
#region State Variables
private bool isStage = true;
private bool isLoadingKeys = false;
private Dictionary<int, LootLocker.Extension.DataTypes.Game> gameData = new Dictionary<int, LootLocker.Extension.DataTypes.Game>();
private DateTime gameDataRefreshTime;
private readonly int gameDataCacheExpirationTimeMinutes = 1;
Expand All @@ -30,8 +28,6 @@ public partial class LootLockerAdminExtension : EditorWindow

#region Style Colors
[Header("Colors")]
private StyleColor stage;
private StyleColor live;
private StyleColor defaultButton;
#endregion

Expand All @@ -40,11 +36,6 @@ public partial class LootLockerAdminExtension : EditorWindow
private Label gameName;
private Label securityWarning;

// Environment
private VisualElement environmentBackground, environmentHandle;
private VisualElement environmentElement;
private Label environmentTitle;

// Flows
private VisualElement activeFlow;
private VisualElement loginFlow, mfaFlow, gameSelectorFlow, apiKeyFlow, settingsFlow;
Expand Down Expand Up @@ -163,42 +154,6 @@ public void CreateGUI()
#endregion

#region Flow Management
private bool IsStageOnlyGame()
{
int selectedGameId = LootLockerEditorData.GetSelectedGame();
if (!gameData.ContainsKey(selectedGameId)) return false;
var game = gameData[selectedGameId];
if (game.created_at == default(System.DateTime) || game.created_at == null) return false;
var cutoff = new System.DateTime(2025, 3, 10);
return game.created_at >= cutoff;
} void SwapEnvironment()
{
if (isLoadingKeys)
{
if (popup != null && popupTitle != null && popupMessage != null)
{
popupTitle.text = "Error";
popupMessage.text = "Please wait...";
popup.style.display = DisplayStyle.Flex;
}
if (loadingPage != null) loadingPage.style.display = DisplayStyle.None;
return;
}

isStage = !isStage;
RefreshAPIKeys();

if (isStage)
{
LootLockerEditorData.SetEnvironmentStage();
}
else
{
LootLockerEditorData.SetEnvironmentLive();
}

UpdateEnvironmentUI();
}

void SwapFlows(VisualElement newFlow)
{
Expand Down Expand Up @@ -257,7 +212,6 @@ private void ConfigureGameSelectorFlow()
if (emailField != null) emailField.value = "";
if (passwordField != null) passwordField.value = "";
SetMenuVisibility(apiKey: false, changeGame: false, logout: true);
if (environmentElement != null) environmentElement.style.display = DisplayStyle.None;
if (createApiKeyWindow != null) createApiKeyWindow.style.display = DisplayStyle.None;
CreateGameButtons();
}
Expand All @@ -270,20 +224,6 @@ private void ConfigureApiKeyFlow()
SetMenuVisibility(apiKey: true, changeGame: true, logout: true);
if (createApiKeyWindow != null) createApiKeyWindow.style.display = DisplayStyle.Flex;

// Show environment switcher only for non-stage-only games
if (environmentElement != null && environmentBackground != null && environmentHandle != null && environmentTitle != null)
{
if (!IsStageOnlyGame())
{
environmentElement.style.display = DisplayStyle.Flex;
environmentBackground.style.display = DisplayStyle.Flex;
environmentHandle.style.display = DisplayStyle.Flex;
}
else
{
environmentElement.style.display = DisplayStyle.None;
}
}
RefreshAPIKeys();
}

Expand All @@ -292,7 +232,6 @@ private void ConfigureSettingsFlow()
if (settingsBtn != null) settingsBtn.style.display = DisplayStyle.Flex;
if (licenseCountdownContainer != null) licenseCountdownContainer.style.display = DisplayStyle.None;
SetMenuVisibility(apiKey: true, changeGame: true, logout: true);
if (environmentElement != null) environmentElement.style.display = DisplayStyle.None;
if (createApiKeyWindow != null) createApiKeyWindow.style.display = DisplayStyle.None;
LoadSettingsUI();
}
Expand Down
11 changes: 1 addition & 10 deletions Runtime/Editor/Editor UI/LootLockerAdminExtension.uxml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@
<ui:Label tabindex="-1" text="LootLocker" display-tooltip-when-elided="true" name="GameName" style="align-items: flex-start; align-self: center; font-size: 28px; -unity-text-align: middle-left; text-overflow: clip; width: auto; white-space: nowrap; max-width: 750px; margin-left: 24px; justify-content: flex-start;" />
<ui:VisualElement name="LicenseCountdownContainer" style="flex-direction: row; align-items: center; align-self: center; margin-left: 12px;">
<ui:Label name="LicenseCountdownLabel" text="" style="font-size: 14px; color: rgb(255, 200, 0); margin-right: 4px; display: none;" />
<ui:Image name="LicenseCountdownIcon" style="width: 16px; height: 16px; display: none; cursor: link;" /> </ui:VisualElement>
<ui:VisualElement style="flex-grow: 1; flex-direction: row; align-items: center; justify-content: flex-end;"> <ui:VisualElement name="Environment" style="flex-grow: 0; flex-direction: row; flex-shrink: 1; align-self: center; justify-content: flex-end; margin-right: 8px; align-items: center;">
<ui:Label tabindex="-1" text="Environment: Stage" display-tooltip-when-elided="true" name="EnvironmentTitle" style="align-items: flex-start; align-self: center; font-size: 14px; -unity-text-align: middle-left; text-overflow: clip; white-space: nowrap; margin-right: 8px;" />
<ui:VisualElement name="SwitchBackground" class="environmentToStageBackground" style="flex-grow: 1; background-color: rgb(28, 232, 109); min-width: 40px; min-height: 26px; border-top-left-radius: 12px; border-top-right-radius: 12px; border-bottom-right-radius: 12px; border-bottom-left-radius: 12px; align-items: auto; align-self: center; max-width: 80px; justify-content: center; flex-shrink: 0;">
<ui:VisualElement name="Handle" style="flex-grow: 1; background-color: rgb(255, 255, 255); align-self: flex-start; align-items: flex-end; justify-content: flex-start; border-top-left-radius: 90px; border-top-right-radius: 90px; border-bottom-right-radius: 90px; border-bottom-left-radius: 90px; margin-right: 4px; margin-left: 4px; flex-shrink: 0; width: 20px; height: 20px; min-width: 20px; min-height: 20px; max-height: 20px; max-width: 20px; margin-top: 0;" />
</ui:VisualElement> </ui:VisualElement>
<ui:VisualElement name="SettingsContainer" style="flex-direction: row; align-items: center; align-self: center; margin-right: 24px;">
<ui:Button name="SettingsBtn" tooltip="Settings" style="width: 28px; height: 28px; align-self: center; background-color: rgba(60, 60, 60, 0); border-width: 1px; border-color: rgba(100,100,100,0.0); border-radius: 0px; font-size: 18px; cursor: link; display: none; color: rgb(200,200,200);" />
</ui:VisualElement>
</ui:VisualElement>
<ui:Image name="LicenseCountdownIcon" style="width: 16px; height: 16px; display: none; cursor: link;" /> </ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ContentView" style="flex-grow: 1; background-color: rgba(0, 0, 0, 0); margin-top: 0; opacity: 1; bottom: 0; top: 0; height: 100%;">
<ui:VisualElement name="MenuBar" style="flex-grow: 0; flex-shrink: 0; visibility: visible; display: flex; border-bottom-width: 2px; border-bottom-color: rgb(46, 46, 46); flex-direction: row; justify-content: flex-start; align-self: auto; align-items: center; margin-left: 0; margin-bottom: 12px; min-height: 40px;">
Expand Down
17 changes: 0 additions & 17 deletions Runtime/Editor/LootLockerEditorData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class LootLockerEditorData
private static string adminToken = prefix + "AdminToken";
private static string selectedGameID = prefix + "SelectedGameID";
private static string selectedGameName = prefix + "SelectedGameName";
private static string environment = prefix + "Environment";
private static string firstTimeWelcome = prefix + "FirstTimeWelcome";
private static string newSession = prefix + "NewSession";

Expand All @@ -20,7 +19,6 @@ public static void ClearLootLockerPrefs()
EditorPrefs.DeleteKey(adminToken);
EditorPrefs.DeleteKey(selectedGameID);
EditorPrefs.DeleteKey(selectedGameName);
EditorPrefs.DeleteKey(environment);
EditorPrefs.DeleteKey(firstTimeWelcome);
EditorPrefs.DeleteKey(newSession);
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClearLootLockerPrefs() no longer deletes the legacy EditorPrefs key that older versions wrote (prefix + "Environment"). Consider still deleting that key (e.g. via an inline string) so users upgrading from older versions can fully reset LootLocker editor state from the Tools menu.

Suggested change
EditorPrefs.DeleteKey(newSession);
EditorPrefs.DeleteKey(newSession);
// Delete legacy environment key used by older versions so resets fully clear LootLocker editor state
EditorPrefs.DeleteKey(PlayerSettings.productGUID.ToString() + ".LootLocker.Environment");

Copilot uses AI. Check for mistakes.
}
Expand Down Expand Up @@ -56,21 +54,6 @@ public static string GetSelectedGameName()
return EditorPrefs.GetString(selectedGameName);
}

public static void SetEnvironmentStage()
{
EditorPrefs.SetString(environment, "Stage");
}

public static void SetEnvironmentLive()
{
EditorPrefs.SetString(environment, "Live");
}

public static bool IsEnvironmentStage()
{
return EditorPrefs.GetString(environment).Equals("Stage");
}

public static bool ShouldAutoShowWindow()
{
var result = EditorPrefs.GetBool(firstTimeWelcome, true);
Expand Down
4 changes: 1 addition & 3 deletions Runtime/Game/Resources/LootLockerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,7 @@ public static LootLockerConfig current
[HideInInspector] private static readonly string WssProtocol = "wss://";
[HideInInspector] private static readonly string UrlCore = "api.lootlocker.com";
[HideInInspector] private static string UrlCoreOverride =
#if LOOTLOCKER_TARGET_STAGE_ENV
"api.stage.internal.dev.lootlocker.cloud";
#elif LOOTLOCKER_TARGET_LOCAL_ENV
#if LOOTLOCKER_TARGET_LOCAL_ENV
"localhost:8080";
#else
null;
Comment on lines 417 to 421
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says stage env is retired and references removed, but the repo still has stage-targeting references in CI (e.g. .github/workflows/run-tests-and-package.yml sets LOOTLOCKER_TARGET_STAGE_ENV / LL_USE_STAGE). If stage is truly removed, CI config should be updated/removed as well to avoid misleading configuration and ensure the pipeline is testing the intended environment(s).

Copilot uses AI. Check for mistakes.
Expand Down
Loading