/// <summary> /// Read and parse match data to extract match information. /// </summary> /// <returns>The puzzle from match.</returns> /// <param name="match">Match.</param> public static TransferablePuzzleData GetPuzzleFromMatch(GKTurnBasedMatch match) { // Filter obviously invalid matches if (match.MatchData == null || match.MatchData.Length == 0) { Logger.E("Match without data! Maybe an old one? Shouldn't happend in production."); return(null); } try { // Try to get the XML inside string xml = NSString.FromData(match.MatchData, NSStringEncoding.UTF8); TransferablePuzzleData tp = null; XmlSerializer xmlSerializer = new XmlSerializer(typeof(TransferablePuzzleData)); using (StringReader reader = new StringReader(xml)) { tp = (TransferablePuzzleData)xmlSerializer.Deserialize(reader); } xmlSerializer = null; // Save the image if we don't have it locally if (tp != null) { if (string.IsNullOrEmpty(tp.Base64Image) == false) { if (File.Exists(tp.Puzzle.Filename) == false) { byte[] imgRaw = Convert.FromBase64String(tp.Base64Image); NSData imageData = NSData.FromArray(imgRaw); UIImage img = UIImage.LoadFromData(imageData); NSError err = null; img.AsPNG().Save(tp.Puzzle.Filename, false, out err); } } } return(tp); } catch (Exception e) { Logger.E("GameCenterPlayer.FoundMatch", e); return(null); } }
/// <summary> /// List matches with friends /// </summary> /// <param name="listLoaded">List loaded.</param> public static void GetFriendsPuzzles(Action <List <PuzzleData> > listLoaded) { Logger.I("Game center: requesting turn based matches..."); GKTurnBasedMatch.LoadMatches((matches, error) => { if (error != null) { Logger.E("Game Center: match list failed... ", error); } else { Logger.I("Game center: " + matches.Length + " turn based matches found."); List <PuzzleData> puzzles = new List <PuzzleData> (); foreach (GKTurnBasedMatch match in matches) { // Deserialize data TransferablePuzzleData tp = GetPuzzleFromMatch(match); if (tp != null) { tp.Puzzle.MatchId = match.MatchID; tp.Puzzle.Match = match; puzzles.Add(tp.Puzzle); } } if (listLoaded != null) { listLoaded(puzzles); } } }); }
/// <summary> /// Update versus match status /// </summary> public static void UpdateMatchFromPuzzle(PuzzleData puzzle, Action <NSError> callback) { if (puzzle.Match == null) { Logger.E("This puzzle contains no match data... Can't do anything!"); return; } // Match data -> Puzzle + Image // -- Image as Base64 string UIImage image = UIImage.FromFile(puzzle.Filename); Byte[] byteArray = null; using (NSData nsImageData = image.AsPNG()) { byteArray = new Byte[nsImageData.Length]; System.Runtime.InteropServices.Marshal.Copy(nsImageData.Bytes, byteArray, 0, Convert.ToInt32(nsImageData.Length)); } string base64image = Convert.ToBase64String(byteArray); // -- Data TransferablePuzzleData tp = new TransferablePuzzleData(); tp.Puzzle = puzzle; tp.Base64Image = base64image; // Build an XML text string xml = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(tp.GetType()); using (StringWriter textWriter = new StringWriter()) { xmlSerializer.Serialize(textWriter, tp); xml = textWriter.ToString(); } xmlSerializer = null; // Xml to bytes NSData puzzleData = NSData.FromString(xml); // Next participant GKTurnBasedParticipant nextPlayer = null; foreach (var participant in puzzle.Match.Participants) { if (participant.PlayerID != GKLocalPlayer.LocalPlayer.PlayerID) { nextPlayer = participant; break; } } // Game center match progress // -- Already an opponent score? End if (puzzle.GetBestPlayerScore(nextPlayer.PlayerID).HasValue) { puzzle.Match.EndMatchInTurn( puzzleData, (err) => { if (callback != null) { callback(err); } } ); } else { // -- Send current score puzzle.Match.EndTurn( new GKTurnBasedParticipant[] { nextPlayer }, 120, puzzleData, callback ); } }