Skip to content

Commit e4b5da3

Browse files
committed
Add functionality to inject fields
Closes #15
1 parent 0a25b32 commit e4b5da3

17 files changed

+1255
-78
lines changed

OxidePatcher/Fields/Field.cs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
using System;
2+
using System.Linq;
3+
using System.Windows.Forms;
4+
5+
using Mono.Cecil;
6+
7+
using OxidePatcher.Patching;
8+
using System.IO;
9+
10+
namespace OxidePatcher.Fields
11+
{
12+
public enum Exposure { Private, Protected, Public, Internal, Static, Null }
13+
14+
/// <summary>
15+
/// Represents a hook that is applied to single method and calls a single Oxide hook
16+
/// </summary>
17+
public class Field
18+
{
19+
/// <summary>
20+
/// Gets or sets a name for this field
21+
/// </summary>
22+
public string Name { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the name of the assembly in which the target resides
26+
/// </summary>
27+
public string AssemblyName { get; set; }
28+
29+
/// <summary>
30+
/// Gets or sets the fully qualified name for the type in which the target resides
31+
/// </summary>
32+
public string TypeName { get; set; }
33+
34+
/// <summary>
35+
/// Gets or sets the field to be added
36+
/// </summary>
37+
public string FieldType { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets if this modifier has been flagged
41+
/// </summary>
42+
public bool Flagged { get; set; }
43+
44+
public Field()
45+
{
46+
}
47+
48+
public Field(TypeDefinition type, string assembly)
49+
{
50+
Name = "NewField";
51+
TypeName = type.FullName;
52+
FieldType = string.Empty;
53+
AssemblyName = assembly;
54+
}
55+
56+
protected void ShowMsg(string msg, string header, Patcher patcher = null)
57+
{
58+
if (patcher != null)
59+
patcher.Log(msg);
60+
else
61+
MessageBox.Show(msg, header, MessageBoxButtons.OK, MessageBoxIcon.Error);
62+
}
63+
64+
/// <summary>
65+
/// Creates the settings view control for this hook
66+
/// </summary>
67+
/// <returns></returns>
68+
public Views.FieldSettingsControl CreateSettingsView()
69+
{
70+
return new Views.FieldSettingsControl { Field = this };
71+
}
72+
73+
internal bool IsValid(bool warn = false)
74+
{
75+
var fieldData = FieldType.Split('|');
76+
77+
var targetAssemblyFile = Path.Combine(PatcherForm.MainForm.CurrentProject.TargetDirectory, $"{AssemblyName.Replace(".dll", "")}_Original.dll");
78+
var targetAssembly = AssemblyDefinition.ReadAssembly(targetAssemblyFile);
79+
var target = targetAssembly.MainModule.GetType(TypeName);
80+
if (target == null)
81+
{
82+
if (warn)
83+
ShowMsg($"The type '{TypeName}' in '{AssemblyName}' to add the field '{Name}' into could not be found!", "Target type missing");
84+
85+
return false;
86+
}
87+
88+
if (target.Fields.Any(x => x.Name == Name))
89+
{
90+
if (warn)
91+
ShowMsg($"A field with the name '{Name}' already exists in the targetted class!", "Duplicate name");
92+
93+
return false;
94+
}
95+
96+
foreach (var field in PatcherForm.MainForm.CurrentProject.Manifests.Find(x => x.AssemblyName == AssemblyName).Fields.Where(x => x != this))
97+
{
98+
if (field.Name != Name) continue;
99+
100+
if (warn)
101+
ShowMsg($"A field with the name '{Name}' is already being added to the targetted class!", "Duplicate name");
102+
103+
return false;
104+
}
105+
106+
if (string.IsNullOrEmpty(FieldType)) return true;
107+
108+
var newFieldAssemblyFile = Path.Combine(PatcherForm.MainForm.CurrentProject.TargetDirectory, $"{fieldData[0].Replace(".dll", "")}.dll");
109+
var newFieldAssembly = AssemblyDefinition.ReadAssembly(newFieldAssemblyFile);
110+
var newFieldType = newFieldAssembly?.MainModule?.GetType(fieldData[1]);
111+
if (newFieldType == null)
112+
{
113+
if (warn)
114+
ShowMsg($"The type '{fieldData[1]}' in '{fieldData[0]}' to add the field '{Name}' from could not be found!", "New field type missing");
115+
116+
return false;
117+
}
118+
119+
return true;
120+
}
121+
}
122+
}

OxidePatcher/Manifest.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44

5+
using OxidePatcher.Fields;
56
using OxidePatcher.Hooks;
67
using OxidePatcher.Modifiers;
78

@@ -30,6 +31,11 @@ public class Manifest
3031
/// </summary>
3132
public List<Modifier> Modifiers { get; set; }
3233

34+
/// <summary>
35+
/// Gets or sets the additional fields in this project
36+
/// </summary>
37+
public List<Field> Fields { get; set; }
38+
3339
private static string[] ValidExtensions => new[] { ".dll", ".exe" };
3440

3541
/// <summary>
@@ -40,6 +46,7 @@ public Manifest()
4046
// Fill in defaults
4147
Hooks = new List<Hook>();
4248
Modifiers = new List<Modifier>();
49+
Fields = new List<Field>();
4350
}
4451

4552
public class Converter : JsonConverter
@@ -105,6 +112,18 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
105112
manifest.Modifiers.Add(modifier);
106113
}
107114
break;
115+
case "Fields":
116+
if (reader.TokenType != JsonToken.StartArray) return null;
117+
while (reader.Read() && reader.TokenType != JsonToken.EndArray)
118+
{
119+
if (reader.TokenType != JsonToken.StartObject) return null;
120+
var field = Activator.CreateInstance(typeof(Field)) as Field;
121+
serializer.Populate(reader, field);
122+
123+
if (!Path.HasExtension(field.AssemblyName)) field.AssemblyName += ".dll";
124+
manifest.Fields.Add(field);
125+
}
126+
break;
108127
}
109128
}
110129
foreach (var hook in manifest.Hooks)
@@ -148,6 +167,9 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
148167
writer.WritePropertyName("Modifiers");
149168
serializer.Serialize(writer, manifest.Modifiers);
150169

