public static GameInformation Deserialize(string data) { try { var info = new GameInformation(); var nodes = MiniYaml.FromString(data); foreach (var node in nodes) { var keyParts = node.Key.Split('@'); switch (keyParts[0]) { case "Root": FieldLoader.Load(info, node.Value); break; case "Player": info.Players.Add(FieldLoader.Load <Player>(node.Value)); break; } } return(info); } catch (InvalidOperationException) { Log.Write("debug", "GameInformation deserialized invalid MiniYaml:\n{0}".F(data)); throw; } }
public void QueryRemoteMapDetails(string repositoryUrl, IEnumerable <string> uids, Action <MapPreview> mapDetailsReceived = null, Action queryFailed = null) { var maps = uids.Distinct() .Select(uid => previews[uid]) .Where(p => p.Status == MapStatus.Unavailable) .ToDictionary(p => p.Uid, p => p); if (!maps.Any()) { return; } foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Searching, null); } var url = repositoryUrl + "hash/" + string.Join(",", maps.Keys) + "/yaml"; Action <DownloadDataCompletedEventArgs> onInfoComplete = i => { if (i.Error != null) { Log.Write("debug", "Remote map query failed with error: {0}", Download.FormatErrorMessage(i.Error)); Log.Write("debug", "URL was: {0}", url); foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Unavailable, null); } if (queryFailed != null) { queryFailed(); } return; } var data = Encoding.UTF8.GetString(i.Result); try { var yaml = MiniYaml.FromString(data); foreach (var kv in yaml) { maps[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value, mapDetailsReceived); } } catch (Exception e) { Log.Write("debug", "Can't parse remote map search data:\n{0}", data); Log.Write("debug", "Exception: {0}", e); if (queryFailed != null) { queryFailed(); } } }; new Download(url, _ => { }, onInfoComplete); }
public void QueryRemoteMapDetails(string repositoryUrl, IEnumerable <string> uids, Action <MapPreview> mapDetailsReceived = null, Action <MapPreview> mapQueryFailed = null) { var queryUids = uids.Distinct() .Where(uid => uid != null) .Select(uid => previews[uid]) .Where(p => p.Status == MapStatus.Unavailable) .Select(p => p.Uid) .ToList(); foreach (var uid in queryUids) { previews[uid].UpdateRemoteSearch(MapStatus.Searching, null); } Task.Run(async() => { var client = HttpClientFactory.Create(); // Limit each query to 50 maps at a time to avoid request size limits for (var i = 0; i < queryUids.Count; i += 50) { var batchUids = queryUids.Skip(i).Take(50).ToList(); var url = repositoryUrl + "hash/" + string.Join(",", batchUids) + "/yaml"; try { var httpResponseMessage = await client.GetAsync(url); var result = await httpResponseMessage.Content.ReadAsStringAsync(); var yaml = MiniYaml.FromString(result); foreach (var kv in yaml) { previews[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value, mapDetailsReceived); } foreach (var uid in batchUids) { var p = previews[uid]; if (p.Status != MapStatus.DownloadAvailable) { p.UpdateRemoteSearch(MapStatus.Unavailable, null); } } } catch (Exception e) { Log.Write("debug", "Remote map query failed with error: {0}", e); Log.Write("debug", "URL was: {0}", url); foreach (var uid in batchUids) { var p = previews[uid]; p.UpdateRemoteSearch(MapStatus.Unavailable, null); mapQueryFailed?.Invoke(p); } } } }); }
public void QueryRemoteMapDetails(string repositoryUrl, IEnumerable <string> uids, Action <MapPreview> mapDetailsReceived = null, Action queryFailed = null) { var maps = uids.Distinct() .Where(uid => uid != null) .Select(uid => previews[uid]) .Where(p => p.Status == MapStatus.Unavailable) .ToDictionary(p => p.Uid, p => p); if (!maps.Any()) { return; } foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Searching, null); } var url = repositoryUrl + "hash/" + string.Join(",", maps.Keys) + "/yaml"; Task.Run(async() => { try { var client = HttpClientFactory.Create(); var httpResponseMessage = await client.GetAsync(url); var result = await httpResponseMessage.Content.ReadAsStringAsync(); var yaml = MiniYaml.FromString(result); foreach (var kv in yaml) { maps[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value, mapDetailsReceived); } foreach (var map in maps) { if (map.Value.Status != MapStatus.DownloadAvailable) { map.Value.UpdateRemoteSearch(MapStatus.Unavailable, null); } } } catch (Exception e) { Log.Write("debug", "Remote map query failed with error: {0}", e); Log.Write("debug", "URL was: {0}", url); foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Unavailable, null); } queryFailed?.Invoke(); } }); }
public void RefreshPlayerData(Action onComplete = null) { if (State != LinkState.Unlinked && State != LinkState.Linked && State != LinkState.ConnectionFailed) { return; } Action <DownloadDataCompletedEventArgs> onQueryComplete = i => { try { if (i.Error != null) { innerState = LinkState.ConnectionFailed; return; } var yaml = MiniYaml.FromString(Encoding.UTF8.GetString(i.Result)).First(); if (yaml.Key == "Player") { innerData = FieldLoader.Load <PlayerProfile>(yaml.Value); if (innerData.KeyRevoked) { Log.Write("debug", "Revoking key with fingerprint {0}", Fingerprint); DeleteKeypair(); } else { innerState = LinkState.Linked; } } else { innerState = LinkState.Unlinked; } } catch (Exception e) { Log.Write("debug", "Failed to parse player data result with exception: {0}", e); innerState = LinkState.ConnectionFailed; } finally { if (onComplete != null) { onComplete(); } } }; innerState = LinkState.CheckingLink; new Download(playerDatabase.Profile + Fingerprint, _ => { }, onQueryComplete); }
public void QueryRemoteMapDetails(IEnumerable <string> uids) { var maps = uids.Distinct() .Select(uid => previews[uid]) .Where(p => p.Status == MapStatus.Unavailable) .ToDictionary(p => p.Uid, p => p); if (!maps.Any()) { return; } foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Searching, null); } var url = Game.Settings.Game.MapRepository + "hash/" + string.Join(",", maps.Keys) + "/yaml"; Action <DownloadDataCompletedEventArgs, bool> onInfoComplete = (i, cancelled) => { if (cancelled || i.Error != null) { Log.Write("debug", "Remote map query failed with error: {0}", i.Error != null ? i.Error.Message : "cancelled"); Log.Write("debug", "URL was: {0}", url); foreach (var p in maps.Values) { p.UpdateRemoteSearch(MapStatus.Unavailable, null); } return; } var data = Encoding.UTF8.GetString(i.Result); try { var yaml = MiniYaml.FromString(data); foreach (var kv in yaml) { maps[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value); } } catch { Log.Write("debug", "Can't parse remote map search data:\n{0}", data); } }; new Download(url, _ => { }, onInfoComplete); }
public void RefreshPlayerData(Action onComplete = null) { if (State != LinkState.Unlinked && State != LinkState.Linked && State != LinkState.ConnectionFailed) { return; } Task.Run(async() => { try { var client = HttpClientFactory.Create(); var httpResponseMessage = await client.GetAsync(playerDatabase.Profile + Fingerprint); var result = await httpResponseMessage.Content.ReadAsStringAsync(); var yaml = MiniYaml.FromString(result).First(); if (yaml.Key == "Player") { innerData = FieldLoader.Load <PlayerProfile>(yaml.Value); if (innerData.KeyRevoked) { Log.Write("debug", "Revoking key with fingerprint {0}", Fingerprint); DeleteKeypair(); } else { innerState = LinkState.Linked; } } else { innerState = LinkState.Unlinked; } } catch (Exception e) { Log.Write("debug", "Failed to parse player data result with exception: {0}", e); innerState = LinkState.ConnectionFailed; } finally { onComplete?.Invoke(); } }); innerState = LinkState.CheckingLink; }
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action <MapPreview> parseMetadata = null) { var newData = innerData.Clone(); newData.Status = status; newData.Class = MapClassification.Remote; if (status == MapStatus.DownloadAvailable) { try { var r = FieldLoader.Load <RemoteMapData>(yaml); // Map download has been disabled server side if (!r.downloading) { newData.Status = MapStatus.Unavailable; return; } newData.Title = r.title; newData.Categories = r.categories; newData.Author = r.author; newData.PlayerCount = r.players; newData.Bounds = r.bounds; newData.TileSet = r.tileset; newData.MapFormat = r.mapformat; var spawns = new CPos[r.spawnpoints.Length / 2]; for (var j = 0; j < r.spawnpoints.Length; j += 2) { spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]); } newData.SpawnPoints = spawns; newData.GridType = r.map_grid_type; try { newData.Preview = new Png(new MemoryStream(Convert.FromBase64String(r.minimap))); } catch (Exception e) { Log.Write("debug", "Failed parsing mapserver minimap response: {0}", e); newData.Preview = null; } var playersString = Encoding.UTF8.GetString(Convert.FromBase64String(r.players_block)); newData.Players = new MapPlayers(MiniYaml.FromString(playersString)); var rulesString = Encoding.UTF8.GetString(Convert.FromBase64String(r.rules)); var rulesYaml = new MiniYaml("", MiniYaml.FromString(rulesString)).ToDictionary(); newData.SetCustomRules(modData, this, rulesYaml); } catch (Exception e) { Log.Write("debug", "Failed parsing mapserver response: {0}", e); } // Commit updated data before running the callbacks innerData = newData; if (innerData.Preview != null) { cache.CacheMinimap(this); } parseMetadata?.Invoke(this); } // Update the status and class unconditionally innerData = newData; }
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action <MapPreview> parseMetadata = null) { var newData = innerData.Clone(); newData.Status = status; newData.Class = MapClassification.Remote; if (status == MapStatus.DownloadAvailable) { try { var r = FieldLoader.Load <RemoteMapData>(yaml); // Map download has been disabled server side if (!r.downloading) { newData.Status = MapStatus.Unavailable; return; } newData.Title = r.title; newData.Categories = r.categories; newData.Author = r.author; newData.PlayerCount = r.players; newData.Bounds = r.bounds; newData.TileSet = r.tileset; var spawns = new CPos[r.spawnpoints.Length / 2]; for (var j = 0; j < r.spawnpoints.Length; j += 2) { spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]); } newData.SpawnPoints = spawns; newData.GridType = r.map_grid_type; try { newData.Preview = new Bitmap(new MemoryStream(Convert.FromBase64String(r.minimap))); } catch (Exception e) { Log.Write("debug", "Failed parsing mapserver minimap response: {0}", e); newData.Preview = null; } var playersString = Encoding.UTF8.GetString(Convert.FromBase64String(r.players_block)); newData.Players = new MapPlayers(MiniYaml.FromString(playersString)); newData.SetRulesetGenerator(modData, () => { var rulesString = Encoding.UTF8.GetString(Convert.FromBase64String(r.rules)); var rulesYaml = new MiniYaml("", MiniYaml.FromString(rulesString)).ToDictionary(); var ruleDefinitions = LoadRuleSection(rulesYaml, "Rules"); var weaponDefinitions = LoadRuleSection(rulesYaml, "Weapons"); var voiceDefinitions = LoadRuleSection(rulesYaml, "Voices"); var musicDefinitions = LoadRuleSection(rulesYaml, "Music"); var notificationDefinitions = LoadRuleSection(rulesYaml, "Notifications"); var sequenceDefinitions = LoadRuleSection(rulesYaml, "Sequences"); var modelSequenceDefinitions = LoadRuleSection(rulesYaml, "ModelSequences"); var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions); var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions); return(Pair.New(rules, flagged)); }); } catch (Exception e) { Log.Write("debug", "Failed parsing mapserver response: {0}", e); } // Commit updated data before running the callbacks innerData = newData; if (innerData.Preview != null) { cache.CacheMinimap(this); } if (parseMetadata != null) { parseMetadata(this); } } // Update the status and class unconditionally innerData = newData; }