void ReadReplayInfo(int index) { if (listBoxDemoList.Items.Count == 0 || index >= listBoxDemoList.Items.Count) { return; } ReplayListItem replayItem = (ReplayListItem)listBoxDemoList.Items[index]; if (replayItem.haveBeenUpdated) { return; } string pathOfFiles = replayItem.filePath; int firstSeparator = replayItem.fileName.IndexOf('_'); var demoDate = replayItem.fileName.Substring(0, firstSeparator + 1); if (demoDate.Length > 0) { int year = 0; int.TryParse(demoDate.Substring(0, 4), NumberStyles.Integer, CultureInfo.InvariantCulture, out year); int month = 0; int.TryParse(demoDate.Substring(4, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out month); int day = 0; int.TryParse(demoDate.Substring(6, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out day); int secondSeparator = replayItem.fileName.IndexOf('_', firstSeparator + 1); var demoTime = replayItem.fileName.Substring(firstSeparator + 1, secondSeparator + 1); int hour = 0; int.TryParse(demoTime.Substring(0, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out hour); int minute = 0; int.TryParse(demoTime.Substring(2, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out minute); int second = 0; int.TryParse(demoTime.Substring(4, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out second); replayItem.dateTime = new DateTime(year, month, day, hour, minute, second); } try{ using (FileStream fileStream = File.OpenRead(pathOfFiles)) using (var stream = new StreamReader(fileStream)) { replayItem.replaySize = (int)(fileStream.Length / 1024); String text = ""; string firstLine = stream.ReadLine(); String tmpText = ""; int openBracketCount = 0; bool inBracket = false; while ((openBracketCount > 0 || !inBracket) && !stream.EndOfStream) { tmpText = stream.ReadLine(); if (tmpText == null) { break; } if (tmpText.Length > 150) //skip, avoid waste time parsing it { continue; } text = text + tmpText; if (tmpText.StartsWith("{")) { inBracket = true; openBracketCount++; } else if (tmpText.StartsWith("}")) { openBracketCount--; } } if (text == "") { replayItem.crash = false; replayItem.haveBeenUpdated = true; return; } const char nullChar = '\0'; const char whiteSpace = ' '; string engineName = ""; int i = 24; while (i < firstLine.Length) { if (firstLine[i] == nullChar || firstLine[i] == whiteSpace) { break; } engineName = engineName + firstLine[i]; i++; } if (!engineName.Contains('.')) { engineName = engineName + ".0"; } replayItem.engine = engineName; int offset = 0; var config = new TableReaderConfig { contentSeparator = ';' }; var table = TableReader.ParseTable(config, 0, text, pathOfFiles, out offset); String gameName = ""; String hostName = ""; String mapName = ""; var allyPlayerCount = new int[32]; replayItem.players.Clear(); int totalElo = 0; int totalRank = 0; int eloCount = 0; int rankCount = 0; int aiCount = 0; foreach (var kvp in table) { //System.Diagnostics.Trace.TraceInformation("KEY: " + kvp.Key + " Value:" + (kvp.Value as String)); if (kvp.Key == "gametype") { gameName = (kvp.Value as String); } else if (kvp.Key == "mapname") { mapName = (kvp.Value as String); } else if (kvp.Key.StartsWith("ai")) { aiCount++; string name = ""; foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { switch (kvp2.Key) { case "shortname": name = (kvp2.Value as String); break; } } if (name != "") { replayItem.ais.Add(name); } } else if (kvp.Key == "myplayername") { hostName = (kvp.Value as String); } else if (kvp.Key.StartsWith("team")) { foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { if (kvp2.Key == "allyteam") { int numbers = 0; int.TryParse((kvp2.Value as String), NumberStyles.Integer, CultureInfo.InvariantCulture, out numbers); allyPlayerCount[numbers]++; break; } } } else if (kvp.Key.StartsWith("player")) { int eloNumbers = -1; int rankNumbers = -1; string name = ""; bool isSpectator = false; foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { switch (kvp2.Key) { case "name": name = (kvp2.Value as String); break; case "elo": int.TryParse((kvp2.Value as String), NumberStyles.Integer, CultureInfo.InvariantCulture, out eloNumbers); break; case "rank": int.TryParse((kvp2.Value as String), NumberStyles.Integer, CultureInfo.InvariantCulture, out rankNumbers); break; case "spectator": int numbers = 0; int.TryParse((kvp2.Value as String), NumberStyles.Integer, CultureInfo.InvariantCulture, out numbers); isSpectator = (numbers > 0); break; } } if (!isSpectator) { if (rankNumbers > -1) { rankCount++; totalRank = totalRank + rankNumbers; } if (eloNumbers > -1) { eloCount++; totalElo = totalElo + eloNumbers; } replayItem.players.Add(name); } } } String versusCount = ""; bool firstNumberEntered = false; for (int j = 0; j < allyPlayerCount.Length; j++) { if (allyPlayerCount[j] > 0) { if (!firstNumberEntered) { firstNumberEntered = true; versusCount = allyPlayerCount[j].ToString(); } else { versusCount = versusCount + "v" + allyPlayerCount[j]; } } } if (rankCount == 0) { rankCount = -1; //avoid div by 0 } if (eloCount == 0) { eloCount = -1; } //reference: http://www.dotnetperls.com/string-format //var formattedText = String.Format("Host:{0,-14} " + (versusCount!=""?"Balance:{1,-6} ":"") + "Map:{2,-23} " + (eloCount>0?"Average elo:{3,-5} ":"") + (rankCount>0?"Average rank:{4,-3}":"") + (aiCount>0?"have {5,-3} AI ":"") + "Game:{6,-10}", hostName, versusCount, mapName, totalElo/eloCount, totalRank/rankCount,aiCount,gameName); replayItem.aiCount = aiCount; replayItem.averageElo = totalElo / eloCount; replayItem.averageRank = totalRank / rankCount; replayItem.mapName = mapName; replayItem.gameName = gameName; replayItem.balance = versusCount; replayItem.hostName = hostName; } replayItem.crash = false; replayItem.haveBeenUpdated = true; }catch (Exception e) { replayItem.crash = true; replayItem.haveBeenUpdated = false; Trace.TraceError("LocalReplay info reader error: {0}", e); } }
/// <summary> /// Read options from EngineOptions.lua or ModOptions.lua /// </summary> public static void ReadOptionsTable(String filePath, ref Mod modInfo) { if (!File.Exists(filePath)) { return; } var allOptions = new List <Option>(); using (FileStream fileStream = File.OpenRead(filePath)) using (var stream = new StreamReader(fileStream)) { var allText = stream.ReadToEnd(); int offset = 0; var config = new TableReaderConfig(); var table = TableReader.ParseTable(config, 0, allText, filePath, out offset); foreach (var kvp in table) { var anOption = new Option(); bool isBoolOption = false; foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { var value = (kvp2.Value as String); float numbers; //uncomment to take a peek on what it read!: //System.Diagnostics.Trace.TraceWarning("key: " + kvp2.Key + " value:" + value); switch (kvp2.Key) { case "key": anOption.Key = value; break; case "name": anOption.Name = value; break; case "desc": anOption.Description = value; break; case "type": switch (value) { case "bool": anOption.Type = OptionType.Bool; isBoolOption = true; break; case "list": anOption.Type = OptionType.List; break; case "number": anOption.Type = OptionType.Number; break; case "string": anOption.Type = OptionType.String; break; case "section": anOption.Type = OptionType.Section; continue; default: anOption.Type = OptionType.Undefined; break; } break; case "def": anOption.Default = value; if (isBoolOption) { if (value == "false") { anOption.Default = "0"; } else { anOption.Default = "1"; } } break; case "min": float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out numbers); anOption.Min = numbers; break; case "max": float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out numbers); anOption.Max = numbers; break; case "step": float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out numbers); anOption.Step = numbers; break; case "maxlen": float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out numbers); anOption.StrMaxLen = numbers; break; case "items": var listOptions = new List <ListOption>(); foreach (var kvp3 in (kvp2.Value as Dictionary <String, Object>)) { var listOption = new ListOption(); foreach (var kvp4 in (kvp3.Value as Dictionary <String, Object>)) { var value2 = (kvp4.Value as String); switch (kvp4.Key) { case "key": listOption.Key = value2; break; case "name": listOption.Name = value2; break; case "desc": listOption.Description = value2; break; } } if (listOption.Key != null) { listOptions.Add(listOption); } } anOption.ListOptions = listOptions; break; case "scope": anOption.Scope = value; break; case "section": anOption.Section = value; break; } } if (anOption.Key != null) { allOptions.Add(anOption); } } } if (modInfo.Options != null) { modInfo.Options = modInfo.Options.ToList().Concat(allOptions).ToArray(); } else { modInfo.Options = allOptions.ToArray(); } }
/// <summary> /// Read mission.lua file. /// </summary> public static void ReadMissionSlot(string filePath, ref Mod modInfo) { if (!File.Exists(filePath)) { return; } using (FileStream fileStream = File.OpenRead(filePath)) using (var stream = new StreamReader(fileStream)) { var allText = stream.ReadToEnd(); int offset = 0; var config = new TableReaderConfig(); var table = TableReader.ParseTable(config, 0, allText, filePath, out offset); var allSlots = new List <MissionSlot>(); foreach (var kvp in table) { var slot = new MissionSlot(); int numbers = 0; foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { var value = (kvp2.Value as String); switch (kvp2.Key) { case "AllyID": int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out numbers); slot.AllyID = numbers; break; case "AllyName": slot.AllyName = value; break; case "IsHuman": slot.IsHuman = (value == "true"); break; case "IsRequired": slot.IsRequired = (value == "true"); break; case "TeamID": int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out numbers); slot.TeamID = numbers; break; case "TeamName": slot.TeamName = value; break; case "Color": int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out numbers); slot.Color = numbers; //var springColor = (MyCol)numbers; //slot.ColorR = springColor.R; //slot.ColorG = springColor.G; //slot.ColorB = springColor.B; break; //case "ColorR": // break; //case "ColorG": // break; //case "ColorB": // break; case "AiShortName": slot.AiShortName = value; break; case "AiVersion": slot.AiVersion = value; break; } } if (slot.AiShortName != null) { allSlots.Add(slot); } } modInfo.MissionSlots = allSlots; } }
/// <summary> /// Read mod information from modInfo.lua /// </summary> public static void ParseModInfo(string filePath, ref Mod modInfo) { if (!File.Exists(filePath)) { return; } using (FileStream fileStream = File.OpenRead(filePath)) using (var stream = new StreamReader(fileStream)) { var allText = stream.ReadToEnd(); int offset = 0; var config = new TableReaderConfig(); var table = TableReader.ParseTable(config, 0, allText, filePath, out offset); foreach (var kvp in table) { var value = (kvp.Value as String); switch (kvp.Key) { case "name": modInfo.Name = value; break; case "description": modInfo.Description = value; break; case "shortname": modInfo.ShortName = value; break; case "version": modInfo.PrimaryModVersion = value; break; case "mutator": modInfo.Mutator = value; break; case "game": modInfo.Game = value; break; case "shortGame": modInfo.ShortGame = value; break; case "modtype": //TODO modtype?? break; case "depend": var listDepend = new List <string>(); foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { var value2 = (kvp2.Value as String); listDepend.Add(value2); } modInfo.Dependencies = listDepend; break; } } } }
/// <summary> /// Parse sides name from gamedata/sidedata.lua and side icon (.bmp format with same name as side name) from sidepics/ /// </summary> public static void ReadSideInfo(string sidedataluaPath, string picPath, ref Mod modInfo) { if (!File.Exists(sidedataluaPath)) { modInfo.Sides = new string[0]; //modInfo.SideIcons = (new List<Byte[]>()).ToArray(); //modInfo.StartUnits = new PlasmaShared.SerializableDictionary<string, string>(new Dictionary<string,string>()); return; } using (FileStream fileStream = File.OpenRead(sidedataluaPath)) using (var stream = new StreamReader(fileStream)) { var allText = stream.ReadToEnd(); int offset = 0; var config = new TableReaderConfig(); var table = TableReader.ParseTable(config, 0, allText, sidedataluaPath, out offset); List <String> sides = new List <String>(); List <byte[]> sideIcons = new List <byte[]>(); var startUnits = new Dictionary <string, string>(); //PlasmaShared.SerializableDictionary<string,string>(); foreach (var kvp in table) { String name = ""; String startunit = ""; foreach (var kvp2 in (kvp.Value as Dictionary <String, Object>)) { var value = (kvp2.Value as String); switch (kvp2.Key) { case "name": name = value; break; case "startunit": startunit = value; break; } } if (name != "") { var picBytes = new Byte[0]; try{ var picList = Directory.EnumerateFiles(picPath); using (FileStream fileStream2 = File.OpenRead(picList.First(x => SkirmishControlTool.GetFolderOrFileName(x).StartsWith(name, StringComparison.InvariantCultureIgnoreCase)))) { picBytes = new Byte[fileStream2.Length]; fileStream2.Read(picBytes, 0, picBytes.Length); } }catch (Exception e) { System.Diagnostics.Trace.TraceError(e.ToString()); } sides.Add(name); sideIcons.Add(picBytes); startUnits.Add(name, startunit); } } modInfo.Sides = sides.ToArray(); modInfo.SideIcons = sideIcons.ToArray(); modInfo.StartUnits = new SerializableDictionary <string, string>(startUnits); } }