From 9ec8a12288918832b32c391a239e739d8fb6d28a Mon Sep 17 00:00:00 2001 From: NovaRain Date: Fri, 5 Apr 2019 13:03:08 +0800 Subject: [PATCH] Added setting array values for the debug editor. Updates to sfall debug editor (part 1) --- MPClient/DebugEditor.Designer.cs | 163 +++++++++++++++------------- MPClient/DebugEditor.cs | 80 +++++++------- MPClient/EditorConnection.cs | 6 +- MPClient/EditorWindow.Designer.cs | 26 +++-- MPClient/EditorWindow.cs | 16 ++- MPClient/EditorWindow.resx | 9 ++ MPClient/Program.cs | 3 +- MPClient/Properties/AssemblyInfo.cs | 2 +- MPClient/SfallDebugEditor.csproj | 13 +-- sfall/Arrays.cpp | 22 +++- sfall/Arrays.h | 2 +- sfall/DebugEditor.cpp | 71 ++++++------ sfall/FalloutEngine.h | 1 + 13 files changed, 235 insertions(+), 179 deletions(-) diff --git a/MPClient/DebugEditor.Designer.cs b/MPClient/DebugEditor.Designer.cs index bc8b6839..c9ce1dae 100644 --- a/MPClient/DebugEditor.Designer.cs +++ b/MPClient/DebugEditor.Designer.cs @@ -23,17 +23,19 @@ /// the contents of this method with the code editor. /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.Column0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.bGlobals = new System.Windows.Forms.Button(); this.bMapVars = new System.Windows.Forms.Button(); this.bCritters = new System.Windows.Forms.Button(); this.bSGlobals = new System.Windows.Forms.Button(); this.bArrays = new System.Windows.Forms.Button(); this.bEdit = new System.Windows.Forms.Button(); - this.Column0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.bCrittersLvar = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); this.SuspendLayout(); // @@ -45,7 +47,7 @@ this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + this.dataGridView1.ColumnHeadersHeight = 22; this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.Column0, this.Column1, @@ -55,77 +57,13 @@ this.dataGridView1.MultiSelect = false; this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.RowHeadersVisible = false; + this.dataGridView1.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing; this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; - this.dataGridView1.Size = new System.Drawing.Size(443, 233); + this.dataGridView1.Size = new System.Drawing.Size(561, 354); this.dataGridView1.TabIndex = 0; this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick); this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit); - // - // bGlobals - // - this.bGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.bGlobals.Location = new System.Drawing.Point(12, 251); - this.bGlobals.Name = "bGlobals"; - this.bGlobals.Size = new System.Drawing.Size(100, 23); - this.bGlobals.TabIndex = 1; - this.bGlobals.Text = "Globals"; - this.bGlobals.UseVisualStyleBackColor = true; - this.bGlobals.Click += new System.EventHandler(this.bGlobals_Click); - // - // bMapVars - // - this.bMapVars.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.bMapVars.Location = new System.Drawing.Point(118, 251); - this.bMapVars.Name = "bMapVars"; - this.bMapVars.Size = new System.Drawing.Size(100, 23); - this.bMapVars.TabIndex = 2; - this.bMapVars.Text = "Map variables"; - this.bMapVars.UseVisualStyleBackColor = true; - this.bMapVars.Click += new System.EventHandler(this.bMapVars_Click); - // - // bCritters - // - this.bCritters.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.bCritters.Location = new System.Drawing.Point(12, 280); - this.bCritters.Name = "bCritters"; - this.bCritters.Size = new System.Drawing.Size(100, 23); - this.bCritters.TabIndex = 3; - this.bCritters.Text = "Critters"; - this.bCritters.UseVisualStyleBackColor = true; - this.bCritters.Click += new System.EventHandler(this.bCritters_Click); - // - // bSGlobals - // - this.bSGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.bSGlobals.Location = new System.Drawing.Point(249, 251); - this.bSGlobals.Name = "bSGlobals"; - this.bSGlobals.Size = new System.Drawing.Size(100, 23); - this.bSGlobals.TabIndex = 4; - this.bSGlobals.Text = "sfall globals"; - this.bSGlobals.UseVisualStyleBackColor = true; - this.bSGlobals.Click += new System.EventHandler(this.bSGlobals_Click); - // - // bArrays - // - this.bArrays.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.bArrays.Location = new System.Drawing.Point(355, 251); - this.bArrays.Name = "bArrays"; - this.bArrays.Size = new System.Drawing.Size(100, 23); - this.bArrays.TabIndex = 5; - this.bArrays.Text = "sfall arrays"; - this.bArrays.UseVisualStyleBackColor = true; - this.bArrays.Click += new System.EventHandler(this.bArrays_Click); - // - // bEdit - // - this.bEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.bEdit.Location = new System.Drawing.Point(355, 280); - this.bEdit.Name = "bEdit"; - this.bEdit.Size = new System.Drawing.Size(100, 23); - this.bEdit.TabIndex = 6; - this.bEdit.Text = "Edit"; - this.bEdit.UseVisualStyleBackColor = true; - this.bEdit.Click += new System.EventHandler(this.bEdit_Click); + this.dataGridView1.RowsAdded += new System.Windows.Forms.DataGridViewRowsAddedEventHandler(this.dataGridView1_RowsAdded); // // Column0 // @@ -151,11 +89,89 @@ this.Column3.HeaderText = "Value (Float)"; this.Column3.Name = "Column3"; // + // bGlobals + // + this.bGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.bGlobals.Location = new System.Drawing.Point(12, 372); + this.bGlobals.Name = "bGlobals"; + this.bGlobals.Size = new System.Drawing.Size(100, 23); + this.bGlobals.TabIndex = 1; + this.bGlobals.Text = "Globals"; + this.bGlobals.UseVisualStyleBackColor = true; + this.bGlobals.Click += new System.EventHandler(this.bGlobals_Click); + // + // bMapVars + // + this.bMapVars.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.bMapVars.Location = new System.Drawing.Point(118, 372); + this.bMapVars.Name = "bMapVars"; + this.bMapVars.Size = new System.Drawing.Size(100, 23); + this.bMapVars.TabIndex = 2; + this.bMapVars.Text = "Map variables"; + this.bMapVars.UseVisualStyleBackColor = true; + this.bMapVars.Click += new System.EventHandler(this.bMapVars_Click); + // + // bCritters + // + this.bCritters.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.bCritters.Location = new System.Drawing.Point(12, 401); + this.bCritters.Name = "bCritters"; + this.bCritters.Size = new System.Drawing.Size(100, 23); + this.bCritters.TabIndex = 3; + this.bCritters.Text = "Critters"; + this.bCritters.UseVisualStyleBackColor = true; + this.bCritters.Click += new System.EventHandler(this.bCritters_Click); + // + // bSGlobals + // + this.bSGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.bSGlobals.Location = new System.Drawing.Point(367, 372); + this.bSGlobals.Name = "bSGlobals"; + this.bSGlobals.Size = new System.Drawing.Size(100, 23); + this.bSGlobals.TabIndex = 4; + this.bSGlobals.Text = "sfall globals"; + this.bSGlobals.UseVisualStyleBackColor = true; + this.bSGlobals.Click += new System.EventHandler(this.bSGlobals_Click); + // + // bArrays + // + this.bArrays.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.bArrays.Location = new System.Drawing.Point(473, 372); + this.bArrays.Name = "bArrays"; + this.bArrays.Size = new System.Drawing.Size(100, 23); + this.bArrays.TabIndex = 5; + this.bArrays.Text = "sfall arrays"; + this.bArrays.UseVisualStyleBackColor = true; + this.bArrays.Click += new System.EventHandler(this.bArrays_Click); + // + // bEdit + // + this.bEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.bEdit.Location = new System.Drawing.Point(473, 401); + this.bEdit.Name = "bEdit"; + this.bEdit.Size = new System.Drawing.Size(100, 23); + this.bEdit.TabIndex = 6; + this.bEdit.Text = "Edit"; + this.bEdit.UseVisualStyleBackColor = true; + this.bEdit.Click += new System.EventHandler(this.bEdit_Click); + // + // bCrittersLvar + // + this.bCrittersLvar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.bCrittersLvar.Enabled = false; + this.bCrittersLvar.Location = new System.Drawing.Point(119, 401); + this.bCrittersLvar.Name = "bCrittersLvar"; + this.bCrittersLvar.Size = new System.Drawing.Size(99, 23); + this.bCrittersLvar.TabIndex = 7; + this.bCrittersLvar.Text = "Local variables"; + this.bCrittersLvar.UseVisualStyleBackColor = true; + // // DebugEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(467, 315); + this.ClientSize = new System.Drawing.Size(585, 436); + this.Controls.Add(this.bCrittersLvar); this.Controls.Add(this.bEdit); this.Controls.Add(this.bArrays); this.Controls.Add(this.bSGlobals); @@ -185,6 +201,7 @@ private System.Windows.Forms.DataGridViewTextBoxColumn Column1; private System.Windows.Forms.DataGridViewTextBoxColumn Column2; private System.Windows.Forms.DataGridViewTextBoxColumn Column3; + private System.Windows.Forms.Button bCrittersLvar; } } \ No newline at end of file diff --git a/MPClient/DebugEditor.cs b/MPClient/DebugEditor.cs index b6d909c5..a9051113 100644 --- a/MPClient/DebugEditor.cs +++ b/MPClient/DebugEditor.cs @@ -47,36 +47,27 @@ namespace FalloutClient { private readonly Dictionary CritNames = new Dictionary(); private void Redraw() { + bEdit.Enabled = false; + Column2.ReadOnly = false; + Column3.ReadOnly = false; + Column2.HeaderText = "Value (Int)"; + Column3.HeaderText = "Value (Float)"; + dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect; dataGridView1.SuspendLayout(); dataGridView1.Rows.Clear(); switch (mode) { case Mode.Globals: - Column2.ReadOnly = false; - Column3.ReadOnly = false; - Column2.HeaderText = "Value (Int)"; - Column3.HeaderText = "Value (Float)"; - bEdit.Enabled = false; for (int i = 0; i < connection.Globals.Length; i++) { string name = GlobNames.ContainsKey(i) ? GlobNames[i] : ""; dataGridView1.Rows.Add(i, name, connection.Globals[i], converter.GetAsFloat(connection.Globals[i])); } break; case Mode.MapVars: - Column2.ReadOnly = false; - Column3.ReadOnly = false; - Column2.HeaderText = "Value (Int)"; - Column3.HeaderText = "Value (Float)"; - bEdit.Enabled = false; for (int i = 0; i < connection.MapVars.Length; i++) { dataGridView1.Rows.Add(i, "", connection.MapVars[i], converter.GetAsFloat(connection.MapVars[i])); } break; case Mode.SGlobals: - Column2.ReadOnly = false; - Column3.ReadOnly = false; - Column2.HeaderText = "Value (Int)"; - Column3.HeaderText = "Value (Float)"; - bEdit.Enabled = false; for (int i = 0; i < connection.SGlobalKeys.Length; i++) { string s = connection.SGlobalKeys[i] > 0xffffffff ? new string(System.Text.ASCIIEncoding.ASCII.GetChars(converter.GetAsBytes(connection.SGlobalKeys[i]))) @@ -85,6 +76,7 @@ namespace FalloutClient { } break; case Mode.Arrays: + dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; Column2.ReadOnly = true; Column3.ReadOnly = true; Column2.HeaderText = "Array size"; @@ -94,13 +86,14 @@ namespace FalloutClient { bool isMap = connection.ArrayIsMap[i]; int arrlen = connection.ArrayLengths[i]; if (isMap) arrlen /= 2; - dataGridView1.Rows.Add(connection.Arrays[i], isMap ? "Map" : "", arrlen, "0x" + connection.ArrayDataSizes[i].ToString("x").ToUpper()); + dataGridView1.Rows.Add(connection.Arrays[i], isMap ? "Map" : "", arrlen, "0x" + connection.ArrayFlag[i].ToString("x").ToUpper()); } break; case Mode.Critters: + dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; Column2.ReadOnly = true; Column3.ReadOnly = true; - Column2.HeaderText = "Pid"; + Column2.HeaderText = "PID"; Column3.HeaderText = "Pointer"; bEdit.Enabled = true; for (int i = 0; i < connection.Critters.Length / 2; i++) { @@ -194,8 +187,9 @@ namespace FalloutClient { return; } if (e.ColumnIndex == 2) { + string str = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); int val; - if (!int.TryParse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out val)) { + if (str == null || !int.TryParse(str, out val)) { dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = array[e.RowIndex]; } else { array[e.RowIndex] = val; @@ -204,8 +198,9 @@ namespace FalloutClient { connection.WriteInt(val); } } else { + string str = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); float val; - if (!float.TryParse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out val)) { + if (str == null || !float.TryParse(str, out val)) { dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = array[e.RowIndex]; } else { array[e.RowIndex] = converter.GetAsInt(val); @@ -218,7 +213,7 @@ namespace FalloutClient { private void bEdit_Click(object sender, EventArgs e) { if (dataGridView1.SelectedRows.Count == 0) return; - int i = dataGridView1.SelectedRows[0].Index; + int i = (int)dataGridView1.SelectedRows[0].Tag; switch (mode) { case Mode.Arrays: { DataType[] types = new DataType[connection.ArrayLengths[i]]; @@ -233,9 +228,7 @@ namespace FalloutClient { lenData += lenType[j]; } byte[] buf = connection.ReadBytes(lenData); // read data - MemoryStream ms=new MemoryStream(buf); - BinaryReader br=new BinaryReader(ms); - ms.Position = 0; + BinaryReader br = new BinaryReader(new MemoryStream(buf)); for (int j = 0; j < strings.Length; j++) { switch (types[j]) { case DataType.Int: @@ -246,19 +239,16 @@ namespace FalloutClient { break; case DataType.String: byte[] bytes = br.ReadBytes(lenType[j]); - strings[j] = System.Text.Encoding.ASCII.GetString(bytes, 0, lenType[j] - 1); //Array.IndexOf(bytes, 0) + strings[j] = System.Text.Encoding.ASCII.GetString(bytes, 0, Array.IndexOf(bytes, 0)); break; } } br.Close(); - strings = EditorWindow.ShowEditor(null, types, strings); + strings = EditorWindow.ShowEditor(this, null, types, strings, connection.ArrayIsMap[i]); if (strings != null) { // save - connection.WriteDataType(DataTypeSend.SetArray); - connection.WriteInt(i); - ms = new MemoryStream(connection.ArrayLengths[i] * connection.ArrayDataSizes[i]); - BinaryWriter bw=new BinaryWriter(ms); + MemoryStream ms = new MemoryStream(lenData); + BinaryWriter bw = new BinaryWriter(ms); for (int j = 0; j < strings.Length; j++) { - ms.Position = j * connection.ArrayDataSizes[i]; switch (types[j]) { case DataType.Int: bw.Write(int.Parse(strings[j])); @@ -267,25 +257,31 @@ namespace FalloutClient { bw.Write(float.Parse(strings[j])); break; case DataType.String: - byte[] bytes=System.Text.Encoding.ASCII.GetBytes(strings[j]); - if (bytes.Length < connection.ArrayDataSizes[i]) bw.Write(bytes); - else bw.Write(bytes, 0, connection.ArrayDataSizes[i] - 1); - bw.Write(0); + byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strings[j]); + if (bytes.Length < lenType[j]) + bw.Write(bytes); + else + bw.Write(bytes, 0, lenType[j] - 1); + bw.Write((byte)0); break; } } - connection.WriteBytes(ms.GetBuffer(), 0, connection.ArrayLengths[i] * connection.ArrayDataSizes[i]); + // send data to sfall + connection.WriteDataType(DataTypeSend.SetArray); + connection.WriteInt(i); // index + connection.WriteInt(lenData); + connection.WriteBytes(ms.GetBuffer(), 0, lenData); bw.Close(); } } break; case Mode.Critters: { - DataType[] types=new DataType[33]; - string[] strings=new string[33]; - string[] names=new string[33]; + DataType[] types = new DataType[33]; + string[] strings = new string[33]; + string[] names = new string[33]; connection.WriteDataType(DataTypeSend.RetrieveCritter); connection.WriteInt(i); - BinaryReader br=new BinaryReader(new System.IO.MemoryStream(connection.ReadBytes(33 * 4))); + BinaryReader br = new BinaryReader(new System.IO.MemoryStream(connection.ReadBytes(33 * 4))); for (int j = 0; j < 33; j++) { types[j] = DataType.Int; strings[j] = br.ReadInt32().ToString(); @@ -316,7 +312,7 @@ namespace FalloutClient { names[29] = " Outline flags"; names[30] = " Script ID"; names[32] = " Script index"; - strings = EditorWindow.ShowEditor(names, types, strings); + strings = EditorWindow.ShowEditor(this, names, types, strings); if (strings != null) { MemoryStream ms = new MemoryStream(33 * 4); BinaryWriter bw = new BinaryWriter(ms); @@ -334,5 +330,9 @@ namespace FalloutClient { private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { bEdit.PerformClick(); } + + private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { + dataGridView1.Rows[e.RowIndex].Tag = e.RowIndex; + } } } diff --git a/MPClient/EditorConnection.cs b/MPClient/EditorConnection.cs index 707a4ee7..b54ba515 100644 --- a/MPClient/EditorConnection.cs +++ b/MPClient/EditorConnection.cs @@ -18,7 +18,7 @@ namespace FalloutClient { public readonly int[] sGlobals; public readonly uint[] Arrays; public readonly int[] ArrayLengths; - public readonly int[] ArrayDataSizes; + public readonly int[] ArrayFlag; public readonly bool[] ArrayIsMap; public EditorConnection() { @@ -33,7 +33,7 @@ namespace FalloutClient { sGlobals = new int[SGlobalKeys.Length]; Arrays = new uint[br.ReadInt32()]; ArrayLengths = new int[Arrays.Length]; - ArrayDataSizes = new int[Arrays.Length]; + ArrayFlag = new int[Arrays.Length]; ArrayIsMap = new bool[Arrays.Length]; Critters = new uint[br.ReadInt32(), 2]; @@ -48,7 +48,7 @@ namespace FalloutClient { Arrays[i] = br.ReadUInt32(); ArrayIsMap[i] = (br.ReadInt32() != 0); ArrayLengths[i] = br.ReadInt32(); - ArrayDataSizes[i] = br.ReadInt32(); + ArrayFlag[i] = br.ReadInt32(); } for (int i = 0; i < Critters.Length / 2; i++) { Critters[i, 0] = br.ReadUInt32(); diff --git a/MPClient/EditorWindow.Designer.cs b/MPClient/EditorWindow.Designer.cs index 63e089ea..052916b1 100644 --- a/MPClient/EditorWindow.Designer.cs +++ b/MPClient/EditorWindow.Designer.cs @@ -34,8 +34,8 @@ // // bSave // - this.bSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.bSave.Location = new System.Drawing.Point(12, 265); + this.bSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.bSave.Location = new System.Drawing.Point(12, 336); this.bSave.Name = "bSave"; this.bSave.Size = new System.Drawing.Size(75, 23); this.bSave.TabIndex = 0; @@ -46,7 +46,7 @@ // bCancel // this.bCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.bCancel.Location = new System.Drawing.Point(281, 265); + this.bCancel.Location = new System.Drawing.Point(371, 336); this.bCancel.Name = "bCancel"; this.bCancel.Size = new System.Drawing.Size(75, 23); this.bCancel.TabIndex = 1; @@ -62,15 +62,18 @@ this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.ColumnHeadersHeight = 22; this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.Column1, this.Column2, this.Column3}); this.dataGridView1.Location = new System.Drawing.Point(12, 12); + this.dataGridView1.MultiSelect = false; this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.RowHeadersVisible = false; - this.dataGridView1.Size = new System.Drawing.Size(344, 247); + this.dataGridView1.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing; + this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dataGridView1.Size = new System.Drawing.Size(434, 318); this.dataGridView1.TabIndex = 2; this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit); // @@ -80,30 +83,35 @@ this.Column1.HeaderText = "Element"; this.Column1.Name = "Column1"; this.Column1.ReadOnly = true; + this.Column1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; // // Column2 // this.Column2.HeaderText = "Type"; this.Column2.Name = "Column2"; this.Column2.ReadOnly = true; - this.Column2.Width = 90; + this.Column2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.Column2.Width = 75; // // Column3 // this.Column3.HeaderText = "Value"; this.Column3.Name = "Column3"; - this.Column3.Width = 125; + this.Column3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.Column3.Width = 150; // // EditorWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(368, 300); + this.ClientSize = new System.Drawing.Size(458, 371); this.Controls.Add(this.dataGridView1); this.Controls.Add(this.bCancel); this.Controls.Add(this.bSave); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.MinimumSize = new System.Drawing.Size(300, 200); this.Name = "EditorWindow"; - this.Text = "Editor Window"; + this.Text = "Edit Values"; ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); this.ResumeLayout(false); diff --git a/MPClient/EditorWindow.cs b/MPClient/EditorWindow.cs index c3479bc3..b7a9eb60 100644 --- a/MPClient/EditorWindow.cs +++ b/MPClient/EditorWindow.cs @@ -12,20 +12,24 @@ namespace FalloutClient { private readonly string[] values; private bool save; - private EditorWindow(string[] names, DataType[] types, string[] values) { + private EditorWindow(string[] names, DataType[] types, string[] values, bool isMap) { this.types = types; this.values = values; InitializeComponent(); dataGridView1.SuspendLayout(); if (names == null) - for (int i = 0; i < types.Length; i++) dataGridView1.Rows.Add(i.ToString(), types[i].ToString(), values[i]); + for (int i = 0; i < types.Length; i++) { + string element = i.ToString(); + if (isMap && (i % 2) == 0) element += " - Key"; + dataGridView1.Rows.Add(element, types[i].ToString(), values[i]); + } else - for (int i = 0; i < types.Length; i++) dataGridView1.Rows.Add("0x" + (i * 4).ToString("x").ToUpper() + names[i], types[i].ToString(), values[i]); + for (int i = 0; i < types.Length; i++) dataGridView1.Rows.Add("[0x" + (i * 4).ToString("x").ToUpper() + "]" + names[i], types[i].ToString(), values[i]); dataGridView1.ResumeLayout(); } - public static string[] ShowEditor(string[] names, DataType[] types, string[] values) { - EditorWindow editor = new EditorWindow(names, types, values); + public static string[] ShowEditor(DebugEditor form, string[] names, DataType[] types, string[] values, bool isMap = false) { + EditorWindow editor = new EditorWindow(names, types, values, isMap); editor.ShowDialog(); if (editor.save) return editor.values; @@ -47,7 +51,7 @@ namespace FalloutClient { private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { string str = (string)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; - if (CheckInput(types[e.RowIndex], str)) + if (str != null && CheckInput(types[e.RowIndex], str)) values[e.RowIndex] = str; else dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = values[e.RowIndex]; diff --git a/MPClient/EditorWindow.resx b/MPClient/EditorWindow.resx index f9914ad8..a4ce6fe7 100644 --- a/MPClient/EditorWindow.resx +++ b/MPClient/EditorWindow.resx @@ -126,4 +126,13 @@ True + + True + + + True + + + True + \ No newline at end of file diff --git a/MPClient/Program.cs b/MPClient/Program.cs index a1afae60..f8e7308c 100644 --- a/MPClient/Program.cs +++ b/MPClient/Program.cs @@ -15,7 +15,8 @@ namespace FalloutClient { if (args.Length == 1 && args[0] == "-debugedit") { Application.Run(new DebugEditor(new EditorConnection())); } else { - throw new Exception("Multiplayer is no longer supported"); + MessageBox.Show("The debug editor can only be run from the game.", + "sfall Debug Editor", MessageBoxButtons.OK, MessageBoxIcon.Stop); } } } diff --git a/MPClient/Properties/AssemblyInfo.cs b/MPClient/Properties/AssemblyInfo.cs index 814746b2..69749a54 100644 --- a/MPClient/Properties/AssemblyInfo.cs +++ b/MPClient/Properties/AssemblyInfo.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Fallout sfall Debug Editor")] +[assembly: AssemblyTitle("sfall Debug Editor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] diff --git a/MPClient/SfallDebugEditor.csproj b/MPClient/SfallDebugEditor.csproj index a74293c0..06709b9e 100644 --- a/MPClient/SfallDebugEditor.csproj +++ b/MPClient/SfallDebugEditor.csproj @@ -16,6 +16,7 @@ v2.0 + false publish\ true Disk @@ -28,9 +29,8 @@ true 0 1.0.0.%2a - false false - true + false true @@ -82,18 +82,13 @@ False - Клиентский профиль .NET Framework 3.5 SP1 + .NET Framework 3.5 SP1 Client Profile false False .NET Framework 3.5 SP1 - true - - - False - Установщик Windows 3.1 - true + false diff --git a/sfall/Arrays.cpp b/sfall/Arrays.cpp index 7be02e34..f6d637d0 100644 --- a/sfall/Arrays.cpp +++ b/sfall/Arrays.cpp @@ -333,10 +333,24 @@ void DEGetArray(int id, DWORD* types, char* data) { } } -// those too are not really used yet in FalloutClient (AFAIK) -- phobos2077 -void DESetArray(int id, const DWORD* types, const void* data) { - //if (types) memcpy(arrays[id].types, types, arrays[id].len * 4); - //memcpy(arrays[id].data, data, arrays[id].len*arrays[id].datalen); +void DESetArray(int id, const DWORD* types, const char* data) { + int pos = 0; + for (size_t i = 0; i < arrays[id].val.size(); i++) { + sArrayElement& arVal = arrays[id].val[i]; + switch (arVal.type) { + case DATATYPE_INT: + arVal.intVal = *(long*)(data + pos); + pos += 4; + break; + case DATATYPE_FLOAT: + arVal.floatVal = *(float*)(data + pos); + pos += 4; + break; + case DATATYPE_STR: + strcpy(arVal.strVal, data + pos); + pos += arVal.len; + } + } } /* diff --git a/sfall/Arrays.h b/sfall/Arrays.h index 6697fe0b..c0b3fc72 100644 --- a/sfall/Arrays.h +++ b/sfall/Arrays.h @@ -152,7 +152,7 @@ int GetNumArrays(); void GetArrays(int* arrays); void DEGetArray(int id, DWORD* types, char* data); -void DESetArray(int id, const DWORD* types, const void* data); +void DESetArray(int id, const DWORD* types, const char* data); const char* _stdcall GetSfallTypeName(DWORD dataType); DWORD _stdcall getSfallTypeByScriptType(DWORD varType); diff --git a/sfall/DebugEditor.cpp b/sfall/DebugEditor.cpp index d71c0b0a..afebb7ee 100644 --- a/sfall/DebugEditor.cpp +++ b/sfall/DebugEditor.cpp @@ -48,6 +48,10 @@ struct sArray { long flag; }; +static void DEGameWinRedraw() { + __asm call process_bk_; +} + static bool SetBlocking(SOCKET s, bool block) { DWORD d = !block; ioctlsocket(s, FIONBIO, &d); @@ -56,13 +60,12 @@ static bool SetBlocking(SOCKET s, bool block) { static bool InternalSend(SOCKET s, const void* _data, int size) { const char* data = (const char*)_data; int upto = 0; - int tmp; - DWORD d; while (upto < size) { - tmp = send(s, &data[upto], size - upto, 0); - if (tmp > 0) upto += tmp; - else { - d = WSAGetLastError(); + int tmp = send(s, &data[upto], size - upto, 0); + if (tmp > 0) { + upto += tmp; + } else { + DWORD d = WSAGetLastError(); if (d != WSAEWOULDBLOCK && d != WSAENOBUFS) return true; } } @@ -72,13 +75,12 @@ static bool InternalSend(SOCKET s, const void* _data, int size) { static bool InternalRecv(SOCKET s, void* _data, int size) { char* data = (char*)_data; int upto = 0; - int tmp; - DWORD d; while (upto < size) { - tmp = recv(s, &data[upto], size - upto, 0); - if (tmp > 0) upto += tmp; - else { - d = WSAGetLastError(); + int tmp = recv(s, &data[upto], size - upto, 0); + if (tmp > 0) { + upto += tmp; + } else { + DWORD d = WSAGetLastError(); if (d != WSAEWOULDBLOCK && d != WSAENOBUFS) return true; } } @@ -86,6 +88,8 @@ static bool InternalRecv(SOCKET s, void* _data, int size) { } static void RunEditorInternal(SOCKET &s) { + *(DWORD*)_script_engine_running = 0; + std::vector vec = std::vector(); for (int elv = 0; elv < 3; elv++) { for (int tile = 0; tile < 40000; tile++) { @@ -107,13 +111,12 @@ static void RunEditorInternal(SOCKET &s) { } } } - int numCritters = vec.size(); - int numGlobals = *(int*)_num_game_global_vars; int numMapVars = *(int*)_num_map_global_vars; int numSGlobals = GetNumGlobals(); int numArrays = GetNumArrays(); + InternalSend(s, &numGlobals, 4); InternalSend(s, &numMapVars, 4); InternalSend(s, &numSGlobals, 4); @@ -122,6 +125,7 @@ static void RunEditorInternal(SOCKET &s) { sGlobalVar* sglobals=new sGlobalVar[numSGlobals]; GetGlobals(sglobals); + sArray* arrays = new sArray[numArrays]; GetArrays((int*)arrays); @@ -140,30 +144,30 @@ static void RunEditorInternal(SOCKET &s) { if (code == CODE_EXIT) break; int id, val; switch (code) { - case 0: + case CODE_SET_GLOBAL: InternalRecv(s, &id, 4); InternalRecv(s, &val, 4); (*(DWORD**)_game_global_vars)[id] = val; break; - case 1: + case CODE_SET_MAPVAR: InternalRecv(s, &id, 4); InternalRecv(s, &val, 4); (*(DWORD**)_map_global_vars)[id] = val; break; - case 2: // Retrieve Critter + case CODE_GET_CRITTER: InternalRecv(s, &id, 4); InternalSend(s, vec[id], 0x84); break; - case 3: // Set Critter + case CODE_SET_CRITTER: InternalRecv(s, &id, 4); InternalRecv(s, vec[id], 0x84); break; - case 4: + case CODE_SET_SGLOBAL: InternalRecv(s, &id, 4); InternalRecv(s, &val, 4); sglobals[id].val = val; break; - case 9: // get array values + case CODE_GET_ARRAY: // get array values { InternalRecv(s, &id, 4); DWORD *types = new DWORD[arrays[id].size * 2]; // type, len @@ -180,22 +184,25 @@ static void RunEditorInternal(SOCKET &s) { delete[] types; } break; - case 10: // set array values + case CODE_SET_ARRAY: // set array values { - //InternalRecv(s, &id, 4); - //InternalRecv(s, &val, 4); - //char *data = new char[arrays[id].size * arrays[id * 3 + 2]]; - //InternalRecv(s, data, arrays[id].size * arrays[id * 3 + 2]); - //DESetArray(arrays[id].id, 0, data); - //delete[] data; + InternalRecv(s, &id, 4); + InternalRecv(s, &val, 4); // len data + char *data = new char[val]; + InternalRecv(s, data, val); + DESetArray(arrays[id].id, nullptr, data); + delete[] data; } break; } + DEGameWinRedraw(); } SetGlobals(sglobals); delete[] sglobals; delete[] arrays; + + *(DWORD*)_script_engine_running = 1; } void RunDebugEditor() { @@ -203,13 +210,13 @@ void RunDebugEditor() { SOCKET sock, client; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) return; - //create the socket + // create the socket sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { WSACleanup(); return; } - //bind the socket + // bind the socket sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("127.0.0.1"); @@ -226,7 +233,7 @@ void RunDebugEditor() { return; } - //Start up the editor + // Start up the editor STARTUPINFO si; PROCESS_INFORMATION pi; @@ -244,7 +251,7 @@ void RunDebugEditor() { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); - //Connect to the editor + // Connect to the editor client = accept(sock, 0, 0); if (client == SOCKET_ERROR) { closesocket(sock); @@ -286,7 +293,7 @@ void DebugModePatch() { DWORD dbgMode = GetPrivateProfileIntA("Debugging", "DebugMode", 0, ".\\ddraw.ini"); if (dbgMode) { dlog("Applying debugmode patch.", DL_INIT); - //If the player is using an exe with the debug patch already applied, just skip this block without erroring + // If the player is using an exe with the debug patch already applied, just skip this block without erroring if (*((DWORD*)0x444A64) != 0x082327E8) { SafeWrite32(0x444A64, 0x082327E8); // call debug_register_env_ SafeWrite32(0x444A68, 0x0120E900); // jmp 0x444B8E diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 8e5a5a5c..9727dbee 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -197,6 +197,7 @@ #define _rotation 0x631D34 #define _sad 0x530014 #define _scr_size 0x6AC9F0 +#define _script_engine_running 0x51C714 #define _scriptListInfo 0x51C7C8 #define _skill_data 0x51D118 #define _slot_cursor 0x5193B8