public override void process(Client client) { Log.Async("Got world data"); //Log.Async(xml); SaveGame mine = SaveGame.loaded; /*if ( mine.player.spouse != null && mine.player.spouse.EndsWith( "engaged" ) && * mine.countdownToWedding == 0 && !mine.weddingToday ) * { * // Not (entirely) sure why this is happening in the first place, but this should fix it. * mine.player.spouse = mine.player.spouse.Replace("engaged", ""); * mine.weddingToday = true; * }*/ SaveGame world = ( SaveGame )SaveGame.serializer.Deserialize(Util.stringStream(xml)); if (Multiplayer.COOP) { mine.player.farmName = world.player.farmName; mine.player.money = world.player.money; mine.player.clubCoins = world.player.clubCoins; mine.player.totalMoneyEarned = world.player.totalMoneyEarned; mine.player.hasRustyKey = world.player.hasRustyKey; mine.player.hasSkullKey = world.player.hasSkullKey; mine.player.hasClubCard = world.player.hasClubCard; // Should I sync dark talisman / magic ink? mine.player.dateStringForSaveGame = world.player.dateStringForSaveGame; } world.player = mine.player; foreach (string mail in Multiplayer.checkMail) { if (world.mailbox.Contains(mail) && !mine.mailbox.Contains(mail)) { mine.mailbox.Add(mail); } if (world.player.mailForTomorrow.Contains(mail) && !mine.player.mailForTomorrow.Contains(mail)) { mine.player.mailForTomorrow.Add(mail); } if (world.player.mailReceived.Contains(mail) && !mine.player.mailReceived.Contains(mail)) { mine.player.mailReceived.Add(mail); } if (world.mailbox.Contains(mail + "%&NL&%") && !mine.mailbox.Contains(mail + "%&NL&%")) { mine.mailbox.Add(mail + "%&NL&%"); } if (world.player.mailForTomorrow.Contains(mail + "%&NL&%") && !mine.player.mailForTomorrow.Contains(mail + "%&NL&%")) { mine.player.mailForTomorrow.Add(mail + "%&NL&%"); } if (world.player.mailReceived.Contains(mail + "%&NL&%") && !mine.player.mailReceived.Contains(mail + "%&NL&%")) { mine.player.mailReceived.Add(mail + "%&NL&%"); } } world.mailbox = mine.mailbox; world.samBandName = mine.samBandName; world.elliottBookName = mine.elliottBookName; // wallpaper/flooring doesn't look needed? world.countdownToWedding = mine.countdownToWedding; world.weddingToday = mine.weddingToday; world.musicVolume = mine.musicVolume; world.soundVolume = mine.soundVolume; world.options = mine.options; world.minecartHighScore = mine.minecartHighScore; if (!Multiplayer.COOP) { world.stats = mine.stats; world.incubatingEgg = mine.incubatingEgg; world.dailyLuck = mine.dailyLuck; world.whichFarm = mine.whichFarm; world.shouldSpawnMonsters = mine.shouldSpawnMonsters; } world.mine_mineLevel = mine.mine_mineLevel; world.mine_nextLevel = mine.mine_nextLevel; world.mine_lowestLevelReached = mine.mine_lowestLevelReached; world.mine_resourceClumps = mine.mine_resourceClumps; world.mine_permanentMineChanges = mine.mine_permanentMineChanges; //} fixPetMultiplication(mine, world); fixRelationships(mine, world); Multiplayer.fixLocations(world.locations, null, debugStuff); Woods woods = null; GameLocation toRemove = null; foreach (GameLocation loc in world.locations) { if (loc.name == "FarmHouse") { toRemove = loc; } else if (loc.name == "Woods") { woods = (Woods)loc; } } if (toRemove != null) { world.locations.Remove(toRemove); } foreach (GameLocation loc in mine.locations) { if (loc.name == "FarmHouse") { world.locations.Add(loc); } else if (loc.name == "Woods" && woods != null) { Woods myWoods = ( Woods )loc; woods.hasUnlockedStatue = myWoods.hasUnlockedStatue; woods.hasFoundStardrop = myWoods.hasFoundStardrop; } } // See the giant block of comments in ClientFarmerDataPacket foreach (GameLocation theirLoc in world.locations) { if (theirLoc is FarmHouse) { Log.Async("FarmHouse: " + theirLoc.name); NewSaveGame.FarmHouse_setMapForUpgradeLevel(theirLoc as FarmHouse); } } /* * findReplaceLocation("FarmHouse", world.locations, mine.locations); * if ( !Multiplayer.COOP ) * { * findReplaceLocation("Farm", world.locations, mine.locations); * findReplaceLocation("FarmCave", world.locations, mine.locations); * findReplaceLocation("Greenhouse", world.locations, mine.locations); * findReplaceLocation("ArchaeologyHouse", world.locations, mine.locations); * findReplaceLocation("CommunityCenter", world.locations, mine.locations); * // ^ How should I do rewards? The ones that affect town permanently * // Mines? * }*/ SaveGame.loaded = world; client.stage = Client.NetStage.Waiting; //client.tempStopUpdating = true; }
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)); foreach (var quest in theirs.player.questLog) { if (quest is SlayMonsterQuest) { (quest as SlayMonsterQuest).loadQuestInfo(); } } 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; client.farmType = theirs.whichFarm; 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; --server.currentlyAccepting; }