Skip to content

Commit 05b48c4

Browse files
unity-cli@v1.6.6 (#54)
- updated license server configuration inputs to accept raw json string - added additional unit tests for license server configuration
1 parent b08e3d2 commit 05b48c4

File tree

5 files changed

+76
-6
lines changed

5 files changed

+76
-6
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ A powerful command line utility for the Unity Game Engine. Automate Unity projec
5454
npm install -g @rage-against-the-pixel/unity-cli
5555
```
5656

57+
> [!IMPORTANT]
58+
> Requires Node v22.12 or higher.
59+
5760
## Usage
5861

5962
In general, the command structure is:
@@ -96,7 +99,7 @@ unity-cli license-version
9699
- `-e`, `--email`: Email associated with the Unity account. Required when activating a personal or professional license.
97100
- `-p`, `--password`: Password for the Unity account. Required when activating a personal or professional license.
98101
- `-s`, `--serial`: License serial number. Required when activating a professional license.
99-
- `-c`, `--config`: Path to the configuration file, or base64 encoded JSON string. Required when activating a floating license.
102+
- `-c`, `--config`: Path to the configuration file, raw JSON, or base64 encoded JSON string. Required when activating a floating license.
100103
- `--json`: Prints the last line of output as JSON string.
101104
- `--verbose`: Enable verbose output.
102105

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rage-against-the-pixel/unity-cli",
3-
"version": "1.6.5",
3+
"version": "1.6.6",
44
"description": "A command line utility for the Unity Game Engine.",
55
"author": "RageAgainstThePixel",
66
"license": "MIT",

src/license-client.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class LicensingClient {
9292
switch (process.platform) {
9393
case 'win32':
9494
// %PROGRAMDATA%\Unity\Config
95-
servicesConfigDirectory = path.join(process.env.PROGRAMDATA || '', 'Unity', 'Config');
95+
servicesConfigDirectory = path.join(process.env.PROGRAMDATA || 'C:\\ProgramData', 'Unity', 'Config');
9696
break;
9797
case 'darwin':
9898
// /Library/Application Support/Unity/config
@@ -119,6 +119,45 @@ export class LicensingClient {
119119
return path.join(servicesConfigDirectory, 'services-config.json');
120120
}
121121

122+
private tryParseJson(content: string | undefined): string | undefined {
123+
if (!content) {
124+
return undefined;
125+
}
126+
127+
try {
128+
JSON.parse(content);
129+
return content;
130+
} catch {
131+
return undefined;
132+
}
133+
}
134+
135+
private resolveServicesConfigContent(input: string): string {
136+
const trimmedInput = input.trim();
137+
138+
if (trimmedInput.length === 0) {
139+
throw new Error('Services config value is empty. Provide a file path, JSON, or base64 encoded JSON string.');
140+
}
141+
142+
const directJson = this.tryParseJson(trimmedInput);
143+
144+
if (directJson) {
145+
return directJson;
146+
}
147+
148+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
149+
if (base64Regex.test(trimmedInput)) {
150+
const decoded = Buffer.from(trimmedInput, 'base64').toString('utf-8').trim();
151+
const decodedJson = this.tryParseJson(decoded);
152+
153+
if (decodedJson) {
154+
return decodedJson;
155+
}
156+
}
157+
158+
throw new Error('Services config value is not a valid JSON string or base64 encoded JSON string.');
159+
}
160+
122161
/**
123162
* Gets the path to the Unity Licensing Client log file.
124163
* @see https://docs.unity.com/en-us/licensing-server/troubleshooting-client#logs
@@ -441,7 +480,8 @@ export class LicensingClient {
441480
fs.copyFileSync(options.servicesConfig, servicesConfigPath);
442481
}
443482
else {
444-
fs.writeFileSync(servicesConfigPath, Buffer.from(options.servicesConfig, 'base64'));
483+
const configContent = this.resolveServicesConfigContent(options.servicesConfig);
484+
fs.writeFileSync(servicesConfigPath, configContent, { encoding: 'utf-8' });
445485
}
446486

447487
if (process.platform !== 'win32') {

tests/license-client.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { LicensingClient } from '../src/license-client';
2+
3+
describe('LicensingClient services config handling', () => {
4+
const invokeResolver = (input: string) => {
5+
const client = new LicensingClient();
6+
return (client as any).resolveServicesConfigContent(input);
7+
};
8+
9+
it('accepts raw JSON input', () => {
10+
const json = '{"floatingServer":"https://example.com"}';
11+
expect(invokeResolver(json)).toBe(json);
12+
});
13+
14+
it('accepts base64 encoded JSON input', () => {
15+
const json = '{"floatingServer":"https://example.com"}';
16+
const encoded = Buffer.from(json, 'utf-8').toString('base64');
17+
expect(invokeResolver(encoded)).toBe(json);
18+
});
19+
20+
it('rejects invalid inline config', () => {
21+
expect(() => invokeResolver('not-a-valid-config')).toThrow('Services config value is not a valid JSON string or base64 encoded JSON string.');
22+
});
23+
24+
it('rejects empty inline config', () => {
25+
expect(() => invokeResolver(' ')).toThrow('Services config value is empty. Provide a file path, JSON, or base64 encoded JSON string.');
26+
});
27+
});

0 commit comments

Comments
 (0)