public static string GetModOptionSummary(Mod mod, Dictionary<string, string> setOptions, bool useSectionHeaders) { try { var sectionNames = mod.Options.Where(o => o.Type == OptionType.Section).ToDictionary(o => o.Key.ToUpper(), o => o.Name); var sections = from option in mod.Options join pair in setOptions on option.Key equals pair.Key where pair.Value != option.Default group new { pair, option } by option.Section; var optionBuilder = new StringBuilder(); foreach (var section in sections) { var indent = false; if (useSectionHeaders && !String.IsNullOrEmpty(section.Key)) { indent = true; optionBuilder.AppendLine(sectionNames[section.Key.ToUpper()]); optionBuilder.AppendLine(); } foreach (var o in section) { string line = null; switch (o.option.Type) { case OptionType.Bool: line = o.option.Name + ": " + (o.pair.Value == "0" ? "No" : "Yes"); break; case OptionType.Number: line = o.option.Name + ": " + o.pair.Value; break; case OptionType.String: line = o.option.Name + ": " + o.pair.Value; break; case OptionType.List: var valueName = o.option.ListOptions.Single(opt => opt.Key == o.pair.Value).Name; line = o.option.Name + ": " + valueName; break; } optionBuilder.AppendLine((indent ? "\t" : String.Empty) + line); } if (useSectionHeaders) optionBuilder.AppendLine(); } return optionBuilder.ToString(); } catch (Exception e) { Trace.WriteLine("Error in building mod option summary: " + e); return String.Empty; } }
public ModStore() { Program.TasClient.ModOptionsChanged += (s, e) => SetModOptions(e.ModOptions); Program.TasClient.BattleJoinSuccess += (s, e) => { if (mod != null && mod.Name != Program.TasClient.MyBattle.ModName) { Ais = null; mod = null; } Program.MetaData.GetModAsync(Program.TasClient.MyBattle.ModName, HandleMod, exception => { }); }; }
public ModOptionsControl(Mod forOffline = null, Dictionary<string,string> currentOption = null) { if (forOffline != null) { offlineMode = true; mod = forOffline; offlineOptions = currentOption; if (currentOption == null) offlineOptions = new Dictionary<string, string>(); } InitializeComponent(); changesBox = new TextBox { Multiline = true, ReadOnly = true, BackColor = Color.White, Dock = DockStyle.Fill }; var changesTab = new TabPage { Text = "Changes" }; changesTab.Controls.Add(changesBox); tabControl.TabPages.Add(changesTab); tooltip.UseFading = false; tooltip.UseAnimation = false; tooltip.InitialDelay = 0; tooltip.ReshowDelay = 0; tooltip.AutoPopDelay = 10000; tooltip.BackColor = Color.FromArgb(255, 255, 225); // its ignored by it }
public void UpdateMission(ZkDataContext db, Mission mission, Mod modInfo) { var file = mission.Mutator.ToArray(); var tempName = Path.GetTempFileName() + ".zip"; File.WriteAllBytes(tempName, file); using (var zf = ZipFile.Open(tempName, ZipArchiveMode.Update)) { var modinfoEntry = zf.GetEntry("modinfo.lua"); modinfoEntry.Delete(); modinfoEntry = zf.CreateEntry("modinfo.lua"); WriteZipArchiveEntry(modinfoEntry, GetModInfo(mission.NameWithVersion, mission.ModRapidTag, mission.Name, "ZK")); FixScript(mission, zf, "script.txt"); var script = FixScript(mission, zf, GlobalConst.MissionScriptFileName); modInfo.MissionScript = script; //modInfo.ShortName = mission.Name; modInfo.Name = mission.NameWithVersion; } mission.Mutator = File.ReadAllBytes(tempName); if (string.IsNullOrEmpty(mission.Script)) mission.Script = " "; // tweak for silly update validation mission.Script = Regex.Replace(mission.Script, "GameType=([^;]+);", (m) => $"GameType={mission.NameWithVersion};"); File.Delete(tempName); var resource = db.Resources.FirstOrDefault(x => x.MissionID == mission.MissionID); if (resource == null) { resource = new Resource() { DownloadCount = 0, TypeID = ZkData.ResourceType.Mod }; db.Resources.Add(resource); } resource.InternalName = mission.NameWithVersion; resource.MissionID = mission.MissionID; resource.ResourceDependencies.Clear(); resource.ResourceDependencies.Add(new ResourceDependency() { NeedsInternalName = mission.Map }); resource.ResourceDependencies.Add(new ResourceDependency() { NeedsInternalName = mission.Mod }); resource.ResourceContentFiles.Clear(); // generate torrent var tempFile = Path.Combine(Path.GetTempPath(), mission.SanitizedFileName); File.WriteAllBytes(tempFile, mission.Mutator.ToArray()); var creator = new TorrentCreator(); creator.Path = tempFile; var torrentStream = new MemoryStream(); creator.Create(torrentStream); try { File.Delete(tempFile); } catch { } var md5 = Hash.HashBytes(mission.Mutator.ToArray()).ToString(); resource.ResourceContentFiles.Add(new ResourceContentFile() { FileName = mission.SanitizedFileName, Length = mission.Mutator.Length, LinkCount = 1, Links = string.Format(MissionFileUrl, mission.MissionID), Md5 = md5 }); var basePath = GlobalConst.SiteDiskPath + @"\resources\"; if (!Directory.Exists(basePath)) Directory.CreateDirectory(basePath); File.WriteAllBytes(string.Format(@"{2}\{0}_{1}.torrent", resource.InternalName.EscapePath(), md5, basePath), torrentStream.ToArray()); File.WriteAllBytes(string.Format(@"{1}\{0}.metadata.xml.gz", resource.InternalName.EscapePath(), basePath), MetaDataCache.SerializeAndCompressMetaData(modInfo)); var imgPath = GlobalConst.SiteDiskPath + @"\img\missions\"; if (!Directory.Exists(imgPath)) Directory.CreateDirectory(imgPath); File.WriteAllBytes(string.Format(imgPath + "{0}.png", mission.MissionID, basePath), mission.Image.ToArray()); }
public static List<Mod> GetPartialSddMods() { var sddMods = new List<Mod>(); var modFolder = Utils.MakePath(Program.SpringPaths.DataDirectories.First(), "games"); var sddFolder = System.IO.Directory.EnumerateDirectories(modFolder, "*.sdd"); //.ToList<string>(); foreach (string path in sddFolder) { var modinfo = Utils.MakePath(path,"modinfo.lua"); if (File.Exists(modinfo)) { var mod = new Mod(); mod.ArchiveName = GetFolderOrFileName(path); CrudeLUAReader.ParseModInfo(modinfo,ref mod); sddMods.Add(mod); } } return sddMods; }
public Mod GetMod(ResourceInfo ae) { if (disposed) throw new ObjectDisposedException("Unitsync has already been released."); NativeMethods.RemoveAllArchives(); NativeMethods.GetPrimaryModCount(); // pre-requisite for the following calls NativeMethods.AddAllArchives(ae.Name); string[] sides; var mod = new Mod(ae) { UnitDefs = GetUnitList().Select(ui => new UnitInfo(ui.Name, ui.FullName)).ToArray(), StartUnits = new SerializableDictionary<string, string>(GetStartUnits(out sides)), Sides = sides, Options = GetModOptions().ToArray(), SideIcons = GetSideIcons(sides).ToArray(), ModAis = GetAis().Where(ai => ai.IsLuaAi).ToArray() }; Trace.TraceInformation("Mod Information: Description {0}, Game {1}, Mutator {2}, ShortGame {3}, PrimaryModVersion {4}", mod.Description, mod.Game, mod.Mutator, mod.ShortGame, mod.PrimaryModVersion); var buf = ReadVfsFile(GlobalConst.MissionScriptFileName); if ((buf != null) && (buf.Length > 0)) mod.MissionScript = Encoding.UTF8.GetString(buf, 0, buf.Length); if (!string.IsNullOrEmpty(mod.MissionScript)) try { buf = ReadVfsFile(GlobalConst.MissionSlotsFileName); var slotString = Encoding.UTF8.GetString(buf, 0, buf.Length); var ser = new XmlSerializer(typeof(List<MissionSlot>)); mod.MissionSlots = (List<MissionSlot>)ser.Deserialize(new StringReader(slotString)); } catch (Exception ex) { Trace.TraceError("Error reading mission slots from mod {0}: {1}", mod.Name, ex); } if (mod.Sides.Length == 0) Trace.WriteLine("Mod has no faction"); if (mod.UnitDefs.Length == 0) Trace.WriteLine("No unit found."); NativeMethods.RemoveAllArchives(); TraceErrors(); return mod; }
private void Setup_MissionModInfo(Mod mod) { myItem.MissionSlot = null; if (missionSlots.Count == 0) missionSlots = null; if (missionSlots != null) { foreach (MissionSlot slot in missionSlots.Where(s => s.IsHuman)) { myItem.MissionSlot = slot; Set_MyBattleStatus(slot.AllyID, slot.TeamID, false); break; } botsMissionSlot.Clear(); Bots.Clear(); foreach (var slot in missionSlots.Where(s => s.AiShortName != null)) { botsMissionSlot.Add(slot); Set_BotBattleStatus(slot.AiShortName, myItem.UserName, slot.TeamID, slot.AllyID, (int)(MyCol)slot.Color,slot.AiVersion); } } else { if (botsMissionSlot.Count > 0) { Bots.Clear(); botsMissionSlot.Clear(); } } if (currentMod.IsMission) { //disable some button for mission mod. playerBox shortcut is disabled in Event_PlayerBox_MouseDown() spectateCheckBox.Enabled = false; addAIButton.Enabled = false; editTeamButton.Enabled = false; //get targeted map for mission mod string mapname; var script = mod.MissionScript; if (mod.MissionMap != null) mapname = mod.MissionMap; else { var open = script.IndexOf("mapname", 7, script.Length - 8, StringComparison.InvariantCultureIgnoreCase) + 8; var close = script.IndexOf(';', open); mapname = script.Substring(open, close - open); mapname = mapname.Trim(new char[3]{' ','=','\t'}); } suppressEvent_SelectedIndexChanged = true; map_comboBox.SelectedItem = mapname; suppressEvent_SelectedIndexChanged = false; int selectedView = normalRadioButton.Checked ? 0 : (elevationRadioButton.Checked ? 1 : 2); Set_MapImages(mapname, selectedView); //get customized modoptions { var open = script.IndexOf("[MODOPTIONS]", 7, script.Length - 8, StringComparison.InvariantCultureIgnoreCase) + 12; open = script.IndexOf("{", open) + 1; var close = script.IndexOf("}", open); var options = script.Substring(open, close - open); options = options.Trim(); string[] optionList = options.Split(new char[1]{';'}, StringSplitOptions.RemoveEmptyEntries); string[] keypair; for (int i = 0; i < optionList.Length; i++) { optionList[i] = optionList[i].Trim(); keypair = optionList[i].Split(new char[1] { '=' }); if (keypair[1] != null) ModOptions.Add(keypair[0], keypair[1]); } } } else { spectateCheckBox.Enabled = true; addAIButton.Enabled = true; editTeamButton.Enabled = true; } Refresh_PlayerBox();//update playerbox (in case there's mission slot, or when there was mission slot but no longer, or to update some related icons) }
public static void ScriptAddTeam(StringBuilder script, int teamNum, List<StartPos> positions, int userNum, UserBattleStatus status, Mod mod, BattleDetails Details) { // BOT TEAM script.AppendFormat(" [TEAM{0}]\n", teamNum); script.AppendLine(" {"); script.AppendFormat(" TeamLeader={0};\n", userNum); script.AppendFormat(" AllyTeam={0};\n", status.AllyNumber); script.AppendFormat(CultureInfo.InvariantCulture," RGBColor={0:F5} {1:F5} {2:F5};\n", (status.TeamColor & 255)/255.0, ((status.TeamColor >> 8) & 255)/255.0, ((status.TeamColor >> 16) & 255)/255.0); var side = "mission"; if (mod.Sides.Length > status.Side) side = mod.Sides[status.Side]; script.AppendFormat(" Side={0};\n", side); script.AppendFormat(" Handicap={0};\n", 0); if (mod.IsMission) { script.AppendFormat(" StartPosX={0};\n", 0); script.AppendFormat(" StartPosZ={0};\n", 0); } else { if ((Details.StartPos == BattleStartPos.Random || Details.StartPos == BattleStartPos.Fixed) && positions.Count > teamNum) { var pos = positions[teamNum]; script.AppendFormat(" StartPosX={0};\n", pos.x); script.AppendFormat(" StartPosZ={0};\n", pos.z); } } script.AppendLine(" }"); }
/// <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 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> /// Read mod luaAI from LuaAI.lua /// </summary> public static void ReadLuaAI(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); List<Ai> modAis = new List<Ai>(); foreach (var kvp in table) { String name = ""; String desc = ""; 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 "desc": desc = value; break; } } if (name!="" && desc!="") { var bot = new Ai() { Info = new AiInfoPair[2] { new AiInfoPair { Key = "shortName", Value = name } , //usually equivalent to AI folder name (aiName[i]) new AiInfoPair { Key = "description", Value = desc } , } }; modAis.Add(bot); } } modInfo.ModAis = modAis.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> /// 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); } }
public static Mod GetOneSddMod(Mod mod) { if (mod.Options!=null || mod.ModAis!=null || mod.MissionScript!=null ||mod.Sides!=null) return mod; var modFolder = Utils.MakePath(Program.SpringPaths.DataDirectories.First(), "games"); var path = Utils.MakePath(modFolder, mod.ArchiveName ); String engineOptions = null; String modOptions = null; String luaAI = null; String missionScriptPath = null; String missionSlotPath = null; var rootFiles = Directory.EnumerateFiles(path); foreach(var pathOfFile in rootFiles) { var fileName = GetFolderOrFileName(pathOfFile); if(fileName.StartsWith("EngineOptions.lua",StringComparison.InvariantCultureIgnoreCase)) engineOptions = pathOfFile; else if(fileName.StartsWith("ModOptions.lua",StringComparison.InvariantCultureIgnoreCase)) modOptions = pathOfFile; else if(fileName.StartsWith("LuaAI.lua",StringComparison.InvariantCultureIgnoreCase)) luaAI = pathOfFile; else if(fileName.StartsWith("script.txt",StringComparison.InvariantCultureIgnoreCase)) missionScriptPath = pathOfFile; else if(fileName.StartsWith("slots.lua",StringComparison.InvariantCultureIgnoreCase)) missionSlotPath = pathOfFile; } if (modOptions!=null) CrudeLUAReader.ReadOptionsTable(modOptions, ref mod); if (engineOptions!=null) CrudeLUAReader.ReadOptionsTable(engineOptions, ref mod); if (luaAI!=null) CrudeLUAReader.ReadLuaAI(luaAI,ref mod); if (missionSlotPath!=null) CrudeLUAReader.ReadMissionSlot(missionSlotPath,ref mod); if (missionScriptPath!=null) { try{ using (FileStream fileStream = File.OpenRead(missionScriptPath)) using (var stream = new StreamReader(fileStream)) { mod.MissionScript = stream.ReadToEnd(); var open = mod.MissionScript.IndexOf("mapname", 7, mod.MissionScript.Length - 8, StringComparison.InvariantCultureIgnoreCase) + 8; var close = mod.MissionScript.IndexOf(';', open); var mapname = mod.MissionScript.Substring(open, close - open); mod.MissionMap = mapname.Trim(new char[3]{' ','=','\t'}); } }catch(Exception e) {} } var sideData = Utils.MakePath(path,"gamedata","sidedata.lua"); var picPath = Utils.MakePath(path,"sidepics"); CrudeLUAReader.ReadSideInfo(sideData,picPath,ref mod); return mod; }
public void HandleMod(Mod mod) { if (mod != null) { Ais = mod.ModAis; ModLoaded(this, new EventArgs<Mod>(mod)); lock (locker) { if (Program.TasClient.MyBattle.ModName == mod.Name) { this.mod = mod; ChangedOptions = GetModOptionSummary(mod, Program.TasClient.MyBattle.ModOptions, false); } else return; } } }
public Battle(string engineVersion, string password, int port, int maxplayers, int rank, Map map, string title, Mod mod, BattleDetails details): this() { if (!String.IsNullOrEmpty(password)) Password = password; if (port == 0) HostPort = 8452; else HostPort = port; try { var ports = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners().OrderBy(x => x.Port).Select(x=>x.Port).ToList(); if (ports.Contains(HostPort)) { var blockedPort = HostPort; while (ports.Contains(HostPort)) HostPort++; Trace.TraceWarning("Host port {0} was used, using backup port {1}", blockedPort, HostPort); } } catch {} EngineVersion = engineVersion; MaxPlayers = maxplayers; Rank = rank; this.map = map; MapName = map.Name; MapHash = 0; Title = title; this.mod = mod; ModName = mod.Name; ModHash = 0; if (details != null) Details = details; }
public void HandleMod(Mod mod) { this.mod = mod; SuspendLayout(); try { options = mod.Options.ToDictionary(option => option.Key); var sections = mod.Options.GroupBy(option => option.Section).OrderBy(group => group.Key).ToArray(); var sectionNames = mod.Options.Where(option => option.Type == OptionType.Section).ToDictionary(option => option.Key, option => option.Name); optionControls = new Dictionary<string, Control>(); const int rowHeight = 30; foreach (var section in sections) { if (!section.Any()) continue; // set the section title string sectionName; if (String.IsNullOrEmpty(section.Key)) sectionName = "Other"; else if (!sectionNames.TryGetValue(section.Key, out sectionName)) sectionName = section.Key.ToLower(); var tabPage = new TabPage { Text = sectionName, Name = sectionName, AutoScroll = true }; tabControl.TabPages.Add(tabPage); var sectionY = 20; foreach (var option in section) { Control control = null; switch (option.Type) { case OptionType.Bool: control = new CheckBox { Checked = option.Default != "0" }; ((CheckBox)control).CheckedChanged += proposedChanged; break; case OptionType.Number: control = new NumericUpDown { Minimum = (decimal)option.Min, Maximum = (decimal)option.Max, Increment = (decimal)option.Step, Value = decimal.Parse(option.Default, CultureInfo.InvariantCulture), DecimalPlaces = (int)(-Math.Floor(Math.Min(0, Math.Log10(option.Step)))), }; ((NumericUpDown)control).ValueChanged += proposedChanged; break; case OptionType.String: control = new TextBox { Text = option.Default }; control.TextChanged += proposedChanged; break; case OptionType.List: var optionIndex = option.ListOptions.IndexOf(option.ListOptions.Single(o => o.Key == option.Default)); var box = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList }; box.Items.AddRange(option.ListOptions.Select(o => o.Name).ToArray()); if (optionIndex > -1) box.SelectedIndex = optionIndex; control = box; box.SelectedIndexChanged += proposedChanged; break; } if (control != null) { var tooltipText = string.Format("{0}\nDefault: {1} = {2}", option.Description, option.Key, option.Default); tooltip.SetToolTip(control, tooltipText); var label = new Label { Text = option.Name, Location = new Point(3, sectionY), Width = 145 }; tooltip.SetToolTip(label, tooltipText); tabPage.Controls.Add(label); control.Location = new Point(150, sectionY); optionControls[option.Key] = control; tabPage.Controls.Add(control); sectionY += rowHeight; } } } } catch (Exception e) { Trace.TraceError("Error in creating mod options controls: " + e); } ResumeLayout(); if (offlineMode) { SetModOptions(); return; } SetModOptions(Program.TasClient.MyBattle.ModOptions); }
private void CallBack_Mod(Mod mod) { if (mod != null) { //Initialize "side" (faction) dropdown list. copied from Notification.BattleBar.cs { sideCB.Visible = mod.Sides.Length > 1; if (sideCB.Visible) { var previousSide = sideCB.SelectedItem != null ? sideCB.SelectedItem.ToString() : null; sideCB.Items.Clear(); var cnt = 0; foreach (var side in mod.Sides) sideCB.Items.Add(new ZeroKLobby.Notifications.SideItem(side, mod.SideIcons[cnt++])); var pickedItem = sideCB.Items.OfType<ZeroKLobby.Notifications.SideItem>() .FirstOrDefault(x => x.Side == previousSide); if (pickedItem != null) sideCB.SelectedItem = pickedItem; else if (sideCB.Items.Count > 0) sideCB.SelectedIndex = sideCB.Items.Count-1; // random.Next(sideCB.Items.Count); } } //end "side" (faction) dropdown list ModOptions.Clear(); currentMod = mod; aiList = mod.ModAis; missionSlots = mod.MissionSlots; Setup_MissionModInfo(mod); Set_InfoLabel(); } else { sideCB.Visible = false; currentMod = null; aiList = null; missionSlots = null; myItem.MissionSlot = null; botsMissionSlot.Clear(); if (currentMod != null) Refresh_PlayerBox(); } }
private static void RecordMissionResult(Spring spring, Mod modInfo) { if (spring.Context.GameEndedOk && !spring.Context.IsCheating) { Trace.TraceInformation("Submitting score for mission " + modInfo.Name); try { var service = GlobalConst.GetContentService(); Task.Factory.StartNew(() => { try { service.SubmitMissionScore(Program.Conf.LobbyPlayerName, ZkData.Utils.HashLobbyPassword(Program.Conf.LobbyPlayerPassword), modInfo.Name, spring.Context.MissionScore ?? 0, spring.Context.MissionFrame/30, spring.Context.MissionVars); } catch (Exception ex) { Trace.TraceError("Error sending score: {0}", ex); } }); } catch (Exception ex) { Trace.TraceError($"Error sending mission score: {ex}"); } } }
public void UpdateMission(ZkDataContext db, Mission mission, Mod modInfo) { var file = mission.Mutator.ToArray(); var tempName = Path.GetTempFileName() + ".zip"; File.WriteAllBytes(tempName, file); using (var zf = new ZipFile(tempName)) { zf.UpdateEntry("modinfo.lua", Encoding.UTF8.GetBytes(GetModInfo(mission.NameWithVersion, mission.Mod, mission.Name, "ZK"))); // FIXME hardcoded crap FixScript(mission, zf, "script.txt"); var script = FixScript(mission, zf, GlobalConst.MissionScriptFileName); modInfo.MissionScript = script; //modInfo.ShortName = mission.Name; modInfo.Name = mission.NameWithVersion; zf.Save(); } mission.Mutator = File.ReadAllBytes(tempName); mission.Script = Regex.Replace(mission.Script, "GameType=([^;]+);", (m) => { return string.Format("GameType={0};", mission.NameWithVersion); }); File.Delete(tempName); var resource = db.Resources.FirstOrDefault(x => x.MissionID == mission.MissionID); if (resource == null) { resource = new Resource() { DownloadCount = 0, TypeID = ZkData.ResourceType.Mod }; db.Resources.Add(resource); } resource.InternalName = mission.NameWithVersion; resource.MissionID = mission.MissionID; resource.ResourceDependencies.Clear(); resource.ResourceDependencies.Add(new ResourceDependency() { NeedsInternalName = mission.Map }); resource.ResourceDependencies.Add(new ResourceDependency() { NeedsInternalName = mission.Mod }); resource.ResourceContentFiles.Clear(); // generate torrent var tempFile = Path.Combine(Path.GetTempPath(), mission.SanitizedFileName); File.WriteAllBytes(tempFile, mission.Mutator.ToArray()); var creator = new TorrentCreator(); creator.Path = tempFile; var torrentStream = new MemoryStream(); creator.Create(torrentStream); try { File.Delete(tempFile); } catch { } var md5 = Hash.HashBytes(mission.Mutator.ToArray()).ToString(); resource.ResourceContentFiles.Add(new ResourceContentFile() { FileName = mission.SanitizedFileName, Length = mission.Mutator.Length, LinkCount = 1, Links = string.Format(MissionFileUrl, mission.MissionID), Md5 = md5 }); var basePath = GlobalConst.SiteDiskPath + @"\resources\"; File.WriteAllBytes(string.Format(@"{2}\{0}_{1}.torrent", resource.InternalName.EscapePath(), md5, basePath), torrentStream.ToArray()); File.WriteAllBytes(string.Format(@"{1}\{0}.metadata.xml.gz", resource.InternalName.EscapePath(), basePath), MetaDataCache.SerializeAndCompressMetaData(modInfo)); File.WriteAllBytes(string.Format(GlobalConst.SiteDiskPath + @"\img\missions\{0}.png", mission.MissionID, basePath), mission.Image.ToArray()); }
public void OpenBattleRoom(string modname, string mapname, bool now = true) { if (!now && spring.IsRunning) spring.WaitForExit(); Stop(); bossName = ""; lastMapChange = DateTime.Now; if (String.IsNullOrEmpty(modname)) modname = config.Mod; if (String.IsNullOrEmpty(mapname)) mapname = config.Map; string title = config.Title.Replace("%1", MainConfig.SpringieVersion); string password = null; if (!string.IsNullOrEmpty(config.BattlePassword)) password = config.BattlePassword; int maxPlayers = config.MaxPlayers; string engine = springPaths.SpringVersion; if (SpawnConfig != null) { modname = SpawnConfig.Mod; if (SpawnConfig.MaxPlayers > 0) maxPlayers = SpawnConfig.MaxPlayers; if (!String.IsNullOrEmpty(SpawnConfig.Map)) mapname = SpawnConfig.Map; title = SpawnConfig.Title; if (!String.IsNullOrEmpty(SpawnConfig.Password)) password = SpawnConfig.Password; if (!String.IsNullOrEmpty(SpawnConfig.Engine)) engine = SpawnConfig.Engine; { //Something needs to go here to properly tell Springie to use a specific engine version, //attempted code below may or may not be responsible for recent springie drops, so commenting. //the below may be causing a rehost //requestedEngineChange = SpawnConfig.Engine; //alternate attempt /* Program.main.Downloader.GetAndSwitchEngine(SpawnConfig.Engine); config.SpringVersion = SpawnConfig.Engine; springPaths.SetEnginePath(Program.main.paths.GetEngineFolderByVersion(SpawnConfig.Engine)); */ } } //title = title + string.Format(" [engine{0}]", springPaths.SpringVersion); // no mod was provided, auto update is on, check if newer version exists, if it does use that instead of config one if (string.IsNullOrEmpty(modname) && !String.IsNullOrEmpty(config.AutoUpdateRapidTag)) { var ver = Program.main.Downloader.PackageDownloader.GetByTag(config.AutoUpdateRapidTag); if (ver != null && cache.GetResourceDataByInternalName(ver.InternalName) != null) modname = config.AutoUpdateRapidTag; } PackageDownloader.Version version = Program.main.Downloader.PackageDownloader.GetByTag(modname); if (version != null && version.InternalName != null) modname = version.InternalName; hostedMod = new Mod() {Name = modname}; cache.GetMod(modname, (m) => { hostedMod = m; }, (m) => {}); if (hostedMod.IsMission && !String.IsNullOrEmpty(hostedMod.MissionMap)) mapname = hostedMod.MissionMap; //Map mapi = null; //cache.GetMap(mapname, (m, x, y, z) => { mapi = m; }, (e) => { }, springPaths.SpringVersion); //int mint, maxt; if (!springPaths.HasEngineVersion(engine)) { Program.main.Downloader.GetAndSwitchEngine(engine,springPaths); } else { springPaths.SetEnginePath(springPaths.GetEngineFolderByVersion(engine)); } var b = new Battle(engine, password, hostingPort, maxPlayers, mapname, title,modname); b.Ip = Program.main.Config.IpOverride; tas.OpenBattle(b); }
public void SendMission(Mission mission, List<MissionSlot> slots, string author, string password, Mod modInfo) { if (mission == null) throw new ApplicationException("Mission is null"); Account acc = null; var db = new ZkDataContext(); if (Debugger.IsAttached) acc = db.Accounts.SingleOrDefault(x => x.Name == "Testor303"); else acc = AuthServiceClient.VerifyAccountPlain(author, password); if (acc == null) { Trace.TraceWarning("Invalid login attempt for {0}", author); System.Threading.Thread.Sleep(new Random().Next(2000)); throw new ApplicationException("Cannot verify user account"); } Mission prev = db.Missions.SingleOrDefault(x => x.MissionID == mission.MissionID || (x.Name == mission.Name && x.AccountID == acc.AccountID)); // previous mission by id or name + account if (prev == null && db.Missions.Any(x =>x.Name == mission.Name)) throw new ApplicationException("Mission name must be unique"); var map = db.Resources.SingleOrDefault(x => x.InternalName == mission.Map && x.TypeID == ZkData.ResourceType.Map); if (map == null) throw new ApplicationException("Map name is unknown"); var mod = db.Resources.SingleOrDefault(x => x.InternalName == mission.Mod && x.TypeID == ZkData.ResourceType.Mod); if (mod == null) throw new ApplicationException("Mod name is unknown"); //if (db.Resources.Any(x => x.InternalName == mission.Name && x.MissionID != null)) throw new ApplicationException("Name already taken by other mod/map"); modInfo.MissionMap = mission.Map; if (prev != null) { if (prev.AccountID != acc.AccountID && !acc.IsZeroKAdmin) throw new ApplicationException("Invalid author or password"); prev.Description = mission.Description; prev.DescriptionStory = mission.DescriptionStory; prev.Mod = mission.Mod; prev.Map = mission.Map; prev.Name = mission.Name; prev.ScoringMethod = mission.ScoringMethod; prev.ModRapidTag = mission.ModRapidTag; prev.ModOptions = mission.ModOptions; prev.Image = mission.Image; prev.MissionEditorVersion = mission.MissionEditorVersion; prev.SpringVersion = mission.SpringVersion; prev.Revision++; prev.Mutator = mission.Mutator; prev.ForumThread.Title = mission.Name; mission = prev; } else { mission.CreatedTime = DateTime.UtcNow; mission.ForumThread = new ForumThread() { Title = mission.Name, ForumCategory = db.ForumCategories.FirstOrDefault(x=>x.ForumMode==ForumMode.Missions), CreatedAccountID = acc.AccountID, LastPostAccountID= acc.AccountID }; mission.ForumThread.UpdateLastRead(acc.AccountID, true); db.Missions.InsertOnSubmit(mission); } mission.AccountID = acc.AccountID; mission.Script = Regex.Replace(mission.Script, "GameType=([^;]+);", (m) => { return string.Format("GameType={0};", mission.NameWithVersion); }); mission.MinHumans = slots.Count(x => x.IsHuman && x.IsRequired); mission.MaxHumans = slots.Count(x => x.IsHuman); mission.ModifiedTime = DateTime.UtcNow; mission.IsDeleted = true; mission.IsCoop = slots.Where(x => x.IsHuman).GroupBy(x => x.AllyID).Count() == 1; db.SaveChanges(); var updater = new MissionUpdater(); updater.UpdateMission(db, mission, modInfo); mission.IsDeleted = false; db.SaveChanges(); }
public Mod GetMod(string modName) { if (disposed) { throw new ObjectDisposedException("Unitsync has already been released."); } if (modName == null) { throw new ArgumentNullException("modName"); } NativeMethods.RemoveAllArchives(); NativeMethods.GetPrimaryModCount(); // pre-requisite for the following calls var archiveName = GetModArchiveName(modName); NativeMethods.AddAllArchives(archiveName); int modIndex = NativeMethods.GetPrimaryModIndex(modName); string[] sides; var mod = new Mod { Name = modName, ArchiveName = archiveName, UnitDefs = GetUnitList(modName).Select(ui => new UnitInfo(ui.Name, ui.FullName)).ToArray(), Description = NativeMethods.GetPrimaryModDescription(modIndex), Game = NativeMethods.GetPrimaryModGame(modIndex), Mutator = NativeMethods.GetPrimaryModMutator(modIndex), ShortGame = NativeMethods.GetPrimaryModShortGame(modIndex), ShortName = NativeMethods.GetPrimaryModShortName(modIndex), PrimaryModVersion = NativeMethods.GetPrimaryModVersion(modIndex), StartUnits = new SerializableDictionary <string, string>(GetStartUnits(modName, out sides)), Sides = sides, Options = GetModOptions(archiveName).ToArray(), SideIcons = GetSideIcons(sides).ToArray(), Dependencies = GetModDependencies(modIndex).Where(x => x != modName && !string.IsNullOrEmpty(x)).ToArray(), ModAis = GetAis().Where(ai => ai.IsLuaAi).ToArray() }; System.Diagnostics.Trace.TraceInformation("Mod Information: Description {0}, Game {1}, Mutator {2}, ShortGame {3}, PrimaryModVersion {4}", mod.Description, mod.Game, mod.Mutator, mod.ShortGame, mod.PrimaryModVersion); var buf = ReadVfsFile(GlobalConst.MissionScriptFileName); if (buf != null && buf.Length > 0) { mod.MissionScript = Encoding.UTF8.GetString(buf, 0, buf.Length); } if (!string.IsNullOrEmpty(mod.MissionScript)) { try { buf = ReadVfsFile(GlobalConst.MissionSlotsFileName); var slotString = Encoding.UTF8.GetString(buf, 0, buf.Length); var ser = new XmlSerializer(typeof(List <MissionSlot>)); mod.MissionSlots = (List <MissionSlot>)ser.Deserialize(new StringReader(slotString)); } catch (Exception ex) { Trace.TraceError("Error reading mission slots from mod {0}: {1}", mod.Name, ex); } } if (mod.Sides.Length == 0) { Trace.WriteLine("Mod has no faction"); } if (mod.UnitDefs.Length == 0) { Trace.WriteLine("No unit found."); } NativeMethods.RemoveAllArchives(); TraceErrors(); return(mod); }