static void Read2DArray(BinBuffer bb, ModIdMap map, int xLen, int yLen, Action <int, int, int> setElemV, Action <int, int, ObjectRef> setElemM) { var dictPos = bb.ReadInt32(); var dataStart = bb.Position; bb.Position = dictPos; map.ReadDictionary(bb); var endOfStream = bb.Position; bb.Position = dataStart; int amt = 0; bool isM = false; ObjectRef curM = ObjectRef.Null; int curV = 0; for (int y = 0; y < yLen; y++) { for (int x = 0; x < xLen; x++) { if (amt == 0) { map.GetRef(bb.ReadUInt32(), oid => { curV = oid; isM = false; setElemV(x, y, curV); // amt == 0 -> one element }, or => { curM = or; isM = true; setElemM(x, y, curM); // amt == 0 -> one element }); amt = bb.ReadUInt16(); } else { if (isM) { setElemM(x, y, curM); } else { setElemV(x, y, curV); } amt--; } } } bb.Position = endOfStream; }
static void LoadTileTypes(BinBuffer bb, int v) { // don't read anything for now, custom tiles aren't implemented return; #pragma warning disable 162 // to be used in future versions if (v == 0) { return; } #pragma warning restore 162 var map = new ModIdMap(TileID.Count, or => new TileRef(or).Resolve().Type, id => new TileRef(id)); var tp = bb.Position; var dictOffset = bb.ReadInt32(); bb.Position += dictOffset; map.ReadDictionary(bb); var end = bb.Position; bb.Position = tp; int amt = 0; for (int y = 0; y < Main.maxTilesY; y++) { for (int x = 0; x < Main.maxTilesX; x++) { if (amt == 0) { var t = bb.ReadUInt32(); Main.tile[x, y].type = (ushort)new TileRef(map.GetRef(t)).Resolve().Type; amt = bb.ReadUInt16(); } else { amt--; } } } bb.Position = end; }
/// <summary> /// Load <paramref name="slots" /> items to <paramref name="inventory" /> from the <paramref name="bb" />. /// </summary> /// <param name="bb">The reader for loading data</param> /// <param name="inventory">The array of items</param> /// <param name="slots">The amount of items in the inventory to load</param> /// <param name="stack">Whether or not the stack size should be loaded</param> /// <param name="favourited">Whether or not the favourited state should be loaded</param> static void LoadItemSlots(BinBuffer bb, Item[] inventory, int slots, bool stack, bool favourited) { for (int i = 0; i < slots; i++) { // Load basic item data string mod = bb.ReadString(); if (!String.IsNullOrEmpty(mod) && mod != PrismApi.VanillaString) { string item = bb.ReadString(); if (!ModData.modsFromInternalName.ContainsKey(mod) || !ModData.modsFromInternalName[mod].ItemDefs.ContainsKey(item)) { inventory[i].SetDefaults(ItemDefHandler.UnknownItemID); inventory[i].toolTip = mod; inventory[i].toolTip2 = item; } else { inventory[i].SetDefaults(ModData.modsFromInternalName[mod].ItemDefs[item].Type); } if (stack) { inventory[i].stack = bb.ReadInt32(); } inventory[i].prefix = bb.ReadByte(); if (favourited) { inventory[i].favorited = bb.ReadBoolean(); } } // Load Mod Data if (inventory[i].P_BHandler == null) { inventory[i].P_BHandler = new ItemBHandler(); ((ItemBHandler)inventory[i].P_BHandler).Create(); } ((ItemBHandler)inventory[i].P_BHandler).Load(bb); } }
/// <summary> /// Load player data from a .plr.prism file /// </summary> /// <param name="playerPath">The path to the vanilla .plr file</param> internal static void LoadPlayer(Player player, string playerPath) { playerPath += ".prism"; // If mod data doesn't exist, don't try to load it if (!File.Exists(playerPath)) { return; } try { using (FileStream fileStream = File.OpenRead(playerPath)) { byte version = (byte)fileStream.ReadByte(); // should be safe to cast here, very unlikely that the file is empty if (version > PLAYER_VERSION) { throw new FileFormatException("Tried to load a player file from a future version of Prism."); } if (version < MIN_PLAYER_SUPPORT_VER) { throw new FileFormatException("This player is saved in a format that is too old and unsupported."); } using (CryptoStream cryptoStream = new CryptoStream(fileStream, new RijndaelManaged() { Padding = PaddingMode.None }.CreateDecryptor(GenerateKey(player.name), ENCRYPTION_KEY), CryptoStreamMode.Read)) using (BinBuffer bb = new BinBuffer(cryptoStream)) { #region Player Data if (player.P_BHandler == null) { player.P_BHandler = new PlayerBHandler(); ((PlayerBHandler)player.P_BHandler).Create(); } ((PlayerBHandler)player.P_BHandler).Load(bb); #endregion Player Data #region Item Data LoadItemSlots(bb, player.armor, player.armor.Length, false, false); LoadItemSlots(bb, player.dye, player.dye.Length, false, false); LoadItemSlots(bb, player.inventory, Main.maxInventory, true, true); LoadItemSlots(bb, player.miscEquips, player.miscEquips.Length, false, false); LoadItemSlots(bb, player.bank.item, Chest.maxItems, true, false); LoadItemSlots(bb, player.bank2.item, Chest.maxItems, true, false); #endregion Item Data #region Buff Data for (int i = 0; i < Player.maxBuffs; i++) { var mod = bb.ReadString(); if (String.IsNullOrEmpty(mod) || !ModData.modsFromInternalName.ContainsKey(mod)) { continue; } var md = ModData.modsFromInternalName[mod]; var buff = bb.ReadString(); var t = bb.ReadInt32(); if (!md.BuffDefs.ContainsKey(buff)) { continue; } player.AddBuff(md.BuffDefs[buff].Type, t); if (player.P_BuffBHandler[i] == null) { player.P_BuffBHandler[i] = new BuffBHandler(); ((BuffBHandler)player.P_BuffBHandler[i]).Create(); } ((BuffBHandler)player.P_BuffBHandler[i]).Save(bb); } #endregion Buff Data } } } catch (Exception e) { // Character could not be properly loaded, report and prevent playing //TODO: report Logging.LogError("Could not load player " + player.name + ": " + e); Trace.WriteLine("Could not load player " + player.name + ": " + e.Message); player.loadStatus = 1; } }