protected override void CreateOrUpdateDetailCollectionItem(ContentItem contentItem, PropertyData existingDetail, Control editor, out object newDetail)
        {
            FancyFileUpload fileEditor = (FancyFileUpload)editor;
            LinkProperty existingFileProperty = existingDetail as LinkProperty;
            if (fileEditor.HasNewOrChangedFile)
            {
                // Add new file.
                File newFile = null;
                if (existingFileProperty != null)
                    newFile = existingFileProperty.LinkedItem as File;
                if (newFile == null)
                {
                    newFile = CreateNewItem();
                    newFile.Name = Name + Guid.NewGuid();
                    newFile.AddTo(contentItem);
                }

                // Populate FileData object.
                newFile.FileName = fileEditor.FileName;
                string uploadFolder = BaseFileUploadHandler.GetUploadFolder(fileEditor.Identifier);
                string uploadedFile = Path.Combine(uploadFolder, fileEditor.FileName);
                using (FileStream fs = new FileStream(uploadedFile, FileMode.Open))
                {
                    newFile.Data = fs.ReadAllBytes();
                    newFile.ContentType = MimeUtility.GetMimeType(newFile.Data);
                    newFile.Size = fs.Length;
                }

                // Delete temp folder.
                System.IO.File.Delete(uploadedFile);
                Directory.Delete(uploadFolder);

                newDetail = newFile;

                if (existingFileProperty != null)
                    HandleUpdatedFile(newFile);
            }
            else
            {
                newDetail = null;
            }
        }
Example #2
0
        private void DowngradeVGAPatch(string file)
        {
            byte[] bytes;
            using (var avatarStream = new System.IO.FileStream(file, System.IO.FileMode.Open))
            {
                bytes = avatarStream.ReadAllBytes();
            }

            var originalRuneNums = new char[] { '1', '2', '0', '1', '2', '1', '3', '4' };

            for (int i = 0; i < 8; i++)
            {
                bytes[AvatarOffsetsOriginal.RUNE_IMAGE_INDEX + 5 + i * 7] = (byte)originalRuneNums[i];
            }
            bytes[AvatarOffsetsOriginal.RUNE_IMAGE_INDEX2] = 0x35;

            using (var avatarOut = new System.IO.BinaryWriter(new System.IO.FileStream(file, System.IO.FileMode.Truncate)))
            {
                avatarOut.Write(bytes);
            }
        }
        public override bool UpdateItem(IEditableObject item, Control editor)
        {
            FancyFileUpload fileUpload = (FancyFileUpload) editor;
            File file = (File) item;

            bool result = false;
            if (fileUpload.HasDeletedFile)
            {
                file.Data = null;
                result = true;
            }
            else if (fileUpload.HasNewOrChangedFile)
            {
                // Populate File object.
                file.FileName = fileUpload.FileName;
                string uploadedFile = GetUploadedFilePath(fileUpload);
                using (FileStream fs = new FileStream(uploadedFile, FileMode.Open))
                {
                    file.Data = fs.ReadAllBytes();
                    file.ContentType = MimeUtility.GetMimeType(file.Data);
                    file.Size = fs.Length;
                }

                // Later, we will change the name, if this is a child property.
                file.Title = fileUpload.FileName;
                file.Name = fileUpload.FileName.ToLower();

                // Delete temp folder.
                System.IO.File.Delete(uploadedFile);
                Directory.Delete(BaseFileUploadHandler.GetUploadFolder(fileUpload.Identifier));

                result = true;
            }

            return result;
        }
Example #4
0
        // Asserts that the contents of two files are equal.
        void AssertFileEqual(string fileName1, string fileName2)
        {
            byte[] content1, content2;
            using (var r1 = new FileStream(fileName1, FileMode.Open))
            {
                content1 = r1.ReadAllBytes();
            }
            using (var r1 = new FileStream(fileName2, FileMode.Open))
            {
                content2 = r1.ReadAllBytes();                
            }

            Assert.Equal(content1, content2);
        }
