private void TextBox_LostFocus(object sender, RoutedEventArgs e) { TextBox tb = sender as TextBox; var binding = BindingOperations.GetBindingExpression(tb, TextBox.TextProperty); if (binding.IsDirty) { if (ObjectReference != null) { StringUpdateWindow dialog = new StringUpdateWindow(); dialog.Owner = Window.GetWindow(this); dialog.ShowDialog(); switch (dialog.Result) { case StringUpdateWindow.ResultType.ChangeOneValue: ObjectReference = (Application.Current.MainWindow as MainWindow).Data.Strings.MakeString(tb.Text); break; case StringUpdateWindow.ResultType.ChangeReferencedValue: binding.UpdateSource(); break; case StringUpdateWindow.ResultType.Cancel: binding.UpdateTarget(); break; } } else { ObjectReference = (Application.Current.MainWindow as MainWindow).Data.Strings.MakeString(tb.Text); } } }
/// <inheritdoc/> public void Dispose() { GC.SuppressFinalize(this); Name = null; Value = null; }
private void TextBox_DragOver(object sender, DragEventArgs e) { UndertaleString sourceItem = e.Data.GetData(e.Data.GetFormats()[0]) as UndertaleString; e.Effects = e.AllowedEffects.HasFlag(DragDropEffects.Link) && sourceItem != null ? DragDropEffects.Link : DragDropEffects.None; e.Handled = true; }
/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { InternalCount = reader.ReadInt32(); if (InternalCount > 0) { Event = reader.ReadUndertaleString(); } }
/// <inheritdoc /> public override string ToString() { try { return(Name.Content + " (" + GetType().Name + ")"); } catch { Name = new UndertaleString("EmbeddedSound Unknown Index"); } return(Name.Content + " (" + GetType().Name + ")"); }
/// <inheritdoc /> public override string ToString() { if (Name != null) { return(Name.Content + " (" + GetType().Name + ")"); } else { Name = new UndertaleString("Texture Unknown Index"); } return(Name.Content + " (" + GetType().Name + ")"); }
private static UndertaleResourceById <UndertaleString, UndertaleChunkSTRG> ParseStringReference(string line, IList <UndertaleString> strg) { string str = line; int at = str.LastIndexOf('@'); uint? id = null; if (at >= 0) { // First make certain that this is actually an ID, not part of the string content if ((at - 1) == str.LastIndexOf('"')) { if (str.Substring(at + 1) != "-1") // TODO { id = UInt32.Parse(str.Substring(at + 1)); } str = str.Substring(0, at); } } if (!String.IsNullOrEmpty(str)) { if (str[0] != '"' || str[str.Length - 1] != '"') { throw new Exception("Bad string format"); } str = UndertaleString.UnescapeText(str.Substring(1, str.Length - 2)); } else { str = null; } UndertaleString strobj = id.HasValue ? strg[(int)id.Value] : null; if (strobj != null) { if (str != null) // Retain original value if empty string passed (push.s @300) { strobj.Content = str; } } else { strobj = strg.MakeString(str); } if (!id.HasValue) { id = (uint)strg.IndexOf(strobj); } return(new UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>() { Resource = strobj, CachedId = (int)id.Value }); }
private static UndertaleResourceById <UndertaleString, UndertaleChunkSTRG> ParseStringReference(string line, IList <UndertaleString> strg) { string str = line; int at = str.LastIndexOf('@'); uint? id = null; if (at >= 0) { if (str.Substring(at + 1) != "-1") // TODO { id = UInt32.Parse(str.Substring(at + 1)); } str = str.Substring(0, at); } if (!String.IsNullOrEmpty(str)) { if (str[0] != '"' || str[str.Length - 1] != '"') { throw new Exception("Bad string format"); } str = str.Substring(1, str.Length - 2); } UndertaleString strobj = id.HasValue ? strg[(int)id.Value] : null; if (strobj != null) { strobj.Content = str; } else { strobj = strg.MakeString(str); } if (!id.HasValue) { id = (uint)strg.IndexOf(strobj); } return(new UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>() { Resource = strobj, CachedId = (int)id.Value }); }
/// <summary> /// Creates <paramref name="content"/> as a new <see cref="UndertaleString"/>, /// adds it to a <see cref="List{T}"/> of <see cref="UndertaleString"/> if it does not exist yet, and returns it. /// </summary> /// <param name="list">The <see cref="List{T}"/> of <see cref="UndertaleString"/>.</param> /// <param name="content">The string to create a <see cref="UndertaleString"/> of.</param> /// <returns><paramref name="content"/> as a <see cref="UndertaleString"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="content"/> is null.</exception> public static UndertaleString MakeString(this IList <UndertaleString> list, string content) { if (content == null) { throw new ArgumentNullException(nameof(content)); } // TODO: without reference counting the strings, this may leave unused strings in the array foreach (UndertaleString str in list) { if (str.Content == content) { return(str); } } UndertaleString newString = new UndertaleString(content); list.Add(newString); return(newString); }
/// <summary> /// Creates <paramref name="content"/> as a new <see cref="UndertaleString"/>, /// adds it to a <see cref="List{T}"/> of <see cref="UndertaleString"/> if it does not exist yet, and returns it. /// </summary> /// <param name="list">The <see cref="List{T}"/> of <see cref="UndertaleString"/>.</param> /// <param name="content">The string to create a <see cref="UndertaleString"/> of.</param> /// <param name="index">The index where the newly created <see cref="UndertaleString"/> is located in <paramref name="list"/>.</param> /// <returns><paramref name="content"/> as a <see cref="UndertaleString"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="content"/> is null.</exception> public static UndertaleString MakeString(this IList <UndertaleString> list, string content, out int index) { if (content == null) { throw new ArgumentNullException(nameof(content)); } // TODO: without reference counting the strings, this may leave unused strings in the array for (int i = 0; i < list.Count; i++) { UndertaleString str = list[i]; if (str.Content == content) { index = i; return(str); } } UndertaleString newString = new UndertaleString(content); index = list.Count; list.Add(newString); return(newString); }
public void DisassembleAndReassembleAllScripts() { Parallel.ForEach(data.Code, (code) => { //Console.WriteLine(code.Name.Content); bool knownBug = false; foreach (var instr in code.Instructions) { if (instr.Value?.GetType() == typeof(UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>)) { UndertaleString str = ((UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>)instr.Value).Resource; if (str.Content.Contains("\n") || str.Content.Contains("\"")) // see #28 { knownBug = true; } } } if (knownBug) { Console.WriteLine("SKIPPING " + code.Name.Content + ", known bug"); return; } string disasm; try { disasm = code.Disassemble(data.Variables, data.CodeLocals.For(code)); } catch (Exception e) { throw new Exception("Failed to disassemble script " + code.Name.Content, e); } IList <UndertaleInstruction> reasm = Assembler.Assemble(disasm, data.Functions, data.Variables, data.Strings); Assert.AreEqual(code.Instructions.Count, reasm.Count, "Reassembled instruction count didn't match the disassembly for script " + code.Name.Content); for (int i = 0; i < code.Instructions.Count; i++) { string errMsg = "Instruction at " + code.Instructions[i].Address.ToString("D5") + " didn't match for script: " + code.Name.Content; Assert.AreEqual(code.Instructions[i].Kind, reasm[i].Kind, errMsg); Assert.AreEqual(code.Instructions[i].ComparisonKind, reasm[i].ComparisonKind, errMsg); Assert.AreEqual(code.Instructions[i].Type1, reasm[i].Type1, errMsg); Assert.AreEqual(code.Instructions[i].Type2, reasm[i].Type2, errMsg); Assert.AreEqual(code.Instructions[i].TypeInst, reasm[i].TypeInst, errMsg); Assert.AreEqual(code.Instructions[i].Extra, reasm[i].Extra, errMsg); Assert.AreEqual(code.Instructions[i].SwapExtra, reasm[i].SwapExtra, errMsg); Assert.AreEqual(code.Instructions[i].ArgumentsCount, reasm[i].ArgumentsCount, errMsg); Assert.AreEqual(code.Instructions[i].JumpOffsetPopenvExitMagic, reasm[i].JumpOffsetPopenvExitMagic, errMsg); if (!code.Instructions[i].JumpOffsetPopenvExitMagic) { Assert.AreEqual(code.Instructions[i].JumpOffset, reasm[i].JumpOffset, errMsg); } Assert.AreSame(code.Instructions[i].Destination?.Target, reasm[i].Destination?.Target, errMsg); Assert.AreEqual(code.Instructions[i].Destination?.Type, reasm[i].Destination?.Type, errMsg); Assert.AreSame(code.Instructions[i].Function?.Target, reasm[i].Function?.Target, errMsg); Assert.AreEqual(code.Instructions[i].Function?.Type, reasm[i].Function?.Type, errMsg); Assert.AreEqual(code.Instructions[i].Value?.GetType(), reasm[i].Value?.GetType(), errMsg); if (code.Instructions[i].Value?.GetType() == typeof(double)) { Assert.AreEqual((double)code.Instructions[i].Value, (double)reasm[i].Value, Math.Abs((double)code.Instructions[i].Value) * (1e-5), errMsg); // see issue #53 } else if (code.Instructions[i].Value?.GetType() == typeof(float)) { Assert.AreEqual((float)code.Instructions[i].Value, (float)reasm[i].Value, Math.Abs((float)code.Instructions[i].Value) * (1e-5), errMsg); // see issue #53 } else if (code.Instructions[i].Value?.GetType() == typeof(UndertaleInstruction.Reference <UndertaleVariable>)) { Assert.AreSame(((UndertaleInstruction.Reference <UndertaleVariable>)code.Instructions[i].Value).Target, ((UndertaleInstruction.Reference <UndertaleVariable>)reasm[i].Value).Target, errMsg); } else if (code.Instructions[i].Value?.GetType() == typeof(UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>)) { Assert.AreSame(((UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>)code.Instructions[i].Value).Resource, ((UndertaleResourceById <UndertaleString, UndertaleChunkSTRG>)reasm[i].Value).Resource, errMsg); } else { Assert.AreEqual(code.Instructions[i].Value, reasm[i].Value, errMsg); } } }); }
public void Unserialize(UndertaleReader reader) { SourceCode = reader.ReadUndertaleString(); }
/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); }
private void Remove_Click(object sender, RoutedEventArgs e) { ObjectReference = null; }
/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { // This reads the string content immediately, if necessary (which it should be) UndertaleString ForceReadString() { UndertaleString res = reader.ReadUndertaleString(); uint returnTo = reader.Position; reader.Position = reader.GetOffsetMapRev()[res]; reader.ReadUndertaleObject <UndertaleString>(); reader.Position = returnTo; return(res); } ModelName = ForceReadString(); Name = reader.ReadUndertaleString(); BuiltinName = reader.ReadInt32(); Traits = reader.ReadInt32(); IsCreationTrack = reader.ReadBoolean(); int tagCount = reader.ReadInt32(); int ownedResCount = reader.ReadInt32(); int trackCount = reader.ReadInt32(); Tags = new List <int>(); for (int i = 0; i < tagCount; i++) { Tags.Add(reader.ReadInt32()); } OwnedResources = new List <UndertaleResource>(); for (int i = 0; i < ownedResCount; i++) { GMAnimCurveString = ForceReadString(); if (GMAnimCurveString.Content != "GMAnimCurve") { throw new IOException("Expected GMAnimCurve"); } UndertaleAnimationCurve res = new UndertaleAnimationCurve(); res.Unserialize(reader); OwnedResources.Add(res); } Tracks = new List <Track>(); for (int i = 0; i < trackCount; i++) { Tracks.Add(reader.ReadUndertaleObject <Track>()); } // Now, handle specific keyframe/etc. data switch (ModelName.Content) { case "GMAudioTrack": Keyframes = reader.ReadUndertaleObject <AudioKeyframes>(); break; case "GMInstanceTrack": Keyframes = reader.ReadUndertaleObject <InstanceKeyframes>(); break; case "GMGraphicTrack": Keyframes = reader.ReadUndertaleObject <GraphicKeyframes>(); break; case "GMSequenceTrack": Keyframes = reader.ReadUndertaleObject <SequenceKeyframes>(); break; case "GMSpriteFramesTrack": Keyframes = reader.ReadUndertaleObject <SpriteFramesKeyframes>(); break; case "GMAssetTrack": // TODO? throw new NotImplementedException("GMAssetTrack not implemented, report this"); case "GMBoolTrack": Keyframes = reader.ReadUndertaleObject <BoolKeyframes>(); break; case "GMStringTrack": Keyframes = reader.ReadUndertaleObject <StringKeyframes>(); break; // TODO? //case "GMIntTrack": // Keyframes = reader.ReadUndertaleObject<IntKeyframes>(); // break; case "GMRealTrack": case "GMColourTrack": Keyframes = reader.ReadUndertaleObject <RealKeyframes>(); break; } }