private static void Dump(GameVersion version) { LotdArchive archive = new LotdArchive(version); archive.Load(); archive.Dump("Dump"); }
public Manager() { Archive = new LotdArchive(); CurrentLanguage = Language.English; BattlePackData = new List <BattlePackData>(); ShopPackData = new List <ShopPackData>(); }
public Manager(GameVersion version) { Version = version; Archive = new LotdArchive(version); CurrentLanguage = Language.English; BattlePackData = new List <BattlePackData>(); ShopPackData = new List <ShopPackData>(); }
public static void UnlockDLC(GameVersion version) { LotdArchive archive = new LotdArchive(version); archive.WriteAccess = true; archive.Load(); UnlockDLC(archive); System.Diagnostics.Debugger.Break(); }
public static string GetSaveFilePath(GameVersion version) { string installDir = LotdArchive.GetInstallDirectory(version); if (!string.IsNullOrEmpty(installDir)) { try { int steamAppId = 0; string appIdFile = Path.Combine(installDir, "steam_appid.txt"); if (File.Exists(appIdFile)) { string[] lines = File.ReadAllLines(appIdFile); if (lines.Length > 0) { int.TryParse(lines[0], out steamAppId); } } if (steamAppId > 0) { string userdataDir = Path.Combine(installDir, "../../../userdata/"); if (Directory.Exists(userdataDir)) { string[] dirs = Directory.GetDirectories(userdataDir); for (int i = 0; i < dirs.Length; i++) { string dirName = new DirectoryInfo(dirs[i]).Name; long userid; if (long.TryParse(dirName, out userid)) { string saveDataDir = Path.Combine(dirs[i], string.Empty + steamAppId, "remote"); if (Directory.Exists(saveDataDir)) { string saveDataFile = Path.Combine(saveDataDir, "savegame.dat"); if (File.Exists(saveDataFile)) { return(Path.GetFullPath(saveDataFile)); } } break; } } } } } catch { } } return(null); }
public void MigrateFrom(GameSaveData other) { LotdArchive archive = new LotdArchive(Version); archive.Load(); LotdArchive otherArchive = new LotdArchive(other.Version); otherArchive.Load(); CardList.MigrateFrom(archive, otherArchive, other); }
public void MigrateFrom(LotdArchive archive, LotdArchive otherArchive, GameSaveData other) { Dictionary <int, CardInfo> cardsById, cardsByIndex, otherCardsById, otherCardsByIndex; LoadCards(archive, out cardsById, out cardsByIndex); LoadCards(otherArchive, out otherCardsById, out otherCardsByIndex); // Well this doesn't work... for (int i = 0; i < other.CardList.Cards.Length; i++) { if (i < otherCardsByIndex.Count) { CardInfo otherCard = otherCardsByIndex[i]; CardInfo card; if (cardsById.TryGetValue(otherCard.CardId, out card)) { Cards[card.Index].RawValue = other.CardList.Cards[i].RawValue; } } } }
public static void UnlockDLC(LotdArchive archive) { if (!archive.WriteAccess) { Console.WriteLine("Write access required"); } // It is important that we don't write any new bytes here as we are writing directly // to the archive. If any new bytes are added the .dat/.toc will be out of sync and the // archive will be corrupted. BinaryWriter writer = new BinaryWriter(archive.Reader.BaseStream); List <CharData> charDataFiles = archive.LoadFiles <CharData>(); foreach (CharData charData in charDataFiles) { foreach (CharData.Item item in charData.Items.Values) { item.DlcId = -1; } writer.BaseStream.Position = charData.File.ArchiveOffset; charData.Save(writer); } List <DuelData> duelDataFiles = archive.LoadFiles <DuelData>(); foreach (DuelData duelData in duelDataFiles) { foreach (DuelData.Item item in duelData.Items.Values) { item.DlcId = -1; } writer.BaseStream.Position = duelData.File.ArchiveOffset; duelData.Save(writer); } }
static void Main() { //TestModifyCardNamedBin(GameVersion.LinkEvolution2); //UnlockDLC(GameVersion.LinkEvolution2); //Dump(GameVersion.LinkEvolution2); if (System.Diagnostics.Debugger.IsAttached) { NativeScriptCompiler.CompileIfChanged(); } Dictionary <GameVersion, string> installedVersions = new Dictionary <GameVersion, string>(); foreach (GameVersion version in Enum.GetValues(typeof(GameVersion))) { if (version == GameVersion.LinkEvolution1) { continue; } string dir = LotdArchive.GetInstallDirectory(version); if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir)) { installedVersions[version] = dir; } } if (installedVersions.Count == 0) { MessageBox.Show("Failed to find LOTD install directory. Make sure you have LOTD installed via Steam (and hopefully not pirated!)"); return; } else if (installedVersions.Count == 1) { Version = installedVersions.First().Key; } else { if (MessageBox.Show("Target LOTD original version from 2016?", "LOTD", MessageBoxButtons.YesNo) == DialogResult.Yes) { Version = GameVersion.Lotd; } else { Version = GameVersion.LinkEvolution2; } } Manager = new Manager(Version); Manager.Load(); YdkHelper.LoadIdMap(); //YdkHelper.GenerateIdMap(); MemTools = new MemTools(Version); MemTools.UseScreenStateTransitions = true; MemTools.CustomYdcBattlePacksEnabled = true; MemTools.RunProcessWatcher(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new DuelStarterForm()); MemTools.StopProcessWatcher(); }
/// <summary> /// Testing changes to CARD_Named.bin /// </summary> private static void TestModifyCardNamedBin(GameVersion version) { LotdArchive archive = new LotdArchive(version); archive.WriteAccess = true; archive.Load(); Dictionary <CardNameType, List <short> > cardNameTypes = new Dictionary <CardNameType, List <short> >(); BinaryWriter writer = new BinaryWriter(archive.Reader.BaseStream, Encoding.Default, true); LotdFile file = archive.Root.FindFile("bin/CARD_Named.bin"); /*foreach (byte b in file.LoadBuffer()) * { * Console.Write(b.ToString("X2") + " "); * }*/ using (BinaryReader reader = new BinaryReader(new MemoryStream(file.LoadBuffer()))) { ushort numArchetypes = reader.ReadUInt16(); ushort numCards = reader.ReadUInt16(); long cardsStartOffset = 4 + (numArchetypes * 4); long cardsEndOffset = cardsStartOffset + (numCards * 2); System.Diagnostics.Debug.Assert(reader.BaseStream.Length == cardsEndOffset); for (int i = 0; i < numArchetypes; i++) { int offset = reader.ReadInt16(); // The offset of the cards for this named group (starts at 0) int count = reader.ReadInt16(); // The number of cards for this named group List <short> cardIds; if (!cardNameTypes.TryGetValue((CardNameType)i, out cardIds)) { cardNameTypes.Add((CardNameType)i, cardIds = new List <short>()); } long tempOffset = reader.BaseStream.Position; reader.BaseStream.Position = cardsStartOffset + (offset * 2); for (int j = 0; j < count; j++) { short cardId = reader.ReadInt16(); cardIds.Add(cardId); } reader.BaseStream.Position = tempOffset; } } int totalCards = 0; int cardsOffset = 0; foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { totalCards += cards.Value.Count; } writer.BaseStream.Position = file.ArchiveOffset; writer.Write((ushort)cardNameTypes.Count); writer.Write((ushort)totalCards);// total num cards foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { writer.Write((ushort)cardsOffset); // The offset of the cards for this named group (starts at 0) writer.Write((ushort)cards.Value.Count); // The number of cards for this named group cardsOffset += cards.Value.Count; } foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { if (cards.Key == CardNameType.UA) { //cards.Value.Remove(11637); cards.Value.Add(11641); cards.Value.Sort(); } //bool first = true; foreach (short cardId in cards.Value) //.OrderBy(x => x)) { if ((cards.Key == CardNameType.UA /* && first*/)) // || cards.Key > CardNameType.PendDragon) { /*if (cardId == 11637)//(cards.Key == CardNameType.UA && first)) * { * Console.WriteLine(cardId); * writer.Write((short)5380); * } * else*/ { writer.Write(cardId); } } else { writer.Write(cardId); } //first = false; } } writer.Close(); System.Diagnostics.Debugger.Break(); }
private void LoadCards(LotdArchive archive, out Dictionary <int, CardInfo> cardsById, out Dictionary <int, CardInfo> cardsByIndex) { Language targetLangue = Language.English; Dictionary <Language, byte[]> indxByLang = archive.LoadLocalizedBuffer("CARD_Indx_", true); Dictionary <Language, byte[]> namesByLang = archive.LoadLocalizedBuffer("CARD_Name_", true); Dictionary <Language, byte[]> descriptionsByLang = archive.LoadLocalizedBuffer("CARD_Desc_", true); byte[] indx = indxByLang[targetLangue]; byte[] names = namesByLang[targetLangue]; byte[] descriptions = descriptionsByLang[targetLangue]; List <CardInfo> cards = new List <CardInfo>(); using (BinaryReader indxReader = new BinaryReader(new MemoryStream(indx))) using (BinaryReader namesReader = new BinaryReader(new MemoryStream(names))) using (BinaryReader descriptionsReader = new BinaryReader(new MemoryStream(descriptions))) { Dictionary <uint, string> namesByOffset = ReadStrings(namesReader); Dictionary <uint, string> descriptionsByOffset = ReadStrings(descriptionsReader); int index = 0; while (true) { uint nameOffset = indxReader.ReadUInt32(); uint descriptionOffset = indxReader.ReadUInt32(); if (indxReader.BaseStream.Position >= indxReader.BaseStream.Length) { // The last index points to an invalid offset break; } CardInfo card = null; if (cards.Count > index) { card = cards[index]; } else { cards.Add(card = new CardInfo(index)); } card.Name = namesByOffset[nameOffset]; card.Description = descriptionsByOffset[descriptionOffset]; index++; } } using (BinaryReader reader = new BinaryReader(new MemoryStream(archive.Root.FindFile("bin/CARD_Prop.bin").LoadBuffer()))) { for (int i = 0; i < cards.Count; i++) { CardInfo card = cards[i]; uint a1 = reader.ReadUInt32(); uint a2 = reader.ReadUInt32(); uint first = (a1 << 18) | ((a1 & 0x7FC000 | a1 >> 18) >> 5); uint second = (((a2 & 1u) | (a2 << 21)) & 0x80000001 | ((a2 & 0x7800) | ((a2 & 0x780 | ((a2 & 0x7E) << 10)) << 8)) << 6 | ((a2 & 0x38000 | ((a2 & 0x7C0000 | ((a2 & 0x7800000 | (a2 >> 8) & 0x780000) >> 9)) >> 8)) >> 1)); short cardId = (short)((first >> 18) & 0x3FFF); card.CardId = cardId; } } cardsById = new Dictionary <int, CardInfo>(); cardsByIndex = new Dictionary <int, CardInfo>(); foreach (CardInfo card in cards) { cardsById[card.CardId] = card; cardsByIndex[card.Index] = card; } }