Example #5
0
        public void Load(string path, UltimaData data)
        {
            var file = Path.Combine(path, filename);

            FileHelper.TryBackupOriginalFile(file);

            // Apply delta file to create new file
            var newFilePath2           = file;
            var newFileOutputDirectory = Path.GetDirectoryName(newFilePath2);

            if (!Directory.Exists(newFileOutputDirectory))
            {
                Directory.CreateDirectory(newFileOutputDirectory);
            }
            var deltaApplier = new DeltaApplier {
                SkipHashCheck = false
            };

            using (var basisStream = new FileStream($"{file}.orig", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (var deltaStream = new MemoryStream(Patches.TITLE_EXE))
                {
                    using (var newFileStream = new FileStream(newFilePath2, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                    {
                        deltaApplier.Apply(basisStream, new BinaryDeltaReader(deltaStream, new ConsoleProgressReporter()), newFileStream);
                    }
                }
            }

            using (var titleStream = new System.IO.FileStream(file, System.IO.FileMode.Open))
            {
                titleBytes = titleStream.ReadAllBytes();
            }

            if (titleBytes[START_X_OFFSET] != 0xE7)
            {
                throw new Exception($"Offset START_X_OFFSET appears to be wrong.");
            }

            if (titleBytes[START_Y_OFFSET] != 0x88)
            {
                throw new Exception($"Offset START_Y_OFFSET appears to be wrong.");
            }

            if (titleBytes[FLAG_ENCODE_OFFSET] != 0x43)
            {
                throw new Exception($"Offset FLAG_ENCODE_OFFSET appears to be wrong.");
            }

            if (titleBytes[ENABLE_KARMA_OVERRIDE_OFFSET] != 0x09)
            {
                throw new Exception($"Offset ENABLE_KARMA_OVERRIDE_OFFSET appears to be wrong.");
            }

            if (titleBytes[KARMA_OVERRIDE_VALUES_OFFSET] != 0xFF)
            {
                throw new Exception($"Offset KARMA_OVERRIDE_VALUES_OFFSET appears to be wrong.");
            }

            for (int offset = 0; offset < 8; offset++)
            {
                data.StartingPositions.Add(new Coordinate(titleBytes[START_X_OFFSET + offset], titleBytes[START_Y_OFFSET + offset]));
            }

            for (int offset = 0; offset < 8; offset++)
            {
                data.StartingKarma.Add(titleBytes[KARMA_OVERRIDE_VALUES_OFFSET + offset]);
            }
        }
Example #6
0
        public void Load(string path, UltimaData data)
        {
            var file = Path.Combine(path, filename);

            FileHelper.TryBackupOriginalFile(file);

            using (var partyStream = new System.IO.FileStream($"{file}.orig", System.IO.FileMode.Open))
            {
                partyBytes = partyStream.ReadAllBytes();
            }

            for (int i = 0; i < 8; i++)
            {
                var character = new Character();
                character.Hp     = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_HP_OFFSET);
                character.MaxHp  = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_MAX_HP_OFFSET);
                character.XP     = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_XP_OFFSET);
                character.Str    = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_STR_OFFSET);
                character.Dex    = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_DEX_OFFSET);
                character.Int    = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_INT_OFFSET);
                character.Mp     = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_MP_OFFSET);
                character.Weapon = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_WEAPON_OFFSET);
                character.Armor  = BitConverter.ToUInt16(partyBytes, CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_ARMOR_OFFSET);

                var nameTextBytes = new List <byte>();
                var textOffset    = CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_NAME_OFFSET;
                for (; partyBytes[textOffset] != 0x00; textOffset++)
                {
                    nameTextBytes.Add(partyBytes[textOffset]);
                }
                character.Name = System.Text.Encoding.Default.GetString(nameTextBytes.ToArray());
                nameTextBytes.Clear();

                character.Sex    = (partyBytes[CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_SEX_OFFSET] == 0xb ? 'M' : 'F');
                character.Class  = partyBytes[CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_CLASS_OFFSET];
                character.Status = (char)partyBytes[CHARACTER_RECORDS_OFFSET + (i * CHAR_RECORD_LENGTH) + CHARACTER_STATUS_OFFSET];

                data.StartingCharacters.Add(character);
            }

            data.StartingFood  = BitConverter.ToUInt32(partyBytes, FOOD_OFFSET);
            data.StartingGold  = BitConverter.ToUInt16(partyBytes, GOLD_OFFSET);
            data.StartingItems = BitConverter.ToUInt16(partyBytes, ITEMS1_OFFSET);
            for (int offset = 0; offset < 4; offset++)
            {
                data.StartingEquipment.Add(BitConverter.ToUInt16(partyBytes, EQUIPMENT_OFFSET + (offset * 2)));
            }
            for (int offset = 0; offset < 8; offset++)
            {
                data.StartingArmor.Add(BitConverter.ToUInt16(partyBytes, ARMOR_OFFSET + (offset * 2)));
            }
            for (int offset = 0; offset < 16; offset++)
            {
                data.StartingWeapons.Add(BitConverter.ToUInt16(partyBytes, WEAPONS_OFFSET + (offset * 2)));
            }
            for (int offset = 0; offset < 8; offset++)
            {
                data.StartingReagents.Add(BitConverter.ToUInt16(partyBytes, REAGENTS_OFFSET + (offset * 2)));
            }
            for (int offset = 0; offset < 26; offset++)
            {
                data.StartingMixtures.Add(BitConverter.ToUInt16(partyBytes, MIXTURES_OFFSET + (offset * 2)));
            }

            data.StartingStones = partyBytes[STONES_OFFSET];
            data.StartingRunes  = partyBytes[RUNES_OFFSET];
        }
