public void cargarGrillaEstudiantes() { //Creamos un documento y lo cargamos con los datos del XML. XmlDocument documento = new XmlDocument(); documento.Load(ruta); //Obtenemos una colección con todos los estudiantes. XmlNodeList listaEstudiantes = documento.SelectNodes("estudiantes/estudiante"); //Creamos un único curso. XmlNode Est; //Limpiamos datagridview dgv.Rows.Clear(); //Recorremos toda la lista de estudiantes. for (int i = 0; i < listaEstudiantes.Count; i++) { //Obtenemos cada curso. Est = listaEstudiantes.Item(i); //Obtenemos valores para cada fila string cod = Est.SelectSingleNode("codEstudiante").InnerText; string nom = Est.SelectSingleNode("nombre").InnerText; string ape = Est.SelectSingleNode("apellidos").InnerText; //Insertamos nueva fila en datagridview dgv.Rows.Add(cod, nom, ape, "Eliminar"); dgv.Update(); } }
public void ObtenerEstudiante(string idEstudiante) { //Creamos un documento y lo cargamos con los datos del XML. XmlDocument documento = new XmlDocument(); documento.Load(ruta); //Obtenemos una colección con todos los estudiantes. XmlNodeList listaEstudiantes = documento.SelectNodes("estudiantes/estudiante"); //Creamos un único estudiante. XmlNode Est; //Recorremos toda la lista de estudiantes. for (int i = 0; i < listaEstudiantes.Count; i++) { //Obtenemos cada estudiante. Est = listaEstudiantes.Item(i); //Seleccionamos el id del estudiante. string codEstudiante = Est.SelectSingleNode("codEstudiante").InnerText; //Comprobamos que el id del estudiante sea el mismo que el número introducido por el usuario. if (codEstudiante == idEstudiante) { //Ponemos campo id como solo lectura txt_Code.ReadOnly = true; //Seteamos campos dentro del formulario con informacion del archivo txt_Names.Text = Est.SelectSingleNode("nombre").InnerText; txt_LastNames.Text = Est.SelectSingleNode("apellidos").InnerText; } } }
private static async Task <Dictionary <XivRace, ExtraSkeletonEntry> > DeserializeEstData(byte[] data, XivDependencyRoot root, uint dataVersion) { if (dataVersion == 1) { // Version 1 didn't include EST data, so just get the defaults. return(await Est.GetExtraSkeletonEntries(root)); } // 6 Bytes per entry. var count = data.Length / 6; var ret = new Dictionary <XivRace, ExtraSkeletonEntry>(count); for (int i = 0; i < count; i++) { var offset = i * 6; var raceCode = BitConverter.ToUInt16(data, offset); var setId = BitConverter.ToUInt16(data, offset + 2); var skelId = BitConverter.ToUInt16(data, offset + 4); var race = XivRaces.GetXivRace(raceCode); ret.Add(race, new ExtraSkeletonEntry(race, setId, skelId)); } return(ret); }
/// <summary> /// Creates a new ItemMetaData entry from the constituent files around the FFXIV file system. /// </summary> /// <param name="root"></param> /// <returns></returns> private static async Task <ItemMetadata> CreateFromRaw(XivDependencyRoot root, bool forceDefault = false) { var _eqp = new Eqp(XivCache.GameInfo.GameDirectory); var _imc = new Imc(XivCache.GameInfo.GameDirectory); // These functions generate the path::offset to each of our // contiguous metadata entries. var imcPaths = await root.GetImcEntryPaths(); var ret = new ItemMetadata(root); if (imcPaths.Count > 0) { ret.ImcEntries = await _imc.GetEntries(imcPaths, forceDefault); } ret.EqpEntry = await _eqp.GetEqpEntry(root.Info, forceDefault); ret.EqdpEntries = await _eqp.GetEquipmentDeformationParameters(root.Info, forceDefault); ret.EstEntries = await Est.GetExtraSkeletonEntries(root, forceDefault); ret.GmpEntry = await _eqp.GetGimmickParameter(root, forceDefault); return(ret); }
public void UpdateRender(Est nuevoEstado) { estado = nuevoEstado; if (estado == Est.Exclamacion) { render.sprite = DialogueManager.instance.exclamacion; } else if (estado == Est.Interrogacion) { render.sprite = DialogueManager.instance.interrogacion; } else { render.sprite = null; } }
public void eliminarEstudiante(string idEstudiante) { //Creamos un documento y lo cargamos con los datos del XML. XmlDocument documento = new XmlDocument(); documento.Load(ruta); //Obtenemos el nodo raiz del documento. XmlElement estudiantes = documento.DocumentElement; //Obtenemos una colección con todos los estudiantes. XmlNodeList listaEstudiantes = documento.SelectNodes("estudiantes/estudiante"); //Creamos un único estudiante. XmlNode Est; //Recorremos toda la lista de estudiantes. for (int i = 0; i < listaEstudiantes.Count; i++) { //Obtenemos cada estudiante. Est = listaEstudiantes.Item(i); //Seleccionamos el id del curso. string codEstudiante = Est.SelectSingleNode("codEstudiante").InnerText; //Comprobamos que el id del estudiante sea el mismo que el número introducido por el usuario. if (codEstudiante == idEstudiante) { //Borrar un nodo. estudiantes.RemoveChild(Est); } } //Salvamos el documento. documento.Save(ruta); }
void sendTags(Est est) { try { System.IO.File.AppendAllText( est.enc.i.filename + ".txt", est.enc.i.timestamp() + " " + est.tag + "\r\n", Encoding.UTF8); } catch { } string meta = est.tag; //meta = new string(meta.Reverse().ToArray()); if (settings.latin) { meta = Uri.EscapeUriString(latin1.GetString(Encoding.UTF8.GetBytes(meta))).Replace("+", "%2B"); } else { //meta = Uri.EscapeUriString(est.tag).Replace("+", "%2B"); meta = Chencode.HonkHonk(meta); //meta = est.tag; } if (!socket_fallback && !settings.tagsock) { try { Logger.tag.a("wc_send: " + est.enc.ext + " " + est.tag); string url = string.Format( "http://{0}:{1}/admin/metadata?mode=updinfo&mount=/{2}.{3}&charset=UTF-8&song={4}", settings.host, settings.port, settings.mount, est.enc.ext, meta); Logger.tag.a("url: " + url); using (System.Net.WebClient wc = new System.Net.WebClient()) { //throw new ExecutionEngineException(); Logger.tag.a("made webclient"); wc.Headers.Add("Authorization: Basic " + auth); string msg = wc.DownloadString(url); Logger.tag.a(est.enc.ext + " socket ok: " + msg); if (!haveFailed && !msg.Contains("<return>1</return>")) { haveFailed = true; msg = msg.Contains("<message>") ? msg.Substring(msg.IndexOf("<message>") + 9) : msg; msg = msg.Contains("</message>") ? msg.Substring(0, msg.LastIndexOf("</message>")) : msg; System.Windows.Forms.MessageBox.Show("Metadata broadcast failure:\r\n\r\n" + msg, "Tags failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } } catch (Exception e) { socket_fallback = true; Logger.tag.a(est.enc.ext + " wc_send fail: " + e.Message); //tag = new LSTD(false, "Meta-fail " + est.enc.ext, "(unknown error)"); } } if (socket_fallback || settings.tagsock) { try { Logger.tag.a("sck_send: " + est.enc.ext + " " + est.tag); string header = string.Format( "GET /admin/metadata?mode=updinfo&mount=/{1}.{2}&charset=UTF-8&song={3} HTTP/1.1{0}" + "Authorization: Basic {4}{0}" + "Host: {5}:{6}{0}" + "Connection: Close{0}{0}", "\r\n", settings.mount, est.enc.ext, meta, auth, settings.host, settings.port); Logger.tag.a(header.Replace(auth, "BASE_64_AUTH")); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(header); var kc = new System.Net.Sockets.TcpClient(); kc.Connect(settings.host, settings.port); Logger.tag.a("sck_connected"); var ks = kc.GetStream(); ks.Write(buffer, 0, buffer.Length); ks.Flush(); Logger.tag.a("sck_sent"); buffer = new byte[8192]; /*var response = new List<byte>(); * byte[][] find1 = { * System.Text.Encoding.UTF8.GetBytes("\nContent-Length:"), * System.Text.Encoding.UTF8.GetBytes("\ncontent-length:"), * System.Text.Encoding.UTF8.GetBytes("\ncontent-Length:"), * System.Text.Encoding.UTF8.GetBytes("\nContent-length:"), * System.Text.Encoding.UTF8.GetBytes("\nCONTENT-LENGTH:") * }; * byte[] find2 = System.Text.Encoding.UTF8.GetBytes("\r\n\r\n"); * byte[] find3 = System.Text.Encoding.UTF8.GetBytes("\n\n"); * while (kc.Connected) * { * int i = ks.Read(buffer, 0, buffer.Length); * if (i <= 0) break; * for (int a = 0; a < i; a++) response.Add(buffer[a]); * string tmp = latin1.GetString(response.ToArray()); * if (tmp.Length == i) System.Windows.Forms.MessageBox.Show(tmp); * i = -1; * for (int n = 0; n < find1.Length; n++) * { * i = find(response, find1[n], 0); * if (i > 0) break; * } * if (i < 0) continue; * i += find1[0].Length; * * int nl = find(response, find2, i); * if (nl < 0) * nl = find(response, find3, i); * if (nl < 0) continue; * * while (response[i] == ' ') i++; * List<byte> asdf = new List<byte>(); * while ( * response[i] != '\r' && * response[i] != '\n') * asdf.Add(response[i]); * * int clen = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(asdf.ToArray())); * int red = response.Count - nl; * if (clen - red < 5) break; * } * string msg = System.Text.Encoding.UTF8.GetString(response.ToArray());*/ string msg = ""; while (kc.Connected) { int i = ks.Read(buffer, 0, buffer.Length); if (i <= 0) { break; } msg += latin1.GetString(buffer, 0, i); int clen = msg.IndexOf("\ncontent-length:", StringComparison.OrdinalIgnoreCase); if (clen < 0) { continue; } clen += 16; int nl = msg.IndexOf("\r\n\r\n", clen); if (nl <= 0) { nl = msg.IndexOf("\n\n", clen); } if (nl <= 0) { continue; } while (msg[clen] == ' ' && clen < nl) { clen++; } clen = Convert.ToInt32(msg.Substring(clen, msg.IndexOf("\n", clen) - clen).Trim('\r', '\n', ' ')); clen = (msg.Length - nl) - clen; if (clen < 8) { Logger.tag.a("got eof"); break; } } Logger.tag.a("sck_ok: " + msg); if (!haveFailed && !msg.Contains("<return>1</return>")) { haveFailed = true; msg = msg.Contains("<message>") ? msg.Substring(msg.IndexOf("<message>") + 9) : msg; msg = msg.Contains("</message>") ? msg.Substring(0, msg.LastIndexOf("</message>")) : msg; System.Windows.Forms.MessageBox.Show("Metadata broadcast failure:\r\n\r\n" + msg, "Tags failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } catch (Exception e) { Logger.tag.a(est.enc.ext + " sck_send fail: " + e.Message); tag = new LSTD(false, "Meta-fail " + est.enc.ext, "(unknown error)"); } } }
public Estado(string s) { statActual = new Stats(s); est = Est.normal; }
public Estado(Stats s, Est e) { statActual = s; est = e; }
void onReceive (int bytes) { print( Encoding.ASCII.GetString(bytesReceived, 0, bytes) ); for (i=0; i<bytes; i++) { c3 = c2; c2 = c1; c1 = c; c = (char) bytesReceived[i]; switch (est) { case Est.header: //------------------------------------------ if (c3==0x81 && c2==0x02 && c1=='g' && c=='o') { //< parei aki est = Est.go; sendChar(); } break; case Est.go: //---------------------------------------------- if (c=='"') { est = Est.texto; texto = ""; } else if ( char.IsDigit(c) ) { est = Est.numero; texto = ""+c; } else if ( char.IsLetter(c) ) { est = Est.palavra; texto = ""+c; } else if (c==']' || c=='[') closePilha(); break; case Est.numero: //------------------------------------------ if ( char.IsNumber(c) ) texto += c; else { est = Est.go; lista.Add( texto ); if (c==']' || c=='[') closePilha(); } break; case Est.palavra: //----------------------------------------- if ( char.IsLetterOrDigit(c) ) texto += c; else { est = Est.go; lista.Add( texto ); if (c==']' || c=='[') closePilha(); } break; case Est.texto: //------------------------------------------- if (c=='"') { est = Est.go; lista.Add( texto ); } else if (c=='\\') { est = Est.textoEscape; } else texto += c; break; case Est.textoEscape: //------------------------------------- texto += c; est = Est.texto; break; } } }
void sendTags(Est est) { try { System.IO.File.AppendAllText( est.enc.i.filename + ".txt", est.enc.i.timestamp() + " " + est.tag + "\r\n", Encoding.UTF8); } catch { } string meta = est.tag; //meta = new string(meta.Reverse().ToArray()); if (settings.latin) { meta = Uri.EscapeUriString(latin1.GetString(Encoding.UTF8.GetBytes(meta))).Replace("+", "%2B"); } else { //meta = Uri.EscapeUriString(est.tag).Replace("+", "%2B"); meta = Chencode.HonkHonk(meta); //meta = est.tag; } if (!socket_fallback && !settings.tagsock) { try { Logger.tag.a("wc_send: " + est.enc.ext + " " + est.tag); string url = string.Format( "http://{0}:{1}/admin/metadata?mode=updinfo&mount=/{2}.{3}&charset=UTF-8&song={4}", settings.host, settings.port, settings.mount, est.enc.ext, meta); Logger.tag.a("url: " + url); using (System.Net.WebClient wc = new System.Net.WebClient()) { //throw new ExecutionEngineException(); Logger.tag.a("made webclient"); wc.Headers.Add("Authorization: Basic " + auth); string msg = wc.DownloadString(url); Logger.tag.a(est.enc.ext + " socket ok: " + msg); if (!haveFailed && !msg.Contains("<return>1</return>")) { haveFailed = true; msg = msg.Contains("<message>") ? msg.Substring(msg.IndexOf("<message>") + 9) : msg; msg = msg.Contains("</message>") ? msg.Substring(0, msg.LastIndexOf("</message>")) : msg; System.Windows.Forms.MessageBox.Show("Metadata broadcast failure:\r\n\r\n" + msg, "Tags failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } } catch (Exception e) { socket_fallback = true; Logger.tag.a(est.enc.ext + " wc_send fail: " + e.Message); //tag = new LSTD(false, "Meta-fail " + est.enc.ext, "(unknown error)"); } } if (socket_fallback || settings.tagsock) { try { Logger.tag.a("sck_send: " + est.enc.ext + " " + est.tag); string header = string.Format( "GET /admin/metadata?mode=updinfo&mount=/{1}.{2}&charset=UTF-8&song={3} HTTP/1.1{0}" + "Authorization: Basic {4}{0}" + "Host: {5}:{6}{0}" + "Connection: Close{0}{0}", "\r\n", settings.mount, est.enc.ext, meta, auth, settings.host, settings.port); Logger.tag.a(header.Replace(auth, "BASE_64_AUTH")); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(header); var kc = new System.Net.Sockets.TcpClient(); kc.Connect(settings.host, settings.port); Logger.tag.a("sck_connected"); var ks = kc.GetStream(); ks.Write(buffer, 0, buffer.Length); ks.Flush(); Logger.tag.a("sck_sent"); buffer = new byte[8192]; /*var response = new List<byte>(); byte[][] find1 = { System.Text.Encoding.UTF8.GetBytes("\nContent-Length:"), System.Text.Encoding.UTF8.GetBytes("\ncontent-length:"), System.Text.Encoding.UTF8.GetBytes("\ncontent-Length:"), System.Text.Encoding.UTF8.GetBytes("\nContent-length:"), System.Text.Encoding.UTF8.GetBytes("\nCONTENT-LENGTH:") }; byte[] find2 = System.Text.Encoding.UTF8.GetBytes("\r\n\r\n"); byte[] find3 = System.Text.Encoding.UTF8.GetBytes("\n\n"); while (kc.Connected) { int i = ks.Read(buffer, 0, buffer.Length); if (i <= 0) break; for (int a = 0; a < i; a++) response.Add(buffer[a]); string tmp = latin1.GetString(response.ToArray()); if (tmp.Length == i) System.Windows.Forms.MessageBox.Show(tmp); i = -1; for (int n = 0; n < find1.Length; n++) { i = find(response, find1[n], 0); if (i > 0) break; } if (i < 0) continue; i += find1[0].Length; int nl = find(response, find2, i); if (nl < 0) nl = find(response, find3, i); if (nl < 0) continue; while (response[i] == ' ') i++; List<byte> asdf = new List<byte>(); while ( response[i] != '\r' && response[i] != '\n') asdf.Add(response[i]); int clen = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(asdf.ToArray())); int red = response.Count - nl; if (clen - red < 5) break; } string msg = System.Text.Encoding.UTF8.GetString(response.ToArray());*/ string msg = ""; while (kc.Connected) { int i = ks.Read(buffer, 0, buffer.Length); if (i <= 0) break; msg += latin1.GetString(buffer, 0, i); int clen = msg.IndexOf("\ncontent-length:", StringComparison.OrdinalIgnoreCase); if (clen < 0) continue; clen += 16; int nl = msg.IndexOf("\r\n\r\n", clen); if (nl <= 0) nl = msg.IndexOf("\n\n", clen); if (nl <= 0) continue; while (msg[clen] == ' ' && clen < nl) clen++; clen = Convert.ToInt32(msg.Substring(clen, msg.IndexOf("\n", clen) - clen).Trim('\r', '\n', ' ')); clen = (msg.Length - nl) - clen; if (clen < 8) { Logger.tag.a("got eof"); break; } } Logger.tag.a("sck_ok: " + msg); if (!haveFailed && !msg.Contains("<return>1</return>")) { haveFailed = true; msg = msg.Contains("<message>") ? msg.Substring(msg.IndexOf("<message>") + 9) : msg; msg = msg.Contains("</message>") ? msg.Substring(0, msg.LastIndexOf("</message>")) : msg; System.Windows.Forms.MessageBox.Show("Metadata broadcast failure:\r\n\r\n" + msg, "Tags failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } catch (Exception e) { Logger.tag.a(est.enc.ext + " sck_send fail: " + e.Message); tag = new LSTD(false, "Meta-fail " + est.enc.ext, "(unknown error)"); } } }
void Awake() { estado = Est.None; render = GetComponent <SpriteRenderer> (); UpdateRender(estado); }
/// <summary> /// Applies this Metadata object to the FFXIV file system. /// This should only called by Dat.WriteToDat() / RestoreDefaultMetadata() /// </summary> internal static async Task ApplyMetadata(ItemMetadata meta, IndexFile index = null, ModList modlist = null) { var _eqp = new Eqp(XivCache.GameInfo.GameDirectory); var _modding = new Modding(XivCache.GameInfo.GameDirectory); var _index = new Index(XivCache.GameInfo.GameDirectory); var df = IOUtil.GetDataFileFromPath(meta.Root.Info.GetRootFile()); var dummyItem = new XivGenericItemModel(); dummyItem.Name = Constants.InternalModSourceName; dummyItem.SecondaryCategory = Constants.InternalModSourceName; // Beep boop bool doSave = false; if (index == null) { doSave = true; index = await _index.GetIndexFile(df); modlist = await _modding.GetModListAsync(); } if (meta.ImcEntries.Count > 0) { var _imc = new Imc(XivCache.GameInfo.GameDirectory); var imcPath = meta.Root.GetRawImcFilePath(); await _imc.SaveEntries(imcPath, meta.Root.Info.Slot, meta.ImcEntries, dummyItem, index, modlist); } // Applying EQP data via set 0 is not allowed, as it is a special set hard-coded to use Set 1's data. if (meta.EqpEntry != null && !(meta.Root.Info.PrimaryType == Items.Enums.XivItemType.equipment && meta.Root.Info.PrimaryId == 0)) { await _eqp.SaveEqpEntry(meta.Root.Info.PrimaryId, meta.EqpEntry, dummyItem, index, modlist); } if (meta.EqdpEntries.Count > 0) { await _eqp.SaveEqdpEntries((uint)meta.Root.Info.PrimaryId, meta.Root.Info.Slot, meta.EqdpEntries, dummyItem, index, modlist); } if (meta.EstEntries.Count > 0) { var type = Est.GetEstType(meta.Root); var entries = meta.EstEntries.Values.ToList(); await Est.SaveExtraSkeletonEntries(type, entries, dummyItem, index, modlist); } if (meta.GmpEntry != null) { await _eqp.SaveGimmickParameter(meta.Root.Info.PrimaryId, meta.GmpEntry, dummyItem, index, modlist); } if (doSave) { await _index.SaveIndexFile(index); await _modding.SaveModListAsync(modlist); } }
/// <summary> /// Applies multiple metadata mods simultaneously for performance gains. /// </summary> /// <param name="data"></param> /// <param name="index"></param> /// <param name="modlist"></param> /// <returns></returns> internal static async Task ApplyMetadataBatched(List <ItemMetadata> data, IndexFile index, ModList modlist, bool save = true) { if (data == null || data.Count == 0) { return; } var _eqp = new Eqp(XivCache.GameInfo.GameDirectory); var _modding = new Modding(XivCache.GameInfo.GameDirectory); var _index = new Index(XivCache.GameInfo.GameDirectory); var dummyItem = new XivGenericItemModel(); dummyItem.Name = Constants.InternalModSourceName; dummyItem.SecondaryCategory = Constants.InternalModSourceName; Dictionary <XivRace, List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)> > eqdpEntries = new Dictionary <XivRace, List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)> >(); Dictionary <Est.EstType, List <ExtraSkeletonEntry> > estEntries = new Dictionary <Est.EstType, List <ExtraSkeletonEntry> >(); List <(uint PrimaryId, EquipmentParameter EqpData)> eqpEntries = new List <(uint PrimaryId, EquipmentParameter EqpData)>(); List <(uint PrimaryId, GimmickParameter GmpData)> gmpEntries = new List <(uint PrimaryId, GimmickParameter GmpData)>(); foreach (var meta in data) { // Construct the parameter collections for each function call. foreach (var kv in meta.EqdpEntries) { if (!eqdpEntries.ContainsKey(kv.Key)) { eqdpEntries.Add(kv.Key, new List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)>()); } eqdpEntries[kv.Key].Add(((uint)meta.Root.Info.PrimaryId, meta.Root.Info.Slot, kv.Value)); } var estType = Est.GetEstType(meta.Root); foreach (var kv in meta.EstEntries) { if (!estEntries.ContainsKey(estType)) { estEntries.Add(estType, new List <ExtraSkeletonEntry>()); } estEntries[estType].Add(kv.Value); } if (meta.EqpEntry != null) { eqpEntries.Add(((uint)meta.Root.Info.PrimaryId, meta.EqpEntry)); } if (meta.GmpEntry != null) { gmpEntries.Add(((uint)meta.Root.Info.PrimaryId, meta.GmpEntry)); } } if (index.DataFile == XivDataFile._04_Chara) { // Batch install functions for these three. await _eqp.SaveEqpEntries(eqpEntries, dummyItem, index, modlist); await _eqp.SaveEqdpEntries(eqdpEntries, dummyItem, index, modlist); await _eqp.SaveGmpEntries(gmpEntries, dummyItem, index, modlist); // The EST function already does batch applications by nature of how it works, // so just call it once for each of the four EST types represented. foreach (var kv in estEntries) { await Est.SaveExtraSkeletonEntries(kv.Key, kv.Value, dummyItem, index, modlist); } } // IMC Files don't really overlap that often, so it's // not a significant loss generally to just write them individually. foreach (var meta in data) { if (meta.ImcEntries.Count > 0) { var _imc = new Imc(XivCache.GameInfo.GameDirectory); var imcPath = meta.Root.GetRawImcFilePath(); await _imc.SaveEntries(imcPath, meta.Root.Info.Slot, meta.ImcEntries, null, index, modlist); } } if (save) { await _index.SaveIndexFile(index); await _modding.SaveModListAsync(modlist); } }