casc-cdn 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bogdan Tretyakov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # casc-cdn
2
+
3
+ A modern TypeScript library for downloading and extracting files from Blizzard's CASC (Content Addressable Storage Container) archives via CDN.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **High-level API** - Simple, intuitive interface for downloading game files
8
+ - 📦 **CDN-based** - Downloads directly from Blizzard's CDN servers (no game installation required)
9
+ - 💾 **Built-in caching** - Automatic file caching to minimize network requests
10
+ - 🔍 **File search** - Search files by path with case-insensitive matching
11
+ - ⚡ **Batch downloads** - Optimized multi-file downloads grouped by archive
12
+ - 📝 **Full TypeScript** - Complete type definitions included
13
+
14
+ ## Compatibility
15
+
16
+ ✅ **Tested with Warcraft III: Reforged**
17
+ ⚠️ **May work with other Blizzard games** (World of Warcraft, Diablo, etc.) but untested
18
+
19
+ ## Limitations
20
+
21
+ - ❌ No support for patch files
22
+ - ❌ No support for encrypted files
23
+ - ❌ Archive-only (requires files to be in archives, not loose CDN files)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install casc-cdn
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```typescript
34
+ import { CascClient, TactProduct } from 'casc-cdn';
35
+
36
+ // Initialize client for Warcraft III (EU region)
37
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
38
+
39
+ // Search for a file by path
40
+ const entries = client.getEntryByPath('itemfunc.txt');
41
+
42
+ if (entries.length > 0) {
43
+ // Download the file
44
+ const fileBuffer = await client.getFile(entries[0].contentKey);
45
+ console.log(fileBuffer.toString('utf8'));
46
+ }
47
+ ```
48
+
49
+ ## API Reference
50
+
51
+ ### Initialization
52
+
53
+ ```typescript
54
+ import { CascClient, TactProduct, CascCache } from 'casc-cdn';
55
+
56
+ // Use default cache (node_modules/.cache/casc-cdn)
57
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
58
+
59
+ // Use custom cache directory
60
+ const customCache = new CascCache('./my-cache');
61
+ const client = await CascClient.init(
62
+ TactProduct.WarcraftIII,
63
+ 'us',
64
+ customCache,
65
+ );
66
+ ```
67
+
68
+ **Available Regions:** `'us'` | `'eu'` | `'kr'` | `'cn'`
69
+
70
+ **Available Products:**
71
+
72
+ - `TactProduct.WarcraftIII` - Warcraft III: Reforged
73
+ - Other products may work but are untested
74
+
75
+ ### Searching Files
76
+
77
+ ```typescript
78
+ // Case-insensitive partial match
79
+ const entries = client.getEntryByPath('units.slk');
80
+
81
+ // Search returns an array of matching entries
82
+ entries.forEach((entry) => {
83
+ console.log(entry.contentKey); // File's content key (hash)
84
+ console.log(entry.localeFlags); // Locale information
85
+ });
86
+ ```
87
+
88
+ ### Downloading Files
89
+
90
+ #### Single File
91
+
92
+ ```typescript
93
+ // Download by content key
94
+ const fileBuffer = await client.getFile(contentKey);
95
+
96
+ if (fileBuffer) {
97
+ // File successfully downloaded
98
+ console.log(fileBuffer.toString('utf8'));
99
+ } else {
100
+ // File not found
101
+ console.log('File not available');
102
+ }
103
+ ```
104
+
105
+ #### Multiple Files (Batch)
106
+
107
+ ```typescript
108
+ // Promise-based: Returns all files at once
109
+ const files = await client.getFiles([cKey1, cKey2, cKey3]);
110
+ console.log(files[cKey1].toString('utf8'));
111
+
112
+ // Callback-based: Process files as they download
113
+ client.getFiles([cKey1, cKey2, cKey3], (cKey, data) => {
114
+ console.log(`Downloaded ${cKey}: ${data.length} bytes`);
115
+ });
116
+ ```
117
+
118
+ ## Examples
119
+
120
+ ### Example 1: Extract All Unit Data Files
121
+
122
+ ```typescript
123
+ import { CascClient, TactProduct } from 'casc-cdn';
124
+ import fs from 'fs/promises';
125
+
126
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
127
+
128
+ // Find all .slk files (unit data)
129
+ const slkFiles = client.getEntryByPath('.slk');
130
+
131
+ console.log(`Found ${slkFiles.length} SLK files`);
132
+
133
+ // Download all SLK files
134
+ const cKeys = slkFiles.map((entry) => entry.contentKey);
135
+ const files = await client.getFiles(cKeys);
136
+
137
+ // Save to disk
138
+ for (const [cKey, data] of Object.entries(files)) {
139
+ const entry = slkFiles.find((e) => e.contentKey === cKey);
140
+ const filename = entry?._normalizedPath?.split('/').pop() || cKey;
141
+ await fs.writeFile(`./output/${filename}`, data);
142
+ }
143
+
144
+ console.log('All SLK files extracted!');
145
+ ```
146
+
147
+ ### Example 2: Search and Download Locale File
148
+
149
+ ```typescript
150
+ import { CascClient, TactProduct } from 'casc-cdn';
151
+
152
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
153
+
154
+ // Search for item functions file
155
+ const entries = client.getEntryByPath('a01garithos01.flac');
156
+
157
+ const soundEntry = entries.find((e) => e.localeFlags.ruRU);
158
+
159
+ if (soundEntry) {
160
+ const fileData = await client.getFile(soundEntry.contentKey);
161
+
162
+ if (fileData) {
163
+ // Parse the file content
164
+ const content = fileData.toString('utf8');
165
+ const lines = content.split('\n');
166
+
167
+ console.log(`File has ${lines.length} lines`);
168
+ console.log('First 10 lines:');
169
+ console.log(lines.slice(0, 10).join('\n'));
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### Example 3: Custom Cache Location
175
+
176
+ ```typescript
177
+ import { CascClient, TactProduct, CascCache } from 'casc-cdn';
178
+
179
+ // Store cache in project directory
180
+ const cache = new CascCache('./casc-cache');
181
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu', cache);
182
+
183
+ // Subsequent runs will use cached data
184
+ const entries = client.getEntryByPath('units.slk');
185
+ const fileData = await client.getFile(entries[0].contentKey);
186
+ ```
187
+
188
+ ## How It Works
189
+
190
+ 1. **Initialization**: Fetches CDN configuration, version info, and builds internal indices
191
+ 2. **File Search**: Searches the root file for path-to-content-key mappings
192
+ 3. **File Lookup**: Resolves content keys to encoded keys via encoding table
193
+ 4. **Location Finding**: Locates files in archive indices
194
+ 5. **Download**: Downloads archive chunks from CDN
195
+ 6. **Decompression**: Decodes BLTE-compressed data
196
+ 7. **Caching**: Stores downloaded data for future use
197
+
198
+ ## Architecture
199
+
200
+ ```
201
+ CascClient
202
+ ├── BlizzardAPI - HTTP client for CDN requests
203
+ ├── CascCache - File-based caching layer
204
+ ├── EncodingTable - Maps content keys to encoded keys
205
+ ├── IndexTable - Maps encoded keys to archive locations
206
+ └── RootFile - Maps file paths to content keys
207
+ ```
208
+
209
+ ## License
210
+
211
+ MIT
212
+
213
+ ## Contributing
214
+
215
+ Contributions are welcome! Please feel free to submit issues or pull requests.
216
+
217
+ ## Acknowledgments
218
+
219
+ - Based on the [TACT protocol](https://wowdev.wiki/TACT) used by Blizzard Entertainment
220
+ - Inspired by various CASC implementations in the community
package/dist/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bogdan Tretyakov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # casc-cdn
2
+
3
+ A modern TypeScript library for downloading and extracting files from Blizzard's CASC (Content Addressable Storage Container) archives via CDN.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **High-level API** - Simple, intuitive interface for downloading game files
8
+ - 📦 **CDN-based** - Downloads directly from Blizzard's CDN servers (no game installation required)
9
+ - 💾 **Built-in caching** - Automatic file caching to minimize network requests
10
+ - 🔍 **File search** - Search files by path with case-insensitive matching
11
+ - ⚡ **Batch downloads** - Optimized multi-file downloads grouped by archive
12
+ - 📝 **Full TypeScript** - Complete type definitions included
13
+
14
+ ## Compatibility
15
+
16
+ ✅ **Tested with Warcraft III: Reforged**
17
+ ⚠️ **May work with other Blizzard games** (World of Warcraft, Diablo, etc.) but untested
18
+
19
+ ## Limitations
20
+
21
+ - ❌ No support for patch files
22
+ - ❌ No support for encrypted files
23
+ - ❌ Archive-only (requires files to be in archives, not loose CDN files)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install casc-cdn
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```typescript
34
+ import { CascClient, TactProduct } from 'casc-cdn';
35
+
36
+ // Initialize client for Warcraft III (EU region)
37
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
38
+
39
+ // Search for a file by path
40
+ const entries = client.getEntryByPath('itemfunc.txt');
41
+
42
+ if (entries.length > 0) {
43
+ // Download the file
44
+ const fileBuffer = await client.getFile(entries[0].contentKey);
45
+ console.log(fileBuffer.toString('utf8'));
46
+ }
47
+ ```
48
+
49
+ ## API Reference
50
+
51
+ ### Initialization
52
+
53
+ ```typescript
54
+ import { CascClient, TactProduct, CascCache } from 'casc-cdn';
55
+
56
+ // Use default cache (node_modules/.cache/casc-cdn)
57
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
58
+
59
+ // Use custom cache directory
60
+ const customCache = new CascCache('./my-cache');
61
+ const client = await CascClient.init(
62
+ TactProduct.WarcraftIII,
63
+ 'us',
64
+ customCache,
65
+ );
66
+ ```
67
+
68
+ **Available Regions:** `'us'` | `'eu'` | `'kr'` | `'cn'`
69
+
70
+ **Available Products:**
71
+
72
+ - `TactProduct.WarcraftIII` - Warcraft III: Reforged
73
+ - Other products may work but are untested
74
+
75
+ ### Searching Files
76
+
77
+ ```typescript
78
+ // Case-insensitive partial match
79
+ const entries = client.getEntryByPath('units.slk');
80
+
81
+ // Search returns an array of matching entries
82
+ entries.forEach((entry) => {
83
+ console.log(entry.contentKey); // File's content key (hash)
84
+ console.log(entry.localeFlags); // Locale information
85
+ });
86
+ ```
87
+
88
+ ### Downloading Files
89
+
90
+ #### Single File
91
+
92
+ ```typescript
93
+ // Download by content key
94
+ const fileBuffer = await client.getFile(contentKey);
95
+
96
+ if (fileBuffer) {
97
+ // File successfully downloaded
98
+ console.log(fileBuffer.toString('utf8'));
99
+ } else {
100
+ // File not found
101
+ console.log('File not available');
102
+ }
103
+ ```
104
+
105
+ #### Multiple Files (Batch)
106
+
107
+ ```typescript
108
+ // Promise-based: Returns all files at once
109
+ const files = await client.getFiles([cKey1, cKey2, cKey3]);
110
+ console.log(files[cKey1].toString('utf8'));
111
+
112
+ // Callback-based: Process files as they download
113
+ client.getFiles([cKey1, cKey2, cKey3], (cKey, data) => {
114
+ console.log(`Downloaded ${cKey}: ${data.length} bytes`);
115
+ });
116
+ ```
117
+
118
+ ## Examples
119
+
120
+ ### Example 1: Extract All Unit Data Files
121
+
122
+ ```typescript
123
+ import { CascClient, TactProduct } from 'casc-cdn';
124
+ import fs from 'fs/promises';
125
+
126
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
127
+
128
+ // Find all .slk files (unit data)
129
+ const slkFiles = client.getEntryByPath('.slk');
130
+
131
+ console.log(`Found ${slkFiles.length} SLK files`);
132
+
133
+ // Download all SLK files
134
+ const cKeys = slkFiles.map((entry) => entry.contentKey);
135
+ const files = await client.getFiles(cKeys);
136
+
137
+ // Save to disk
138
+ for (const [cKey, data] of Object.entries(files)) {
139
+ const entry = slkFiles.find((e) => e.contentKey === cKey);
140
+ const filename = entry?._normalizedPath?.split('/').pop() || cKey;
141
+ await fs.writeFile(`./output/${filename}`, data);
142
+ }
143
+
144
+ console.log('All SLK files extracted!');
145
+ ```
146
+
147
+ ### Example 2: Search and Download Locale File
148
+
149
+ ```typescript
150
+ import { CascClient, TactProduct } from 'casc-cdn';
151
+
152
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu');
153
+
154
+ // Search for item functions file
155
+ const entries = client.getEntryByPath('a01garithos01.flac');
156
+
157
+ const soundEntry = entries.find((e) => e.localeFlags.ruRU);
158
+
159
+ if (soundEntry) {
160
+ const fileData = await client.getFile(soundEntry.contentKey);
161
+
162
+ if (fileData) {
163
+ // Parse the file content
164
+ const content = fileData.toString('utf8');
165
+ const lines = content.split('\n');
166
+
167
+ console.log(`File has ${lines.length} lines`);
168
+ console.log('First 10 lines:');
169
+ console.log(lines.slice(0, 10).join('\n'));
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### Example 3: Custom Cache Location
175
+
176
+ ```typescript
177
+ import { CascClient, TactProduct, CascCache } from 'casc-cdn';
178
+
179
+ // Store cache in project directory
180
+ const cache = new CascCache('./casc-cache');
181
+ const client = await CascClient.init(TactProduct.WarcraftIII, 'eu', cache);
182
+
183
+ // Subsequent runs will use cached data
184
+ const entries = client.getEntryByPath('units.slk');
185
+ const fileData = await client.getFile(entries[0].contentKey);
186
+ ```
187
+
188
+ ## How It Works
189
+
190
+ 1. **Initialization**: Fetches CDN configuration, version info, and builds internal indices
191
+ 2. **File Search**: Searches the root file for path-to-content-key mappings
192
+ 3. **File Lookup**: Resolves content keys to encoded keys via encoding table
193
+ 4. **Location Finding**: Locates files in archive indices
194
+ 5. **Download**: Downloads archive chunks from CDN
195
+ 6. **Decompression**: Decodes BLTE-compressed data
196
+ 7. **Caching**: Stores downloaded data for future use
197
+
198
+ ## Architecture
199
+
200
+ ```
201
+ CascClient
202
+ ├── BlizzardAPI - HTTP client for CDN requests
203
+ ├── CascCache - File-based caching layer
204
+ ├── EncodingTable - Maps content keys to encoded keys
205
+ ├── IndexTable - Maps encoded keys to archive locations
206
+ └── RootFile - Maps file paths to content keys
207
+ ```
208
+
209
+ ## License
210
+
211
+ MIT
212
+
213
+ ## Contributing
214
+
215
+ Contributions are welcome! Please feel free to submit issues or pull requests.
216
+
217
+ ## Acknowledgments
218
+
219
+ - Based on the [TACT protocol](https://wowdev.wiki/TACT) used by Blizzard Entertainment
220
+ - Inspired by various CASC implementations in the community