Example #7
0
        public HttpResponseMessage PutPackage(HttpRequestMessage message)
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                return new HttpResponseMessage(HttpStatusCode.BadRequest);
            }

            var provider = new MultipartFormDataStreamProvider(Path.GetTempPath());

            try
            {
                message.Content.ReadAsMultipartAsync(provider).Wait();

                foreach (var file in provider.FileData)
                {
                    using (var fileStream = new FileStream(file.LocalFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 1024*1024))
                    {
                        var bytes = fileStream.ReadAllBytes();
                        Package package;
                        if (!packageBuilder.TryBuild(bytes, out package))
                        {
                            return new HttpResponseMessage(HttpStatusCode.BadRequest);
                        }

                        if (packageService.Any(package.Id, package.Version))
                        {
                            break;
                        }

                        blobService.Upload(GetBlobScope(package), package.BlobId, bytes);
                        packageService.Add(package);
                    }
                }
                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            catch (Exception)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
        }
Example #8
0
        public void Load(string path, UltimaData data, IWorldMap worldMap, Flags flags)
        {
            var file = Path.Combine(path, filename);

            if (flags.VGAPatch && HashHelper.BytesToString(HashHelper.GetHashSha256(file)) == upgradeFileHash)
            {
                DowngradeVGAPatch(file);
            }
            FileHelper.TryBackupOriginalFile(file);

            // Apply delta file to create new file
            var newFilePath2           = file;
            var newFileOutputDirectory = Path.GetDirectoryName(newFilePath2);

            if (!Directory.Exists(newFileOutputDirectory))
            {
                Directory.CreateDirectory(newFileOutputDirectory);
            }
            var deltaApplier = new DeltaApplier {
                SkipHashCheck = false
            };

            using (var basisStream = new FileStream($"{file}.orig", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (var deltaStream = new MemoryStream(Patches.AVATAR_EXE))
                {
                    using (var newFileStream = new FileStream(newFilePath2, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                    {
                        deltaApplier.Apply(basisStream, new BinaryDeltaReader(deltaStream, new ConsoleProgressReporter()), newFileStream);
                    }
                }
            }

            using (var avatarStream = new System.IO.FileStream(file, System.IO.FileMode.Open))
            {
                avatarBytes = avatarStream.ReadAllBytes();
            }

            AvatarOffset = new AvatarOffsetsNew(avatarBytes, $"{file}.orig");


            // Items
            var items = new List <Item>();

            for (int offset = 0; offset < 23; offset++)
            {
                items.Add(new Item(avatarBytes[AvatarOffset.ITEM_LOCATIONS_OFFSET + offset * 5],
                                   avatarBytes[AvatarOffset.ITEM_LOCATIONS_OFFSET + offset * 5 + 1],
                                   avatarBytes[AvatarOffset.ITEM_LOCATIONS_OFFSET + offset * 5 + 2]));
            }
            data.SetItems(items);

            // Moongates
            var moongates = new List <Tile>();

            for (byte offset = 0; offset < 8; offset++)
            {
                moongates.Add(worldMap.GetCoordinate(avatarBytes[AvatarOffset.MOONGATE_X_OFFSET + offset], avatarBytes[AvatarOffset.MOONGATE_Y_OFFSET + offset]));
            }
            data.SetMoongates(moongates);

            // LCB
            var lcb    = new List <Tile>();
            var lcbLoc = worldMap.GetCoordinate(avatarBytes[AvatarOffset.AREA_X_OFFSET + data.LOC_LCB - 1], avatarBytes[AvatarOffset.AREA_Y_OFFSET + data.LOC_LCB - 1]);

            lcb.Add(lcbLoc);
            lcb.Add(worldMap.GetCoordinate(lcbLoc.X - 1, lcbLoc.Y));
            lcb.Add(worldMap.GetCoordinate(lcbLoc.X + 1, lcbLoc.Y));
            data.SetLCB(lcb);

            // Castles
            var castles = new List <TileDirtyWrapper>();

            for (byte offset = 0; offset < 3; offset++)
            {
                castles.Add(new TileDirtyWrapper(worldMap.GetCoordinate(avatarBytes[AvatarOffset.AREA_X_OFFSET + data.LOC_CASTLES + offset], avatarBytes[AvatarOffset.AREA_Y_OFFSET + data.LOC_CASTLES + offset]), worldMap));
            }
            data.SetCastles(castles);

            // Towns
            var towns = new List <TileDirtyWrapper>();

            for (byte offset = 0; offset < 8 + 4; offset++)
            {
                towns.Add(new TileDirtyWrapper(worldMap.GetCoordinate(avatarBytes[AvatarOffset.AREA_X_OFFSET + data.LOC_TOWNS + offset - 1], avatarBytes[AvatarOffset.AREA_Y_OFFSET + data.LOC_TOWNS + offset - 1]), worldMap));
            }
            data.SetTowns(towns);

            // Shrines
            var shrines = new List <TileDirtyWrapper>();

            for (byte offset = 0; offset < 8; offset++)
            {
                shrines.Add(new TileDirtyWrapper(worldMap.GetCoordinate(avatarBytes[AvatarOffset.AREA_X_OFFSET + data.LOC_SHRINES + offset - 1], avatarBytes[AvatarOffset.AREA_Y_OFFSET + data.LOC_SHRINES + offset - 1]), worldMap));
            }
            data.SetShrines(shrines);

            // Dungeons
            var dungeons = new List <Tile>();

            for (byte offset = 0; offset < 8; offset++)
            {
                dungeons.Add(worldMap.GetCoordinate(avatarBytes[AvatarOffset.AREA_X_OFFSET + data.LOC_DUNGEONS + offset - 1], avatarBytes[AvatarOffset.AREA_Y_OFFSET + data.LOC_DUNGEONS + offset - 1]));
            }
            data.SetDungeons(dungeons);

            // Balloon Spawn
            data.BalloonSpawn = worldMap.GetCoordinate(avatarBytes[AvatarOffset.BALLOON_SPAWN_LOCATION_X_OFFSET], avatarBytes[AvatarOffset.BALLOON_SPAWN_LOCATION_Y_OFFSET]);

            OriginalShrineText            = new List <string>();
            OriginalShrineTextStartOffset = new List <int>();
            var shrineTextBytes = new List <byte>();
            var textOffset      = AvatarOffset.SHRINE_TEXT_OFFSET;

            for (int i = 0; i < 24; i++)
            {
                OriginalShrineTextStartOffset.Add(textOffset);
                for (; avatarBytes[textOffset] != 0x0A && avatarBytes[textOffset] != 0x00; textOffset++)
                {
                    shrineTextBytes.Add(avatarBytes[textOffset]);
                }
                OriginalShrineText.Add(System.Text.Encoding.Default.GetString(shrineTextBytes.ToArray()));
                shrineTextBytes.Clear();
                if (avatarBytes[textOffset] == 0x0A)
                {
                    textOffset++;
                }
                textOffset++;
            }
            data.ShrineText.Clear();
            data.ShrineText.AddRange(OriginalShrineText);

            OriginalLBText            = new List <string>();
            OriginalLBTextStartOffset = new List <int>();
            var lbTextBytes = new List <byte>();

            textOffset = AvatarOffset.LB_TEXT_OFFSET;
            // He has more text than 19 but there is some weird stuff after 19 that doesn't get turned into text well. And as far as I can tell we won't need any text after 19
            for (int i = 0; i < 19; i++)
            {
                OriginalLBTextStartOffset.Add(textOffset);
                for (; avatarBytes[textOffset] != 0x00 && avatarBytes[textOffset] != 0xAB; textOffset++)
                {
                    lbTextBytes.Add(avatarBytes[textOffset]);
                }
                OriginalLBText.Add(System.Text.Encoding.Default.GetString(lbTextBytes.ToArray()));
                lbTextBytes.Clear();
                if (avatarBytes[textOffset] == 0x0A || avatarBytes[textOffset] == 0xAB)
                {
                    textOffset++;
                }
                textOffset++;
            }
            data.LBText.Clear();
            data.LBText.AddRange(OriginalLBText);

            OriginalLBHelpText            = new List <string>();
            OriginalLBHelpTextStartOffset = new List <int>();
            lbTextBytes = new List <byte>();
            textOffset  = AvatarOffset.LB_HELP_TEXT_OFFSET;
            for (int i = 0; i < 21; i++)
            {
                OriginalLBHelpTextStartOffset.Add(textOffset);
                for (; avatarBytes[textOffset] != 0x00 && avatarBytes[textOffset] != 0xAB; textOffset++)
                {
                    lbTextBytes.Add(avatarBytes[textOffset]);
                }
                OriginalLBHelpText.Add(System.Text.Encoding.Default.GetString(lbTextBytes.ToArray()));
                lbTextBytes.Clear();
                if (avatarBytes[textOffset] == 0x0A || avatarBytes[textOffset] == 0xAB)
                {
                    textOffset++;
                }
                textOffset++;
            }
            data.LBHelpText.Clear();
            data.LBHelpText.AddRange(OriginalLBHelpText);

            var mantraTextBytes = new List <byte>();

            textOffset    = AvatarOffset.MANTRA_OFFSET;
            MantraMaxSize = 0;
            for (int i = 0; i < 8; i++)
            {
                for (; avatarBytes[textOffset] != 0x00; textOffset++)
                {
                    mantraTextBytes.Add(avatarBytes[textOffset]);
                }
                data.Mantras.Add(System.Text.Encoding.Default.GetString(mantraTextBytes.ToArray()));
                MantraMaxSize += data.Mantras[i].Length + 1;
                mantraTextBytes.Clear();

                textOffset++;
            }

            var wordOfPassageTextBytes = new List <byte>();

            for (int offSet = 0; offSet < 9; offSet++)
            {
                wordOfPassageTextBytes.Add(avatarBytes[AvatarOffset.WORD_OF_PASSAGE + offSet]);
            }
            data.WordOfPassage = System.Text.Encoding.Default.GetString(wordOfPassageTextBytes.ToArray());

            data.DaemonSpawnX1        = avatarBytes[AvatarOffset.DEMON_SPAWN_TRIGGER_X1_OFFSET];
            data.DaemonSpawnX2        = avatarBytes[AvatarOffset.DEMON_SPAWN_TRIGGER_X2_OFFSET];
            data.DaemonSpawnY1        = avatarBytes[AvatarOffset.DEMON_SPAWN_TRIGGER_Y1_OFFSET];
            data.DaemonSpawnY2        = avatarBytes[AvatarOffset.DEMON_SPAWN_TRIGGER_Y2_OFFSET];
            data.DaemonSpawnLocationX = avatarBytes[AvatarOffset.DEMON_SPAWN_LOCATION_X_OFFSET];

            for (int i = 0; i < 8; i++)
            {
                data.PirateCove.Add(new Coordinate(avatarBytes[i + AvatarOffset.PIRATE_COVE_X_OFFSET], avatarBytes[i + AvatarOffset.PIRATE_COVE_Y_OFFSET]));
            }

            data.PirateCoveSpawnTrigger = new Coordinate(avatarBytes[AvatarOffset.PIRATE_COVE_SPAWN_TRIGGER_X_OFFSET1], avatarBytes[AvatarOffset.PIRATE_COVE_SPAWN_TRIGGER_Y_OFFSET1]);

            data.WhirlpoolExit = new Coordinate(avatarBytes[AvatarOffset.WHIRLPOOL_EXIT_X_OFFSET], avatarBytes[AvatarOffset.WHIRLPOOL_EXIT_Y_OFFSET]);

            data.SpellsRecipes = new List <ByteDirtyWrapper>();
            for (int i = 0; i < 26; i++)
            {
                data.SpellsRecipes.Add(new ByteDirtyWrapper(avatarBytes[AvatarOffset.SPELL_RECIPE_OFFSET + i]));
            }

            data.BlinkCastExclusionX1 = avatarBytes[AvatarOffset.BLINK_CAST_EXCLUSION_X1_OFFSET];
            data.BlinkCastExclusionX2 = avatarBytes[AvatarOffset.BLINK_CAST_EXCLUSION_X2_OFFSET];
            data.BlinkCastExclusionY1 = avatarBytes[AvatarOffset.BLINK_CAST_EXCLUSION_Y1_OFFSET];
            data.BlinkCastExclusionY2 = avatarBytes[AvatarOffset.BLINK_CAST_EXCLUSION_Y2_OFFSET];

            data.BlinkDestinationExclusionX1 = avatarBytes[AvatarOffset.BLINK_DESTINATION_EXCLUSION_X1_OFFSET];
            data.BlinkDestinationExclusionX2 = avatarBytes[AvatarOffset.BLINK_DESTINATION_EXCLUSION_X2_OFFSET];
            data.BlinkDestinationExclusionY1 = avatarBytes[AvatarOffset.BLINK_DESTINATION_EXCLUSION_Y1_OFFSET];
            data.BlinkDestinationExclusionY2 = avatarBytes[AvatarOffset.BLINK_DESTINATION_EXCLUSION_Y2_OFFSET];

            data.BlinkDestinationExclusion2X1 = avatarBytes[AvatarOffset.BLINK_DESTINATION2_EXCLUSION_X1_OFFSET];
            data.BlinkDestinationExclusion2X2 = avatarBytes[AvatarOffset.BLINK_DESTINATION2_EXCLUSION_X2_OFFSET];
            data.BlinkDestinationExclusion2Y1 = avatarBytes[AvatarOffset.BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET];
            data.BlinkDestinationExclusion2Y2 = avatarBytes[AvatarOffset.BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET];

            for (int i = 0; i < 13; i++)
            {
                data.AbyssEjectionLocations.Add(new Coordinate(avatarBytes[i + AvatarOffset.ABYSS_EJECTION_LOCATIONS_X], avatarBytes[i + AvatarOffset.ABYSS_EJECTION_LOCATIONS_Y]));
            }

            for (int townIdx = 0; townIdx < 16; townIdx++)
            {
                data.ShopLocations.Add(new List <byte>());
                for (int shopIdx = 0; shopIdx < 8; shopIdx++)
                {
                    data.ShopLocations[townIdx].Add(avatarBytes[townIdx * 8 + shopIdx + AvatarOffset.SHOP_LOCATION_OFFSET]);
                }
            }
        }