2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Reflection ;
5
+ using System . Threading . Tasks ;
5
6
using BepInEx . Unity . IL2CPP ;
6
7
using HarmonyLib ;
7
8
using InnerNet ;
10
11
namespace Reactor . Networking . Attributes ;
11
12
12
13
/// <summary>
13
- /// Automatically registers a custom <see cref="InnerNetObject"/>.
14
+ /// Ignores registering <see cref="InnerNetObject"/>.
14
15
/// </summary>
15
16
[ AttributeUsage ( AttributeTargets . Class ) ]
16
- public sealed class InnerNetObjectAttribute : Attribute
17
+ public sealed class IgnoreInnerNetObjectAttribute : Attribute
17
18
{
18
19
private static readonly HashSet < Assembly > _registeredAssemblies = new ( ) ;
19
- private static readonly HashSet < MethodInfo > _registeredMethods = new ( ) ;
20
+ private static readonly HashSet < MemberInfo > _registeredMembers = new ( ) ;
20
21
21
22
/// <summary>
22
- /// Registers all <see cref="InnerNetObject"/>s annotated with <see cref="InnerNetObjectAttribute "/> in the specified <paramref name="assembly"/>.
23
+ /// Registers all <see cref="InnerNetObject"/>s annotated with out <see cref="IgnoreInnerNetObjectAttribute "/> in the specified <paramref name="assembly"/>.
23
24
/// </summary>
24
25
/// <remarks>This is called automatically on plugin assemblies so you probably don't need to call this.</remarks>
25
26
/// <param name="assembly">The assembly to search.</param>
@@ -30,31 +31,41 @@ public static void Register(Assembly assembly)
30
31
31
32
foreach ( var type in assembly . GetTypes ( ) )
32
33
{
33
- var attribute = type . GetCustomAttribute < InnerNetObjectAttribute > ( ) ;
34
+ if ( ! type . IsSubclassOf ( typeof ( InnerNetObject ) ) ) continue ;
34
35
35
- if ( attribute != null )
36
- {
37
- if ( ! type . IsSubclassOf ( typeof ( InnerNetObject ) ) )
38
- {
39
- throw new InvalidOperationException ( $ "Type { type . FullDescription ( ) } has { nameof ( InnerNetObjectAttribute ) } but doesn't extend { nameof ( InnerNetObject ) } .") ;
40
- }
36
+ var attribute = type . GetCustomAttribute < IgnoreInnerNetObjectAttribute > ( ) ;
41
37
38
+ if ( attribute == null )
39
+ {
42
40
try
43
41
{
44
- var methods = type . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static ) ;
45
-
46
- var prefabMethod = methods . FirstOrDefault ( method =>
47
- method . GetCustomAttribute < InnerNetObjectPrefabAttribute > ( ) != null &&
48
- ( method . ReturnType == typeof ( GameObject ) || method . ReturnType == typeof ( InnerNetObject ) ) &&
49
- method . IsStatic ) ;
42
+ var members = type . GetMembers ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static ) ;
50
43
51
- if ( prefabMethod != null )
44
+ var prefabMember = members . FirstOrDefault ( member =>
52
45
{
53
- _registeredMethods . Add ( prefabMethod ) ;
46
+ if ( member is MethodInfo method )
47
+ {
48
+ return method . IsStatic && ( method . ReturnType == typeof ( GameObject ) || method . ReturnType == typeof ( InnerNetObject ) || method . ReturnType == typeof ( Task < GameObject > ) || method . ReturnType == typeof ( Task < InnerNetObject > ) ) ;
49
+ }
50
+ else if ( member is FieldInfo field )
51
+ {
52
+ return field . IsStatic && ( field . FieldType == typeof ( GameObject ) || field . FieldType == typeof ( InnerNetObject ) ) ;
53
+ }
54
+ else if ( member is PropertyInfo property )
55
+ {
56
+ return property . GetMethod ? . IsStatic == true && ( property . PropertyType == typeof ( GameObject ) || property . PropertyType == typeof ( InnerNetObject ) ) ;
57
+ }
58
+
59
+ return false ;
60
+ } ) ;
61
+
62
+ if ( prefabMember != null )
63
+ {
64
+ _registeredMembers . Add ( prefabMember ) ;
54
65
}
55
66
else
56
67
{
57
- Warning ( $ "Failed to register InnerNetObject, static prefab return method not found.") ;
68
+ Warning ( $ "Failed to register InnerNetObject, static prefab return member not found.") ;
58
69
}
59
70
}
60
71
catch ( Exception ex )
@@ -65,19 +76,51 @@ public static void Register(Assembly assembly)
65
76
}
66
77
}
67
78
68
- internal static void LoadRegistered ( )
79
+ internal static async Task LoadRegisteredAsync ( )
69
80
{
70
- if ( _registeredMethods . Count > 0 ) // Increase array length by one because of beginning if check in InnerNetClient.CoHandleSpawn()
81
+ if ( _registeredMembers . Count > 0 ) // Increase array length by one because of beginning if check in InnerNetClient.CoHandleSpawn()
71
82
{
72
83
var innerNetClient = AmongUsClient . Instance ;
73
84
var list2 = innerNetClient . SpawnableObjects . ToList ( ) ;
74
85
list2 . Add ( new ( ) ) ;
75
86
innerNetClient . SpawnableObjects = list2 . ToArray ( ) ;
76
87
}
77
88
78
- foreach ( var prefabMethod in _registeredMethods )
89
+ foreach ( var prefabMember in _registeredMembers )
79
90
{
80
- var prefab = prefabMethod . Invoke ( null , null ) ;
91
+ object ? prefab = null ;
92
+
93
+ if ( prefabMember is MethodInfo method )
94
+ {
95
+ if ( method . ReturnType == typeof ( Task < GameObject > ) || method . ReturnType == typeof ( Task < InnerNetObject > ) )
96
+ {
97
+ if ( method . Invoke ( null , null ) is Task task )
98
+ {
99
+ await task . ConfigureAwait ( false ) ;
100
+
101
+ if ( method . ReturnType == typeof ( Task < GameObject > ) )
102
+ {
103
+ prefab = ( ( Task < GameObject > ) task ) . Result ;
104
+ }
105
+ else if ( method . ReturnType == typeof ( Task < InnerNetObject > ) )
106
+ {
107
+ prefab = ( ( Task < InnerNetObject > ) task ) . Result ;
108
+ }
109
+ }
110
+ }
111
+ else
112
+ {
113
+ prefab = method . Invoke ( null , null ) ;
114
+ }
115
+ }
116
+ else if ( prefabMember is FieldInfo field )
117
+ {
118
+ prefab = field . GetValue ( null ) ;
119
+ }
120
+ else if ( prefabMember is PropertyInfo property )
121
+ {
122
+ prefab = property . GetValue ( null ) ;
123
+ }
81
124
82
125
if ( prefab == null )
83
126
{
0 commit comments