2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
										 
									
								 
							
							
								 using  System ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  System.Collections.Generic ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  System.Diagnostics ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  System.IO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  System.Linq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  System.Text ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 20:56:05 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  GarrysMod.AddonCreator.Hashing ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								using  Newtonsoft.Json ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 20:56:05 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								namespace  GarrysMod.AddonCreator.Addon 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 20:56:05 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								    public  class  AddonFile 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        private  const  byte  FormatVersion  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        private  const  uint  AppID  =  4000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        private  const  uint  CompressionSignature  =  0xbeefcace ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        private  static  readonly  byte [ ]  FormatIdent  =  Encoding . ASCII . GetBytes ( "GMAD" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 20:56:05 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Initializes a new instance of <see cref="AddonFile" /> 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 20:56:05 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  AddonFile ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Files  =  new  Dictionary < string ,  AddonFileInfo > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            RequiredContent  =  new  List < string > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Version  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Returns the timestamp of when the addon was built. This data is retrieved from full imports and for new (unsaved) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     addons this is 0. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  ulong  BuildTimestamp  {  get ;  private  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     The name of this addon. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  string  Title  {  get ;  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     The author of this addon. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  string  Author  {  get ;  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     A description of this addon. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  string  Description  {  get ;  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     This addon's version. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  int  Version  {  get ;  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     The files to include in the addon. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  Dictionary < string ,  AddonFileInfo >  Files  {  get ;  private  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Currently unused. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  ulong  SteamID  {  get ;  set ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Content that needs to exist in order to run this addon. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  List < string >  RequiredContent  {  get ;  private  set ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Imports a gmod addon into this instance. 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <param name="path">Path to a gmod addon file.</param> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  void  Import ( string  path ,  bool  withMetadata  =  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  stream  =  File . OpenRead ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-23 00:49:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  sr  =  new  BinaryReader ( stream ,  Encoding . GetEncoding ( "iso-8859-1" ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Check format header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                if  ( ! sr . ReadBytes ( 4 ) . SequenceEqual ( FormatIdent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    | |  sr . ReadByte ( )  ! =  FormatVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    throw  new  FormatException ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:09:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								#if DEBUG 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Check addon's CRC32 hash 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:09:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // TODO: Garry's code actually calculates CRC32 hashes differently in edge cases. The code used for it is from zlib-1.1.3. See https://github.com/garrynewman/bootil/blob/master/src/3rdParty/smhasher/crc.cpp#L4. 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . WriteLine ( "Checking CRC32..." ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  baseAddon  =  new  byte [ stream . Length  -  sizeof  ( int ) ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  oldpos  =  stream . Position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    stream . Position  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    stream . Read ( baseAddon ,  0 ,  baseAddon . Length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  baseAddonHash  =  sr . ReadInt32 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  calcAddonHash  =  Crc32 . Compute ( baseAddon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:09:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . WriteLine ( "\tCalculated hash: {0}; Wanted hash: {1}" ,  calcAddonHash ,  baseAddonHash ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . Assert ( calcAddonHash  = =  baseAddonHash ,  "CRC32 hash mismatch" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        "Calculated CRC32 hash is different from the one saved within the addon. Causes could be a corrupted file or the edge case bug https://github.com/icedream/gmadsharp/issues/2." ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    stream . Position  =  oldpos ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:09:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								# endif 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Import metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newSteamID  =  sr . ReadUInt64 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newBuildTimestamp  =  sr . ReadUInt64 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newRequiredContentLen  =  sr . ReadByte ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newTitle  =  sr . ReadString ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newDescription  =  sr . ReadString ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newAuthor  =  sr . ReadString ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newVersion  =  sr . ReadInt32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "## Metadata ##" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "Steam ID: {0}" ,  newSteamID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "Build time: {0}" ,  newBuildTimestamp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "Required content count: {0}" ,  newRequiredContentLen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . Assert ( newSteamID  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . Assert ( newRequiredContentLen  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                for  ( var  b  =  0 ;  b  <  newRequiredContentLen ;  b + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  value  =  sr . ReadString ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    if  ( withMetadata  & &  ! RequiredContent . Contains ( value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        RequiredContent . Add ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                if  ( withMetadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    SteamID  =  newSteamID ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    BuildTimestamp  =  newBuildTimestamp ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Title  =  newTitle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Description  =  newDescription ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Author  =  newAuthor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Version  =  newVersion ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // file list 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "## File list ##" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  newFilesList  =  new  Dictionary < string ,  Tuple < long ,  int > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  expectedFileId  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileId  =  sr . ReadUInt32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    if  ( fileId  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        break ;  // end of list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    // key, size, hash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  filePath  =  sr . ReadString ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileSize  =  sr . ReadInt64 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileHash  =  sr . ReadInt32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 02:37:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . WriteLine ( "\t#{2} : {0} ({1:0.0} kB)" ,  filePath ,  ( double ) fileSize / 1024 ,  fileId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . Assert ( fileId  = =  expectedFileId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    expectedFileId + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    // avoid duplicates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    if  ( newFilesList . ContainsKey ( filePath ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        throw  new  IOException ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                            "Found duplicate file path in addon file. Contact the addon creator and tell him to build a new proper addon file." ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    newFilesList . Add ( filePath ,  new  Tuple < long ,  int > ( fileSize ,  fileHash ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                }  while  ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Debug . WriteLine ( "## File import ##" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                foreach  ( var  file  in  newFilesList ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  filePath  =  file . Key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileSize  =  file . Value . Item1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileHash  =  file . Value . Item2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:08:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  filePosition  =  sr . BaseStream . Position ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 02:37:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . WriteLine ( "Analyzing: {0} ({1:0.00} kB)" ,  filePath ,  ( double ) fileSize  /  1024 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileContent  =  new  byte [ fileSize ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    // long-compatible file reading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    for  ( long  i  =  0 ;  i  <  fileSize ;  i  + =  int . MaxValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    { 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 02:41:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        sr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                            . ReadBytes ( ( int )  Math . Min ( int . MaxValue ,  fileSize ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                            . CopyTo ( fileContent ,  i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    // CRC check for this file 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    var  fileCalcHash  =  Crc32 . Compute ( fileContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:09:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Debug . WriteLine ( "\t\tCalculated hash: {0}; Wanted hash: {1}" ,  fileCalcHash ,  fileHash ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    if  ( fileCalcHash  ! =  fileHash ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        throw  new  IOException ( "File "  +  filePath  +  " in addon file is corrupted (hash mismatch)" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:08:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Files . Add ( filePath ,  new  SegmentedAddonFileInfo ( stream ,  filePosition ,  fileSize ,  fileHash ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        ///     Exports this addon into a GMA file. 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <param name="path">The output file path, should be pointing to a writable location ending with ".gma".</param> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  void  Export ( string  path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:34:42 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Enforce .gma extension 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            if  ( ! path . EndsWith ( ".gma" ,  StringComparison . OrdinalIgnoreCase ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  pathSplit  =  path . Split ( '.' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                pathSplit [ pathSplit . Length  -  1 ]  =  "gma" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                path  =  string . Join ( "." ,  pathSplit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Checking for existing addon.json 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            if  ( ! Files . ContainsKey ( "addon.json" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                throw  new  FileNotFoundException ( "Addon building requires a valid addon.json file." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 03:44:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  files  =  Files . ToDictionary ( i  = >  i . Key ,  i  = >  i . Value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            if  ( MinimizeLua ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                files  =  files 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    // minimize lua code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    . Select ( f  = >  f . Key . EndsWith ( ".lua" ,  StringComparison . OrdinalIgnoreCase ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        ?  new  KeyValuePair < string ,  AddonFileInfo > ( f . Key ,  new  MinifiedLuaAddonFileInfo ( f . Value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        :  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    . ToDictionary ( i  = >  i . Key ,  i  = >  i . Value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Check for errors and ignores in addon.json 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  addonJson  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                JsonConvert . DeserializeObject < AddonJson > ( Encoding . UTF8 . GetString ( Files [ "addon.json" ] . GetContents ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            addonJson . CheckForErrors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            addonJson . RemoveIgnoredFiles ( ref  files ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Extract data from addon.json 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Title  =  addonJson . Title ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:51:18 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Author  =  addonJson . Author ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Description  =  string . IsNullOrEmpty ( addonJson . Description )  ?  string . Empty  :  addonJson . Description ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            Version  =  addonJson . Version ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Create a stripped down version of addon.json for the output gma, it will replace the Description field 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  newDescription  =  JsonConvert . SerializeObject ( new  AddonJson 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Description  =  Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Tags  =  addonJson . Tags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                Type  =  addonJson . Type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:07:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // Sort files 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  resultingFiles  =  new  SortedDictionary < string ,  AddonFileInfo > ( files ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            resultingFiles . Remove ( "addon.json" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            // General whitelist 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            var  blacklistedFiles  =  AddonWhitelist 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                . FindBlacklistedFiles ( resultingFiles . Select ( i  = >  i . Key ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                . ToArray ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            if  ( blacklistedFiles . Any ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                throw  new  InvalidOperationException ( "Found files which aren't whitelisted. Remove or ignore those files before you retry packing your addon:" 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                                                    +  Environment . NewLine  +  Environment . NewLine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                                                    +  string . Join ( Environment . NewLine ,  blacklistedFiles ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            using  ( var  stream  =  new  MemoryStream ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // TODO: Standardized encoding - Garry should use standardized encoding, currently he uses Encoding.Default which is applocale-dependent... 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-23 00:49:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  sw  =  new  BinaryWriter ( stream ,  Encoding . GetEncoding ( "iso-8859-1" ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Format header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( FormatIdent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( FormatVersion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Creator steam ID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( SteamID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Build timestamp 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( BuildTimestamp  =  ( ulong )  ( DateTime . UtcNow  -  new  DateTime ( 1970 ,  1 ,  1 ,  0 ,  0 ,  0 ) ) . TotalSeconds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Required content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                if  ( RequiredContent . Count  >  byte . MaxValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    throw  new  IndexOutOfRangeException ( "Required content count must not exceed "  +  byte . MaxValue  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                                                       " entries." ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( ( byte )  RequiredContent . Count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                foreach  ( var  content  in  RequiredContent ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( content ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( Title ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:42:45 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( newDescription ,  true ) ;  // "Description" field which is actually a trimmed down addon.json 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( Author ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( Version ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // File list 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-23 00:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								#if SUPPORT_BIG 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                if  ( Files . Count  >  uint . MaxValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    throw  new  IndexOutOfRangeException ( "Number of addon files must not exceed "  +  uint . MaxValue  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                                                       " elements." ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-23 00:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								# endif 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                uint  fileNum  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                foreach  ( var  file  in  resultingFiles ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 02:37:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Console . WriteLine ( "Processing: {0} ({1:0.00} kB)" ,  file . Key ,  ( double ) file . Value . Size  /  1024 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    fileNum + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( fileNum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( file . Key . ToLower ( ) ,  true ) ;  // Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( file . Value . Size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( file . Value . Crc32Hash ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( ( uint )  0 ) ;  // End of file list 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // File contents 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:29:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                foreach  ( var  file  in  resultingFiles ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    if  ( file . Value . Size  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 02:37:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    Console . WriteLine ( "Packing: {0}" ,  file . Key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    sw . Write ( file . Value . GetContents ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                // Addon CRC 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 01:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								                var  addonHash  =  Crc32 . Compute ( stream . ToArray ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                sw . Write ( addonHash ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                using  ( var  outfile  =  File . Create ( path ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 14:01:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    stream . Position  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                    stream . CopyTo ( outfile ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-11 03:44:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// <summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// Indicates whether Lua files will have comments and unnecessary whitespace stripped out on export. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        /// </summary> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								        public  bool  MinimizeLua  {  get ;  set ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 13:47:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:48:30 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
								
									
								 
							
							
								}