public bool patchSCX(Dictionary <string, MPKEntry> mpk, string charset, Dictionary <string, dynamic> scx) { Log("[SCX] 正在应用 SCX 补丁..."); foreach (KeyValuePair <string, dynamic> kv in scx) { if (!mpk.ContainsKey(kv.Key)) { Oops("[SCX] 无法找到文件 " + kv.Key); return(false); } Log("[SCX] 正在对 " + kv.Key + " 应用补丁..."); using (var ms = new MemoryStream()) using (var reader = new SCXReader(mpk[kv.Key].Data, charset)) using (var writer = new SCXWriter(ms, charset)) { var sb = new StringBuilder(); if (!SCX.ApplyPatch(kv.Value, reader, writer, sb)) { Log(sb.ToString()); Oops("[SCX] 补丁应用失败"); return(false); } mpk[kv.Key].SetData(ms.ToArray()); } } return(true); }
private void button_scx_apply_Click(object sender, EventArgs e) { try { var patch = JSON.ToObject <Dictionary <string, dynamic> >(File.ReadAllText(textBox_scx_patch.Text)); if (!patch.ContainsKey("data") || !(patch["data"] is Dictionary <string, dynamic> scx)) { throw new Exception("Bad patch file: Key scx not found or not dictionary"); } var sb = new StringBuilder(); string charset = patch["charset_preset"] + patch["charset"]; foreach (KeyValuePair <string, object> kv in scx) { string target = Path.Combine(textBox_scx_target.Text, kv.Key); if (!File.Exists(target + ".bak")) { continue; } sb.AppendLine("---------- " + kv.Key + " ----------"); using (var reader = new SCXReader(File.OpenRead(target + ".bak"), charset)) using (var writer = new SCXWriter(File.Open(target, FileMode.Create), charset)) { if (!SCX.ApplyPatch((IList <object>)kv.Value, reader, writer, sb)) { break; } } } sb.Append("\n"); textBox_log.Clear(); textBox_log.AppendText(sb.ToString()); File.WriteAllText("R:/patch.log", sb.ToString()); } catch (Exception ex) { Oops(ex); } }
public TextToken(SCXReader reader) : base(TokenType.TextMask) { var sb = new StringBuilder(); while (true) { byte next = reader.ReadByte(); if (next == (byte)TokenType.LineBreak) { sb.Append("\n"); continue; } else if (next == (byte)TokenType.Terminator || (next & (byte)TokenType.TextMask) == 0) { reader.BaseStream.Position--; break; } sb.Append(reader.ReadChar(next)); } Value = sb.ToString(); }
public ExpressionToken(TokenType type, SCXReader reader) : base(type) { var sb = new StringBuilder(); while (true) { sbyte next = reader.ReadSByte(); if (next == 0) { break; } Value.Add((byte)next); Value.Add(reader.ReadByte()); if (next > 0) { continue; } switch (next & 0x60) { case 0: break; case 0b0100000: Value.Add(reader.ReadByte()); break; case 0b1000000: Value.Add(reader.ReadByte()); Value.Add(reader.ReadByte()); break; case 0b1100000: Value.Add(reader.ReadByte()); Value.Add(reader.ReadByte()); Value.Add(reader.ReadByte()); Value.Add(reader.ReadByte()); break; } } }
private void button_scx_export_Click(object sender, EventArgs e) { try { var files = new List <string>(); if (Directory.Exists(textBox_scx_export.Text)) { files.AddRange(Directory.GetFiles(textBox_scx_export.Text) .Where(f => f.EndsWith(".scx", StringComparison.CurrentCultureIgnoreCase))); } else { files.Add(textBox_scx_export.Text); } var charset = File.ReadAllText(textBox_scx_charset.Text); var patch = new Dictionary <string, List <List <string> > >(); foreach (var file in files) { Log("[SCX Export] Exporting " + Path.GetFileName(file) + " ..."); using (var reader = new SCXReader(File.OpenRead(file), charset)) { var result = new List <List <string> >(); try { for (int i = 0; !reader.EOF; i++) { var xd = reader.ReadString(i); var row = new List <string>(); foreach (var t in xd.Tokens) { if (t is TextToken text) { row.Add(text.Value); } } if (row.Count > 0) { result.Add(row); } } } catch (Exception ex) { Log(ex.Message); } patch.Add(Path.GetFileName(file), result); } } var save = new SaveFileDialog { Filter = "JSON|*.json", DefaultExt = "log", CheckPathExists = true }; if (save.ShowDialog() == DialogResult.OK) { using (var writer = new StreamWriter(save.OpenFile())) { writer.Write(JSON.ToNiceJSON(patch, new JSONParameters() { UseEscapedUnicode = false })); } } else { textBox_log.Text = JSON.ToNiceJSON(patch, new JSONParameters() { UseEscapedUnicode = false }); } } catch (Exception ex) { Oops(ex); } }