170+
writer.WritePropertyName("Fields");
171+
serializer.Serialize(writer, manifest.Fields);
172+
151173
writer.WriteEndObject();
152174
}
153175

OxidePatcher/ModifyForm.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Mono.Cecil;
88
using Mono.Cecil.Cil;
99

10+
using OxidePatcher.Fields;
1011
using OxidePatcher.Hooks;
1112
using OxidePatcher.Patching;
1213

@@ -60,6 +61,23 @@ public ModifyForm(Modify hook, MethodDefinition method, Modify.InstructionData i
6061
SaveButton.Visible = true;
6162
}
6263

64+
public ModifyForm(Field field, string type) : this(hook: null, method: null)
65+
{
66+
Instruction = new Modify.InstructionData { Operand = type, OpType = Modify.OpType.Type };
67+
68+
opcodelabel.Visible = false;
69+
opcodes.Visible = false;
70+
71+
optypes.Items.Clear();
72+
optypes.Items.Add(Modify.OpType.Type);
73+
74+
tablepanel.RowStyles[0].Height = 0;
75+
76+
InsertBeforeButton.Visible = false;
77+
InsertAfterButton.Visible = false;
78+
SaveButton.Visible = true;
79+
}
80+
6381
protected override void OnLoad(EventArgs e)
6482
{
6583
base.OnLoad(e);

OxidePatcher/OxidePatcher.csproj

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="Deobfuscation\Deobfuscators.cs" />
7777
<Compile Include="Deobfuscation\Deobfuscator.cs" />
7878
<Compile Include="Deobfuscation\Deobfuscators\UnityCodeGuard.cs" />
79+
<Compile Include="Fields\Field.cs" />
7980
<Compile Include="Hooks\Modify.cs" />
8081
<Compile Include="Hooks\Simple.cs" />
8182
<Compile Include="Modifiers\Modifier.cs" />
@@ -108,6 +109,18 @@
108109
<Compile Include="Views\HookSettingsControl.cs">
109110
<SubType>UserControl</SubType>
110111
</Compile>
112+
<Compile Include="Views\FieldSettingsControl.cs">
113+
<SubType>UserControl</SubType>
114+
</Compile>
115+
<Compile Include="Views\FieldSettingsControl.Designer.cs">
116+
<DependentUpon>FieldSettingsControl.cs</DependentUpon>
117+
</Compile>
118+
<Compile Include="Views\FieldViewControl.cs">
119+
<SubType>UserControl</SubType>
120+
</Compile>
121+
<Compile Include="Views\FieldViewControl.Designer.cs">
122+
<DependentUpon>FieldViewControl.cs</DependentUpon>
123+
</Compile>
111124
<Compile Include="Views\ModifierViewControl.cs">
112125
<SubType>UserControl</SubType>
113126
</Compile>
@@ -192,6 +205,12 @@
192205
<EmbeddedResource Include="Views\ClassViewControl.resx">
193206
<DependentUpon>ClassViewControl.cs</DependentUpon>
194207
</EmbeddedResource>
208+
<EmbeddedResource Include="Views\FieldSettingsControl.resx">
209+
<DependentUpon>FieldSettingsControl.cs</DependentUpon>
210+
</EmbeddedResource>
211+
<EmbeddedResource Include="Views\FieldViewControl.resx">
212+
<DependentUpon>FieldViewControl.cs</DependentUpon>
213+
</EmbeddedResource>
195214
<EmbeddedResource Include="Views\ModifierViewControl.resx">
196215
<DependentUpon>ModifierViewControl.cs</DependentUpon>
197216
</EmbeddedResource>

OxidePatcher/PatchProcessForm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected override void OnLoad(EventArgs e)
3636
errors = 0;
3737

3838
foreach (var manifest in PatchProject.Manifests)
39-
progressbar.Maximum += manifest.Hooks.Count(h => h.BaseHook == null || (h.BaseHook != null && h.Flagged)) + manifest.Modifiers.Count + 2;
39+
progressbar.Maximum += manifest.Hooks.Count(h => h.BaseHook == null || (h.BaseHook != null && h.Flagged)) + manifest.Modifiers.Count + manifest.Fields.Count + 2;
4040

4141
thetask = new Task(Worker);
4242
thetask.Start();

OxidePatcher/PatcherForm.Designer.cs

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)