public override void process(Client client) { Log.debug("Got farmer data for other players."); foreach (SFarmer farmer in client.others.Values) { if (farmer.currentLocation != null) { farmer.currentLocation.farmers.Remove(farmer); } } client.others.Clear(); foreach (KeyValuePair <byte, string> other in others) { SFarmer farmer = (SFarmer)SaveGame.farmerSerializer.Deserialize(Util.stringStream(other.Value)); farmer.uniqueMultiplayerID += 1 + client.id; // For IsMainPlayer //SFarmer oldPlayer = Game1.player; NewSaveGame.loadDataToFarmer(farmer); //Game1.player = oldPlayer; // Seriously, why does this get reassigned in there? client.others.Add(other.Key, farmer); if (other.Key == 0) { foreach (string mail in Multiplayer.checkMail) { if (farmer.mailReceived.Contains(mail) && !SaveGame.loaded.player.mailReceived.Contains(mail)) { SaveGame.loaded.player.mailReceived.Add(mail); } if (farmer.mailForTomorrow.Contains(mail) && !SaveGame.loaded.player.mailForTomorrow.Contains(mail)) { SaveGame.loaded.player.mailForTomorrow.Add(mail); } if (farmer.mailReceived.Contains(mail + "%&NL&%") && !SaveGame.loaded.player.mailReceived.Contains(mail + "%&NL&%")) { SaveGame.loaded.player.mailReceived.Add(mail + "%&NL&%"); } if (farmer.mailForTomorrow.Contains(mail + "%&NL&%") && !SaveGame.loaded.player.mailForTomorrow.Contains(mail + "%&NL&%")) { SaveGame.loaded.player.mailForTomorrow.Add(mail + "%&NL&%"); } } // Maybe more } } }
public override void process(Server server, Server.Client client) { Log.debug("Got farmer data for client " + client.id); //SFarmer old = client.farmer; SaveGame theirs = (SaveGame)SaveGame.serializer.Deserialize(Util.stringStream(xml)); if (client.farmer == null) { ChatMenu.chat.Add(new ChatEntry(null, theirs.player.name + " has connected.")); server.broadcast(new ChatPacket(255, theirs.player.name + " has connected."), client.id); String str = "Currently playing: "; str += NewLoadMenu.pendingSelected.name; foreach (Server.Client other in server.clients) { if (other == client || other.farmer == null) { continue; } str += ", " + other.farmer.name; } client.send(new ChatPacket(255, str)); } client.farmerXml = Util.serialize <SFarmer>(theirs.player); client.farmer = theirs.player; client.farmer.uniqueMultiplayerID += 1 + client.id; NewSaveGame.loadDataToFarmer(client.farmer); client.farmer.FarmerSprite.setOwner(client.farmer); Game1.player.FarmerSprite.setOwner(Game1.player); //if(!server.playing) //if (server.playing) client.farmer = old; // About second-day-sleeping crashes: // So just adding the location directly puts the raw deserialized one into the game. // The raw deserialized one doesn't have the tiles and stuff loaded. Just the game data. // I think this is why vanilla copies data over in loadDataToLocations instead of using // the loaded objects directly. Why not just postpone loading until later, I don't know. // // So, when the second day begins, otherFarmer.currentLocation was still set to the // previous day's farm house[*]. On day two, the 'good' one[**] was removed, so when they go // back in, the bad one is used. Basically, I need to make them all the 'good' one. // For now, I'm just going to reload the needed data for this client's farmhouse. // I'll figure out how to do it 'properly' later. Maybe. (My mind is muddled today.) // // [*] Looking at addFixedLocationToOurWorld now you'll see that this isn't the case. // I added the part about fixing SFarmer.currentLocation as I was going through this // thought process. So things will break more obviously if something like this happens // again. // // [**] The first day's farmhouse is okay because in loadDataToLocations, (called in // NewSaveGame.getLoadEnumerator), the map is reloaded from FarmHouse_setMapForUpgradeLevel. // If CO-OP weren't on, worse things would happen, because things besides the farm house // would need loading (see Multiplayer.isPlayerUnique). The client doesn't have this // issue because they do the whole loading process each day anyways. // // Of course, the whole second-day-crash doesn't happen when I test it on localhost. Hence // why this was so annoying. And probably why I documented all this. foreach (GameLocation theirLoc in theirs.locations) { if (theirLoc.name == "FarmHouse") { NewSaveGame.FarmHouse_setMapForUpgradeLevel(theirLoc as FarmHouse); } } fixPetDuplicates(theirs); Multiplayer.fixLocations(theirs.locations, client.farmer, addFixedLocationToOurWorld, client); foreach (string mail in Multiplayer.checkMail) { if (client.farmer.mailForTomorrow.Contains(mail)) { if (!SaveGame.loaded.player.mailForTomorrow.Contains(mail)) { SaveGame.loaded.player.mailForTomorrow.Add(mail); } if (Game1.player != null && !Game1.player.mailForTomorrow.Contains(mail)) { Game1.player.mailForTomorrow.Add(mail); } } if (client.farmer.mailForTomorrow.Contains(mail + "%&NL&%")) { if (!SaveGame.loaded.player.mailForTomorrow.Contains(mail + "%&NL&%")) { SaveGame.loaded.player.mailForTomorrow.Add(mail + "%&NL&%"); } if (Game1.player != null && !Game1.player.mailForTomorrow.Contains(mail + "%&NL&%")) { Game1.player.mailForTomorrow.Add(mail + "%&NL&%"); } } } client.stage = Server.Client.NetStage.WaitingForStart; }
public NewLoadMenu() : base(Game1.viewport.Width / 2 - (1100 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 1100 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, false) { this.upArrow = new ClickableTextureComponent(new Rectangle(this.xPositionOnScreen + this.width + Game1.tileSize / 4, this.yPositionOnScreen + Game1.tileSize / 4, 11 * Game1.pixelZoom, 12 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(421, 459, 11, 12), (float)Game1.pixelZoom, false); this.downArrow = new ClickableTextureComponent(new Rectangle(this.xPositionOnScreen + this.width + Game1.tileSize / 4, this.yPositionOnScreen + this.height - Game1.tileSize, 11 * Game1.pixelZoom, 12 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(421, 472, 11, 12), (float)Game1.pixelZoom, false); this.scrollBar = new ClickableTextureComponent(new Rectangle(this.upArrow.bounds.X + Game1.pixelZoom * 3, this.upArrow.bounds.Y + this.upArrow.bounds.Height + Game1.pixelZoom, 6 * Game1.pixelZoom, 10 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(435, 463, 6, 10), (float)Game1.pixelZoom, false); this.scrollBarRunner = new Rectangle(this.scrollBar.bounds.X, this.upArrow.bounds.Y + this.upArrow.bounds.Height + Game1.pixelZoom, this.scrollBar.bounds.Width, this.height - Game1.tileSize - this.upArrow.bounds.Height - Game1.pixelZoom * 7); this.okDeleteButton = new ClickableTextureComponent("OK", new Rectangle((int)Utility.getTopLeftPositionForCenteringOnScreen(Game1.tileSize, Game1.tileSize, 0, 0).X - Game1.tileSize, (int)Utility.getTopLeftPositionForCenteringOnScreen(Game1.tileSize, Game1.tileSize, 0, 0).Y + Game1.tileSize * 2, Game1.tileSize, Game1.tileSize), null, null, Game1.mouseCursors, Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, 46, -1, -1), 1f, false); this.cancelDeleteButton = new ClickableTextureComponent("Cancel", new Rectangle((int)Utility.getTopLeftPositionForCenteringOnScreen(Game1.tileSize, Game1.tileSize, 0, 0).X + Game1.tileSize, (int)Utility.getTopLeftPositionForCenteringOnScreen(Game1.tileSize, Game1.tileSize, 0, 0).Y + Game1.tileSize * 2, Game1.tileSize, Game1.tileSize), null, null, Game1.mouseCursors, Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, 47, -1, -1), 1f, false); for (int i = 0; i < 4; i++) { this.gamesToLoadButton.Add(new ClickableComponent(new Rectangle(this.xPositionOnScreen + Game1.tileSize / 4, this.yPositionOnScreen + Game1.tileSize / 4 + i * (this.height / 4), this.width - Game1.tileSize / 2, this.height / 4 + Game1.pixelZoom), string.Concat(i))); this.deleteButtons.Add(new ClickableTextureComponent("", new Rectangle(this.xPositionOnScreen + this.width - Game1.tileSize - Game1.pixelZoom, this.yPositionOnScreen + Game1.tileSize / 2 + Game1.pixelZoom + i * (this.height / 4), 12 * Game1.pixelZoom, 12 * Game1.pixelZoom), "", "Delete File", Game1.mouseCursors, new Rectangle(322, 498, 12, 12), (float)Game1.pixelZoom * 3f / 4f, false)); } string text = Path.Combine(new string[] { Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley"), "Saves") }); if (Directory.Exists(text)) { string[] directories = Directory.GetDirectories(text); if (directories.Length != 0) { string[] array = directories; for (int j = 0; j < array.Length; j++) { string text2 = array[j]; try { Stream stream = null; try { stream = File.Open(Path.Combine(text, text2, "SaveGameInfo"), FileMode.Open); } catch (IOException) { if (stream != null) { stream.Close(); } } if (stream != null) { Farmer farmer = (Farmer)SaveGame.farmerSerializer.Deserialize(stream); NewSaveGame.loadDataToFarmer(farmer, farmer); farmer.favoriteThing = text2.Split(new char[] { Path.DirectorySeparatorChar }).Last <string>(); this.saveGames.Add(farmer); stream.Close(); } } catch (Exception) { } } } } this.saveGames.Sort(); }