// ----------------------------------------------------------------------------------- /// <summary> /// Loads the images for a given round /// </summary> public RoundImages LoadRound(int round) { if (round >= header.availableRounds) { throw new Exception(string.Concat("Tried to load round: ", round + 1, " but only ", header.availableRounds, " rounds are available")); } BinaryReader br = new BinaryReader(System.IO.File.Open(source, FileMode.Open)); BlowFishCS.BlowFish blowfish = new BlowFishCS.BlowFish(IllogicGate.Data.EncryptedFile.RestoreKey(ShuffledKey)); // read and decrypt the round image and shadow br.BaseStream.Seek(header.roundBase[round].offset, SeekOrigin.Begin); byte[] rawBase = br.ReadBytes(header.roundBase[round].length); rawBase = blowfish.Decrypt_ECB(rawBase); rawBase = LZMAtools.DecompressLZMAByteArrayToByteArray(rawBase); br.BaseStream.Seek(header.roundShadow[round].offset, SeekOrigin.Begin); byte[] rawShadow = br.ReadBytes(header.roundShadow[round].length); rawShadow = blowfish.Decrypt_ECB(rawShadow); rawShadow = LZMAtools.DecompressLZMAByteArrayToByteArray(rawShadow); br.Close(); return(new RoundImages(rawBase, rawShadow, header.isPortrait[round])); }
// ----------------------------------------------------------------------------------- /// <summary> /// Loads and decrypts a character sheet from file /// </summary> void LoadCharacterSheet() { BinaryReader br = new BinaryReader(System.IO.File.Open(source, FileMode.Open)); BlowFishCS.BlowFish blowfish = new BlowFishCS.BlowFish(IllogicGate.Data.EncryptedFile.RestoreKey(ShuffledKey)); // read and decrypt the character sheet br.BaseStream.Seek(header.characterSheet.offset, SeekOrigin.Begin); byte[] rawData = br.ReadBytes(header.characterSheet.length); rawData = blowfish.Decrypt_ECB(rawData); rawData = LZMAtools.DecompressLZMAByteArrayToByteArray(rawData); br.Close(); _characterSheet = new BaseSheet(rawData); }
// ----------------------------------------------------------------------------------- #if UNITY_EDITOR /// <summary> /// Creates a file with the character sheet and each round image /// Only available in editor mode /// encrypting them separately /// </summary> /// <param name="filename">File to save to</param> /// <param name="guid"> Unique id to identify the character </param> /// <param name="tags"> comma separated tags, like IB </param> /// <param name="charSheetFile"> PNG file with the character sheet </param> /// <param name="roundFiles"> PNG files for each round (base, shadow) </param> /// <param name="updateFile"> File to update. If null, a new one is created </param> public static void CreateFile(string filename, string guid, string characterName, string artist, string tags, string charSheetFile, List <string[]> roundFiles, File updateFile = null) { string tempFile = Application.temporaryCachePath + "/temp_charfile.chr"; // count the number of available rounds int availableRounds = updateFile != null ? updateFile.availableRounds : 0; for (int i = availableRounds; i < Config.Rounds; i++) { // can only add extra rounds in this version // not remove or leave empty gaps. So, only increase count // if a new one is added, otherwise keep previous count if (roundFiles[i] != null) { availableRounds++; } } // ----- Validation check ----- // the update file is null, so all other png files must exist and be set string errors = ""; if (updateFile == null) { if (string.IsNullOrEmpty(charSheetFile)) { errors += "You must set the character sheet file\n"; } if (availableRounds == 0) { errors += "Set at least one round file!\n"; } // make sure we don't leave empty holes for (int i = 0; i < availableRounds; i++) { if (string.IsNullOrEmpty(roundFiles[i][0])) { errors += string.Format("You must set the base image file for round {0}\n", i + 1); } if (string.IsNullOrEmpty(roundFiles[i][1])) { errors += string.Format("You must set the shadow image file for round {0}\n", i + 1); } } } // no need to continue at this point if (!string.IsNullOrEmpty(errors)) { throw new Exception(errors); } // ----- File creation ----- BinaryWriter bw = new BinaryWriter(System.IO.File.Open(tempFile, FileMode.Create)); BlowFishCS.BlowFish blowfish = new BlowFishCS.BlowFish(IllogicGate.Data.EncryptedFile.RestoreKey(ShuffledKey)); // save an empty header to make space for it Header header = new Header(Version1, guid); header.availableRounds = availableRounds; header.tags = tags; header.artist = artist; header.characterName = characterName; // if we're updating, keep creation date if (updateFile != null) { header.createdDate = updateFile.header.createdDate; } header.Save(bw); byte[] data; // encrypt and save the character sheet file if (string.IsNullOrEmpty(charSheetFile)) { data = updateFile.baseSheet.source.GetRawTextureData(); } else { data = GetRawTextureData(charSheetFile); } data = LZMAtools.CompressByteArrayToLZMAByteArray(data); data = blowfish.Encrypt_ECB(data); header.characterSheet = new Entry((int)bw.BaseStream.Position, data.Length); bw.Write(data); // encrypt and save round images int img_w, img_h; Orientation orientation; for (int i = 0; i < header.availableRounds; i++) { // load original images if available RoundImages original = null; if (updateFile != null && i < updateFile.availableRounds) { original = updateFile.LoadRound(i); } // just copy the image from the previously loaded character file if (roundFiles[i] == null) { data = original.baseImage.GetRawTextureData(); img_w = original.baseImage.width; img_h = original.baseImage.height; } // load from file else { data = GetRawTextureData(roundFiles[i][0], out img_w, out img_h); } orientation = CheckOrientation(img_w, img_h); if (orientation == Orientation.Invalid) { throw new Exception("Invalid image size for base image " + (i + 1)); } data = LZMAtools.CompressByteArrayToLZMAByteArray(data); data = blowfish.Encrypt_ECB(data); header.roundBase[i] = new Entry((int)bw.BaseStream.Position, data.Length); bw.Write(data); // just copy the image from the previously loaded character file if (roundFiles[i] == null) { data = original.shadowImage.GetRawTextureData(); img_w = original.shadowImage.width; img_h = original.shadowImage.height; } // load from file else { data = GetRawTextureData(roundFiles[i][1], out img_w, out img_h, true); } orientation = CheckOrientation(img_w, img_h); if (orientation == Orientation.Invalid) { throw new Exception("Invalid image size for shadow image " + (i + 1)); } data = LZMAtools.CompressByteArrayToLZMAByteArray(data); data = blowfish.Encrypt_ECB(data); header.roundShadow[i] = new Entry((int)bw.BaseStream.Position, data.Length); bw.Write(data); header.isPortrait[i] = orientation == Orientation.Portrait; } // rewind and overwrite header bw.Seek(0, SeekOrigin.Begin); header.Save(bw); bw.Close(); // replace files if (System.IO.File.Exists(filename)) { System.IO.File.Delete(filename); } System.IO.File.Move(tempFile, filename); }