-
Notifications
You must be signed in to change notification settings - Fork 7
feat: Add support for file configurations #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for external file-based configuration of the LootLocker SDK, allowing settings to be loaded from a .bytes file at initialization. The implementation includes optional encryption for the configuration file and makes the SDK package name configurable.
Changes:
- Introduced
ExternalFileConfigclass for JSON-serializable SDK configuration - Added encryption utilities for optional config file obfuscation
- Refactored
LootLockerConfigto check for and load external file configurations on initialization - Updated log messages throughout the SDK to remove hardcoded "LootLocker" references, making them more generic
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Runtime/Game/Utilities/LootLockerEncryptionUtilities.cs | Implements AES encryption/decryption utilities for config files |
| Runtime/Game/Utilities/LootLockerEncryptionUtilities.cs.meta | Unity metadata for encryption utilities |
| Runtime/Game/Resources/LootLockerExternalFileConfig.cs | Defines serializable external configuration structure |
| Runtime/Game/Resources/LootLockerExternalFileConfig.cs.meta | Unity metadata for external config |
| Runtime/Game/Resources/LootLockerConfig.cs | Refactored to support file-based configuration loading with encryption support |
| Runtime/Game/Requests/WhiteLabelRequest.cs | Updated error messages to remove "LootLocker" prefix |
| Runtime/Game/LootLockerSDKManager.cs | Updated log messages for generic SDK references |
| Runtime/Game/LootLockerLogger.cs | Added configurable log label functionality |
| Runtime/Editor/LogViewer/LootLockerLogViewerUI.cs | Updated to handle new log label format |
| Runtime/Editor/Editor UI/LootLockerAdminExtension.cs | Fixed formatting spacing |
| Runtime/Client/LootLockerLifecycleManager.cs | Updated initialization log message |
| Runtime/Client/LootLockerHTTPClient.cs | Updated HTTP client log messages |
| Runtime/Client/LootLockerEventSystem.cs | Updated event system log message |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private static readonly byte[] Key = { | ||
| 0x81, 0x71, 0xF7, 0xD6, 0xE5, 0xC4, 0xB3, 0xA2, | ||
| 0x8A, 0x9B, 0xAC, 0xBD, 0xCE, 0xDF, 0xE0, 0xF1 | ||
| }; |
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded encryption key is embedded directly in the source code and will be visible in compiled assemblies. This provides minimal security as the key can be extracted through decompilation. Consider using a key derivation function or storing the key more securely, or document that this is intentionally basic encryption (as mentioned in the PR description) and should not be relied upon for security-critical data.
| // If directory does not exist, create it | ||
| if (!Directory.Exists(ConfigResourceFolder)) | ||
| { | ||
| Directory.CreateDirectory(ConfigResourceFolder); |
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directory creation can fail due to permissions or invalid paths. Add error handling with a meaningful error message to help developers diagnose issues when the config directory cannot be created.
| Directory.CreateDirectory(ConfigResourceFolder); | |
| try | |
| { | |
| Directory.CreateDirectory(ConfigResourceFolder); | |
| } | |
| catch (Exception ex) | |
| { | |
| Debug.LogError($"Failed to create config directory at path '{ConfigResourceFolder}'. Config asset will not be created. Exception: {ex}"); | |
| return; | |
| } |
| catch (Exception) | ||
| { |
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The catch block silently swallows all exceptions without logging. This makes debugging configuration issues difficult. Consider logging the exception details or at minimum a warning message when file config loading fails.
| catch (Exception) | |
| { | |
| catch (Exception ex) | |
| { | |
| Debug.LogWarning($"Failed to load external LootLocker config from file '{ConfigFilePath}'. Using default configuration instead. Exception: {ex}"); |
| _current.ConstructUrls(); | ||
| return _current; | ||
| } | ||
|
|
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing documentation for this important method. Add a summary comment explaining when this method is called, what it returns, and how it handles both encrypted and unencrypted config files.
| /// <summary> | |
| /// Attempts to load configuration values from an external config file in the Resources/Config folder. | |
| /// Called by the configuration initialization logic before falling back to the ScriptableObject asset. | |
| /// Returns a deserialized <see cref="ExternalFileConfig"/> when a valid config file with a non-empty api_key is found, | |
| /// or null when the file is missing, invalid, or does not contain a usable api_key. | |
| /// Handles both unencrypted JSON and encrypted config files: non-base64 content is treated as plain JSON, | |
| /// while valid base64 content is decrypted before deserialization. Any exceptions during loading or | |
| /// deserialization are caught and result in the method returning the last successfully read value or null. | |
| /// </summary> |
| } | ||
| return fileConfig; | ||
| } | ||
|
|
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing documentation for this method. Add a summary comment explaining when this method is called and what it creates.
| /// <summary> | |
| /// Creates a new <see cref="LootLockerConfig"/> asset in the configured Resources path | |
| /// when no existing configuration asset can be found, and assigns it to <c>_current</c>. | |
| /// </summary> |
| { | ||
| // Skip regular HTTP log lines (let the enriched HTTP log handle it) | ||
| if (message.StartsWith("[LL HTTP]") || message.StartsWith("[LL HTTP RESPONSE]")) | ||
| if (message.Contains("[HTTP]") || message.Contains("[HTTP RESPONSE]")) |
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Contains for prefix matching is less precise than StartsWith. If the intent is to filter HTTP log lines, consider using StartsWith with the log label to avoid false positives from messages that happen to contain "[HTTP]" elsewhere in the text.
| if (message.Contains("[HTTP]") || message.Contains("[HTTP RESPONSE]")) | |
| if (message.StartsWith("[HTTP]") || message.StartsWith("[HTTP RESPONSE]")) |
File Configurable SDK
This is the first step of the publisher package. What it does is it allows for a
.bytesfile to be automatically read by the SDK on boot. If it exists, then that file is used to set the LootLocker SDK configuration.Solves issue: https://github.com/lootlocker/index/issues/1260
Changes
LootLockerExternalFileConfigas a json serializable version of LootLockerConfigExtra Features