@@ -13,25 +13,88 @@ internal class Program
13
13
{
14
14
public static void Main ( string [ ] args )
15
15
{
16
- if ( args . Length < 4 ) return ;
16
+ if ( args . Length == 0 )
17
+ {
18
+ PrintUsage ( ) ;
19
+ Environment . Exit ( 1 ) ;
20
+ return ;
21
+ }
22
+ else if ( args [ 0 ] . ToLower ( ) == "pack" )
23
+ {
24
+ if ( args . Length <= 3 )
25
+ {
26
+ PrintUsage ( ) ;
27
+ Environment . Exit ( 1 ) ;
28
+ return ;
29
+ }
30
+ else if ( ( args . Length - 2 ) % 2 != 0 )
31
+ {
32
+ PrintUsage ( ) ;
33
+ Environment . Exit ( 1 ) ;
34
+ return ;
35
+ }
36
+
37
+ string outputFile = args [ 1 ] ;
17
38
18
- string inputDir = args [ 0 ] ;
19
- string outputFile = args [ 1 ] ;
39
+ if ( ! Path . IsPathRooted ( outputFile ) )
40
+ outputFile = Path . GetFullPath ( outputFile ) ;
20
41
21
- List < FileEntry > entries = new List < FileEntry > ( ) ;
22
- for ( int i = 2 ; i < args . Length ; i += 2 )
42
+ List < FileEntry > entries = new List < FileEntry > ( ) ;
43
+
44
+ for ( int i = 2 ; i < args . Length ; i += 2 )
45
+ {
46
+ FileEntry entry = new FileEntry ( ) ;
47
+
48
+ if ( ! Path . IsPathRooted ( args [ i ] ) )
49
+ entry . FullPath = Path . GetFullPath ( args [ i ] ) ;
50
+ else
51
+ entry . FullPath = args [ i ] ;
52
+
53
+ entry . OutputExportPath = args [ i + 1 ] ;
54
+
55
+ entries . Add ( entry ) ;
56
+ }
57
+
58
+ Pack ( entries . ToArray ( ) , outputFile ) ;
59
+ }
60
+ else if ( args [ 0 ] . ToLower ( ) == "unpack" )
23
61
{
24
- entries . Add ( new FileEntry ( )
62
+ if ( args . Length != 3 )
25
63
{
26
- FullPath = args [ i ] ,
27
- OutputExportPath = args [ i + 1 ]
28
- } ) ;
29
- }
64
+ PrintUsage ( ) ;
65
+ Environment . Exit ( 1 ) ;
66
+ return ;
67
+ }
68
+
69
+ string inputFile = args [ 1 ] ;
70
+
71
+ if ( ! Path . IsPathRooted ( inputFile ) )
72
+ inputFile = Path . GetFullPath ( inputFile ) ;
73
+
74
+ string outputFolder = args [ 2 ] ;
30
75
31
- Pack ( entries . ToArray ( ) , inputDir , outputFile ) ;
76
+ if ( ! Path . IsPathRooted ( outputFolder ) )
77
+ outputFolder = Path . GetFullPath ( outputFolder ) ;
78
+
79
+ Unpack ( inputFile , outputFolder ) ;
80
+ }
81
+ else
82
+ {
83
+ PrintUsage ( ) ;
84
+ }
32
85
}
33
86
34
- private static void Pack ( FileEntry [ ] files , string inputDirectory , string outputFile )
87
+ private static void PrintUsage ( )
88
+ {
89
+ Console . WriteLine ( "Usage:" ) ;
90
+ Console . WriteLine ( "\t " + "UnityPackager pack <output> [(<input-file> <target-path>)]..." ) ;
91
+ Console . WriteLine ( "\t " + "UnityPackager unpack <input-file> <output-folder>" ) ;
92
+ Console . WriteLine ( "Example:" ) ;
93
+ Console . WriteLine ( "\t " + "UnityPackager pack MyPackage.unitypackage MyFile.cs Assets/MyFile.cs" ) ;
94
+ Console . WriteLine ( "\t " + "UnityPackager unpack MyPackage.unitypackage MyProjectFolder" ) ;
95
+ }
96
+
97
+ private static void Pack ( FileEntry [ ] files , string outputFile )
35
98
{
36
99
string tempPath = Path . Combine ( Path . GetTempPath ( ) , Guid . NewGuid ( ) . ToString ( ) ) ;
37
100
Directory . CreateDirectory ( tempPath ) ;
@@ -41,22 +104,34 @@ private static void Pack(FileEntry[] files, string inputDirectory, string output
41
104
string guid = CreateGuid ( files [ i ] . OutputExportPath ) ;
42
105
43
106
Directory . CreateDirectory ( Path . Combine ( tempPath , guid ) ) ;
44
- File . Copy ( files [ i ] . FullPath , Path . Combine ( tempPath , guid , "asset" ) ) ;
107
+ File . Copy ( files [ i ] . FullPath , Path . Combine ( tempPath , guid , "asset" ) ) ;
108
+
45
109
File . WriteAllText ( Path . Combine ( tempPath , guid , "pathname" ) , files [ i ] . OutputExportPath ) ;
46
110
47
- using ( StreamWriter writer = new StreamWriter ( Path . Combine ( tempPath , guid , "asset.meta" ) ) )
111
+
112
+ string metaPath = Path . Combine ( Path . GetDirectoryName ( files [ i ] . FullPath ) , Path . GetFileNameWithoutExtension ( files [ i ] . FullPath ) + ".meta" ) ;
113
+
114
+ if ( File . Exists ( metaPath ) )
48
115
{
49
- new YamlStream ( new YamlDocument ( new YamlMappingNode ( )
50
- {
51
- { "guid" , guid } ,
52
- { "fileFormatVersion" , "2" }
53
- } ) ) . Save ( writer ) ;
116
+ File . Copy ( metaPath , Path . Combine ( tempPath , guid , "asset.meta" ) ) ;
54
117
}
55
-
56
- FileInfo metaFile = new FileInfo ( Path . Combine ( Path . Combine ( tempPath , guid , "asset.meta" ) ) ) ;
57
- using ( FileStream metaFileStream = metaFile . Open ( FileMode . Open ) )
118
+ else
58
119
{
59
- metaFileStream . SetLength ( metaFile . Length - 3 - Environment . NewLine . Length ) ;
120
+ using ( StreamWriter writer = new StreamWriter ( Path . Combine ( tempPath , guid , "asset.meta" ) ) )
121
+ {
122
+ new YamlStream ( new YamlDocument ( new YamlMappingNode ( )
123
+ {
124
+ { "guid" , guid } ,
125
+ { "fileFormatVersion" , "2" }
126
+ } ) ) . Save ( writer ) ;
127
+ }
128
+
129
+ FileInfo metaFile = new FileInfo ( Path . Combine ( Path . Combine ( tempPath , guid , "asset.meta" ) ) ) ;
130
+
131
+ using ( FileStream metaFileStream = metaFile . Open ( FileMode . Open ) )
132
+ {
133
+ metaFileStream . SetLength ( metaFile . Length - 3 - Environment . NewLine . Length ) ;
134
+ }
60
135
}
61
136
}
62
137
@@ -70,6 +145,7 @@ private static void Pack(FileEntry[] files, string inputDirectory, string output
70
145
using ( TarArchive archive = TarArchive . CreateOutputTarArchive ( zipStream ) )
71
146
{
72
147
archive . RootPath = tempPath . Replace ( '\\ ' , '/' ) ;
148
+
73
149
if ( archive . RootPath . EndsWith ( "/" ) )
74
150
archive . RootPath = archive . RootPath . Remove ( archive . RootPath . Length - 1 ) ;
75
151
@@ -81,10 +157,59 @@ private static void Pack(FileEntry[] files, string inputDirectory, string output
81
157
// Clean up
82
158
Directory . Delete ( tempPath , true ) ;
83
159
}
160
+
161
+ private static void Unpack ( string inputFile , string outputFolder )
162
+ {
163
+ string tempPath = Path . Combine ( Path . GetTempPath ( ) , Guid . NewGuid ( ) . ToString ( ) ) ;
164
+ Directory . CreateDirectory ( tempPath ) ;
165
+
166
+ using ( FileStream stream = new FileStream ( inputFile , FileMode . Open ) )
167
+ {
168
+ using ( GZipInputStream zipStream = new GZipInputStream ( stream ) )
169
+ {
170
+ using ( TarArchive archive = TarArchive . CreateInputTarArchive ( zipStream ) )
171
+ {
172
+ archive . ExtractContents ( tempPath ) ;
173
+ }
174
+ }
175
+ }
176
+
177
+ string [ ] dirEntries = Directory . GetDirectories ( tempPath ) ;
178
+
179
+ for ( int i = 0 ; i < dirEntries . Length ; i ++ )
180
+ {
181
+ if ( ! File . Exists ( Path . Combine ( dirEntries [ i ] , "pathname" ) ) || ! File . Exists ( Path . Combine ( dirEntries [ i ] , "asset" ) ) || ! File . Exists ( Path . Combine ( dirEntries [ i ] , "asset.meta" ) ) )
182
+ {
183
+ // Invalid format
184
+ continue ;
185
+ }
186
+
187
+ string targetPath = Path . Combine ( outputFolder , File . ReadAllText ( Path . Combine ( dirEntries [ i ] , "pathname" ) ) ) ;
188
+ string targetFileNameWithoutExtension = Path . GetFileNameWithoutExtension ( targetPath ) ;
189
+ string targetFolder = Path . GetDirectoryName ( targetPath ) ;
190
+ string targetMetaPath = Path . Combine ( outputFolder , targetFolder , targetFileNameWithoutExtension + ".meta" ) ;
191
+
192
+ if ( ! Directory . Exists ( targetFolder ) )
193
+ Directory . CreateDirectory ( targetFolder ) ;
194
+
195
+ if ( File . Exists ( targetPath ) )
196
+ File . Delete ( targetPath ) ;
197
+
198
+ if ( File . Exists ( targetMetaPath ) )
199
+ File . Delete ( targetMetaPath ) ;
200
+
201
+ File . WriteAllText ( targetPath , File . ReadAllText ( Path . Combine ( dirEntries [ i ] , "asset" ) ) ) ;
202
+ File . WriteAllText ( targetMetaPath , File . ReadAllText ( Path . Combine ( dirEntries [ i ] , "asset.meta" ) ) ) ;
203
+ }
204
+
205
+ // Clean up
206
+ Directory . Delete ( tempPath , true ) ;
207
+ }
84
208
85
209
private static void AddFilesInDirRecursive ( TarArchive archive , string directory )
86
210
{
87
211
string [ ] files = Directory . GetFiles ( directory ) ;
212
+
88
213
for ( int i = 0 ; i < files . Length ; i ++ )
89
214
{
90
215
TarEntry entry = TarEntry . CreateEntryFromFile ( files [ i ] ) ;
@@ -93,6 +218,7 @@ private static void AddFilesInDirRecursive(TarArchive archive, string directory)
93
218
}
94
219
95
220
string [ ] subDirs = Directory . GetDirectories ( directory ) ;
221
+
96
222
for ( int i = 0 ; i < subDirs . Length ; i ++ )
97
223
{
98
224
AddFilesInDirRecursive ( archive , subDirs [ i ] ) ;
@@ -107,6 +233,7 @@ private static string CreateGuid(string input)
107
233
byte [ ] hashBytes = md5 . ComputeHash ( inputBytes ) ;
108
234
109
235
StringBuilder stringBuilder = new StringBuilder ( ) ;
236
+
110
237
foreach ( byte b in hashBytes )
111
238
{
112
239
stringBuilder . Append ( b . ToString ( "X2" ) ) ;
0 commit comments