Skip to content

Commit 6d1754c

Browse files
author
FirstGearGames
committed
4.7.0R
- Fixed NetworkTrigger/Collider incorrectly updating states during replays, resulting in collider Enter callbacks invoking unexpectedly. - Fixed PredictionRigidbody/2D pending forces conflicting with NetworkTrigger/Collider interactions. - Fixed Local States not being used as reconcile data when remote states were unavailable. - Fixed overflow vulnerability with SplitReader. - Fixed memory allocation attack via packet fragmentation in LiteNetLib (#1026). - Fixed Buffer ArgumentNullException (#1021). - Fixed NetworkCollider/Trigger callbacks sometimes invoking OnEnter incorrectly multiple times during a reconcile. - Fixed cecil errors commonly seen as xyz not imported (#1023). - Changed (break) NetworkCollider/Trigger now provides Tick as well. Callbacks must be updated to include 'uint tick'. - Changed reverted objects deinitializing during OnDisable. This change prior caused NulLReferenceExceptions for some when reloading scenes. - Improved additional sanity checks when an object becomes intialized twice without first deinitializing. - Added ObserverManager Level of Detail. This feature currently supports prediction reconciles -- improving both server and client performance and bandwidth. - Added NetworkObject.UseLevelOfDetail. - Added NetworkObject AddComponentMenu (#1022). - Added TransportManager.MaximumClientPacketSize.
1 parent bd5c118 commit 6d1754c

75 files changed

Lines changed: 2089 additions & 1297 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Assets/FishNet/CodeGenerating/Extension/MethodDefinitionExtensions.cs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,9 @@ public static List<ParameterDefinition> CreateParameters(this MethodDefinition t
111111

112112
foreach (ParameterDefinition pd in otherMd.Parameters)
113113
{
114-
session.ImportReference(pd.ParameterType.CachedResolve(session));
115114
int currentCount = thisMd.Parameters.Count;
116115
string name = pd.Name + currentCount;
117-
ParameterDefinition parameterDef = new(name, pd.Attributes, pd.ParameterType);
118-
// Set any default values.
119-
parameterDef.Constant = pd.Constant;
120-
parameterDef.IsReturnValue = pd.IsReturnValue;
121-
parameterDef.IsOut = pd.IsOut;
122-
foreach (CustomAttribute item in pd.CustomAttributes)
123-
parameterDef.CustomAttributes.Add(item);
124-
parameterDef.HasConstant = pd.HasConstant;
125-
parameterDef.HasDefault = pd.HasDefault;
116+
ParameterDefinition parameterDef = pd.CloneImported(session, thisMd, name);
126117

127118
if (parameterDef == null || thisMd.Parameters == null)
128119
{
@@ -156,17 +147,14 @@ public static MethodReference GetMethodReference(this MethodDefinition md, Codeg
156147
DeclaringType = git,
157148
CallingConvention = md.CallingConvention
158149
};
150+
159151
foreach (ParameterDefinition pd in md.Parameters)
160-
{
161-
session.ImportReference(pd.ParameterType);
162-
result.Parameters.Add(pd);
163-
}
152+
result.Parameters.Add(pd.CloneImported(session, result));
153+
164154
return result;
165155
}
166-
else
167-
{
168-
return methodRef;
169-
}
156+
157+
return methodRef;
170158
}
171159

172160
/// <summary>
@@ -206,13 +194,13 @@ public static MethodReference GetMethodReference(this MethodDefinition md, Codeg
206194

207195
public static MethodDefinition CreateCopy(this MethodDefinition copiedMd, CodegenSession session, string nameOverride = null, MethodAttributes? attributesOverride = null)
208196
{
209-
session.ImportReference(copiedMd.ReturnType);
197+
TypeReference returnType = session.ImportReference(copiedMd.ReturnType);
210198

211199
MethodAttributes attr = attributesOverride.HasValue ? attributesOverride.Value : copiedMd.Attributes;
212200
string name = nameOverride == null ? copiedMd.Name : nameOverride;
213-
MethodDefinition result = new(name, attr, copiedMd.ReturnType);
201+
MethodDefinition result = new(name, attr, returnType);
214202
foreach (GenericParameter item in copiedMd.GenericParameters)
215-
result.GenericParameters.Add(item);
203+
result.GenericParameters.Add(new(item.Name, result) { Attributes = item.Attributes });
216204

217205
result.CreateParameters(session, copiedMd);
218206
return result;

Assets/FishNet/CodeGenerating/Extension/TypeDefinitionExtensions.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ public static MethodReference GetMethodReferenceInBase(this TypeDefinition td, C
5151
ExplicitThis = baseMd.ExplicitThis
5252
};
5353
foreach (ParameterDefinition pd in baseMd.Parameters)
54-
{
55-
session.ImportReference(pd.ParameterType);
56-
baseMr.Parameters.Add(pd);
57-
}
54+
baseMr.Parameters.Add(pd.CloneImported(session, baseMr));
5855
}
5956
else
6057
{
@@ -154,19 +151,15 @@ public static MethodDefinition GetOrCreateMethodDefinition(this TypeDefinition t
154151
};
155152
md.Body.InitLocals = methodTemplate.Body.InitLocals;
156153

157-
if (copyParameters)
154+
foreach (GenericParameter item in methodTemplate.GenericParameters)
158155
{
159-
foreach (ParameterDefinition pd in methodTemplate.Parameters)
160-
{
161-
session.ImportReference(pd.ParameterType.CachedResolve(session));
162-
md.Parameters.Add(pd);
163-
}
156+
md.GenericParameters.Add(new(item.Name, md) { Attributes = item.Attributes });
164157
}
165158

166-
foreach (GenericParameter item in methodTemplate.GenericParameters)
159+
if (copyParameters)
167160
{
168-
session.ImportReference(item);
169-
md.GenericParameters.Add(item);
161+
foreach (ParameterDefinition pd in methodTemplate.Parameters)
162+
md.Parameters.Add(pd.CloneImported(session, md));
170163
}
171164

172165
td.Methods.Add(md);

Assets/FishNet/CodeGenerating/Helpers/Extension/CustomAttributeExtensions.cs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,67 @@
33

44
namespace FishNet.CodeGenerating.Helping.Extension
55
{
6-
internal static class CustomAttributeExtensions
6+
internal static class CustomAttributeExtensions
77
{
8+
private static IGenericParameterProvider GetSafeContext(CodegenSession session, IGenericParameterProvider context)
9+
{
10+
return (context != null && context.Module == session.Module) ? context : null;
11+
}
12+
13+
/// <summary>
14+
/// Clones an attribute into the current session module.
15+
/// </summary>
16+
internal static CustomAttribute CloneImported(this CustomAttribute customAttr, CodegenSession session, IGenericParameterProvider context = null)
17+
{
18+
IGenericParameterProvider safeContext = GetSafeContext(session, context);
19+
MethodReference ctor = (safeContext == null) ? session.ImportReference(customAttr.Constructor) : session.ImportReference(customAttr.Constructor, safeContext);
20+
CustomAttribute result = new(ctor);
21+
22+
foreach (CustomAttributeArgument item in customAttr.ConstructorArguments)
23+
result.ConstructorArguments.Add(item.CloneImported(session, safeContext));
24+
25+
foreach (CustomAttributeNamedArgument item in customAttr.Fields)
26+
result.Fields.Add(item.CloneImported(session, safeContext));
27+
28+
foreach (CustomAttributeNamedArgument item in customAttr.Properties)
29+
result.Properties.Add(item.CloneImported(session, safeContext));
30+
31+
return result;
32+
}
33+
34+
/// <summary>
35+
/// Clones an attribute argument into the current session module.
36+
/// </summary>
37+
internal static CustomAttributeArgument CloneImported(this CustomAttributeArgument customAttrArg, CodegenSession session, IGenericParameterProvider context = null)
38+
{
39+
IGenericParameterProvider safeContext = GetSafeContext(session, context);
40+
TypeReference typeRef = safeContext == null ? session.ImportReference(customAttrArg.Type) : session.ImportReference(customAttrArg.Type, safeContext);
41+
object value = customAttrArg.Value;
42+
43+
if (value is TypeReference tr)
44+
{
45+
value = (safeContext == null) ? session.ImportReference(tr) : session.ImportReference(tr, safeContext);
46+
}
47+
else if (value is CustomAttributeArgument[] arguments)
48+
{
49+
CustomAttributeArgument[] clonedArguments = new CustomAttributeArgument[arguments.Length];
50+
for (int i = 0; i < arguments.Length; i++)
51+
clonedArguments[i] = arguments[i].CloneImported(session, safeContext);
52+
53+
value = clonedArguments;
54+
}
55+
56+
return new(typeRef, value);
57+
}
58+
59+
/// <summary>
60+
/// Clones a named attribute argument into the current session module.
61+
/// </summary>
62+
internal static CustomAttributeNamedArgument CloneImported(this CustomAttributeNamedArgument customAttrNamedArg, CodegenSession session, IGenericParameterProvider context = null)
63+
{
64+
return new(customAttrNamedArg.Name, customAttrNamedArg.Argument.CloneImported(session, context));
65+
}
66+
867
/// <summary>
968
/// Finds a field within an attribute.
1069
/// </summary>

Assets/FishNet/CodeGenerating/Helpers/Extension/ParameterDefinitionExtensions.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ namespace FishNet.CodeGenerating.Helping.Extension
55
{
66
internal static class ParameterDefinitionExtensions
77
{
8+
private static IGenericParameterProvider GetSafeContext(CodegenSession session, IGenericParameterProvider context)
9+
{
10+
return context != null && context.Module == session.Module ? context : null;
11+
}
12+
813
/// <summary>
914
/// Returns if parameterDef is Type.
1015
/// </summary>
@@ -15,5 +20,34 @@ public static bool Is(this ParameterDefinition parameterDef, Type type)
1520
{
1621
return parameterDef.ParameterType.FullName == type.FullName;
1722
}
23+
24+
/// <summary>
25+
/// Clones a parameter into the current session module.
26+
/// </summary>
27+
public static ParameterDefinition CloneImported(this ParameterDefinition parameterDef, CodegenSession session, IGenericParameterProvider context = null, string nameOverride = null)
28+
{
29+
IGenericParameterProvider safeContext = GetSafeContext(session, context);
30+
TypeReference parameterTypeRef = safeContext == null ? session.ImportReference(parameterDef.ParameterType) : session.ImportReference(parameterDef.ParameterType, safeContext);
31+
ParameterDefinition result = new(nameOverride ?? parameterDef.Name, parameterDef.Attributes, parameterTypeRef)
32+
{
33+
Constant = parameterDef.Constant,
34+
IsReturnValue = parameterDef.IsReturnValue,
35+
IsOut = parameterDef.IsOut,
36+
IsIn = parameterDef.IsIn,
37+
IsLcid = parameterDef.IsLcid,
38+
IsOptional = parameterDef.IsOptional,
39+
HasConstant = parameterDef.HasConstant,
40+
HasDefault = parameterDef.HasDefault,
41+
HasFieldMarshal = parameterDef.HasFieldMarshal
42+
};
43+
44+
if (parameterDef.HasMarshalInfo)
45+
result.MarshalInfo = parameterDef.MarshalInfo;
46+
47+
foreach (CustomAttribute item in parameterDef.CustomAttributes)
48+
result.CustomAttributes.Add(item.CloneImported(session, safeContext));
49+
50+
return result;
51+
}
1852
}
1953
}

Assets/FishNet/CodeGenerating/Processing/Rpc/RpcProcessor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ private bool CreateClientRpcWriterMethod(List<ParameterDefinition> serializedPar
349349
ILProcessor processor = writerMd.Body.GetILProcessor();
350350
// Add all parameters from the original.
351351
for (int i = 0; i < originalMd.Parameters.Count; i++)
352-
writerMd.Parameters.Add(originalMd.Parameters[i]);
352+
writerMd.Parameters.Add(originalMd.Parameters[i].CloneImported(Session, writerMd));
353353
// Get channel if it exist, and get target parameter.
354354
ParameterDefinition channelParameterDef = GetChannelParameter(writerMd, RpcType.None);
355355

@@ -413,7 +413,7 @@ private bool CreateServerRpcWriterMethod(List<ParameterDefinition> serializedPar
413413

414414
// Add all parameters from the original.
415415
for (int i = 0; i < originalMd.Parameters.Count; i++)
416-
writerMd.Parameters.Add(originalMd.Parameters[i]);
416+
writerMd.Parameters.Add(originalMd.Parameters[i].CloneImported(Session, writerMd));
417417
// Add in channel if it doesnt exist.
418418
ParameterDefinition channelParameterDef = GetChannelParameter(writerMd, RpcType.Server);
419419

@@ -880,7 +880,7 @@ private MethodDefinition CreateRpcLogicMethod(List<AttributeData> datas, Created
880880
* that some reason is the resolution, because Unity. However, even with this fix if the
881881
* developer makes use of the generic properties of the class from the offending method
882882
* there is a fair chance the application will crash. */
883-
#if !UNITY_2022_3_OR_NEWER
883+
#if !UNITY_2022_3_OR_NEWER
884884
/* If the declaring type has a generic then we need to see if any
885885
* logic instructions call methods in another or same generic class. */
886886
ILProcessor processor = createdMd.Body.GetILProcessor();
@@ -894,7 +894,7 @@ private MethodDefinition CreateRpcLogicMethod(List<AttributeData> datas, Created
894894

895895
Instruction v = instructions[i];
896896
OpCode instrOpCode = v.OpCode;
897-
897+
898898
if (instrOpCode == OpCodes.Callvirt || instrOpCode == OpCodes.Call)
899899
{
900900
MethodDefinition calledMd = null;
@@ -919,7 +919,7 @@ private MethodDefinition CreateRpcLogicMethod(List<AttributeData> datas, Created
919919
}
920920
}
921921
}
922-
#endif
922+
#endif
923923

924924
return createdMd;
925925
}

Assets/FishNet/Demos/Prediction/CharacterController/CharacterController Prediction Demo.unity

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ MonoBehaviour:
188188
_preventDespawnOnDisconnect: 0
189189
_defaultDespawnType: 0
190190
_initializedTimestamp: 0
191+
_useLevelOfDetail: 0
192+
_useRootLevelOfDetail: 1
191193
NetworkObserver: {fileID: 0}
192194
_enablePrediction: 1
193195
_predictionType: 0
@@ -342,7 +344,7 @@ MonoBehaviour:
342344
_timingType: 0
343345
_allowTickDropping: 0
344346
_maximumFrameTicks: 2
345-
_tickRate: 60
347+
_tickRate: 10
346348
_pingInterval: 1
347349
_physicsMode: 1
348350
--- !u!114 &192429409
@@ -586,6 +588,22 @@ PrefabInstance:
586588
m_Modification:
587589
m_TransformParent: {fileID: 7443408886491487332}
588590
m_Modifications:
591+
- target: {fileID: 818862022, guid: 0570b6f7f713dc44a90463654bbcd8d0, type: 3}
592+
propertyPath: m_AnchoredPosition.x
593+
value: 155.1001
594+
objectReference: {fileID: 0}
595+
- target: {fileID: 818862022, guid: 0570b6f7f713dc44a90463654bbcd8d0, type: 3}
596+
propertyPath: m_AnchoredPosition.y
597+
value: -52.69995
598+
objectReference: {fileID: 0}
599+
- target: {fileID: 3414662637240338350, guid: 0570b6f7f713dc44a90463654bbcd8d0, type: 3}
600+
propertyPath: m_AnchoredPosition.x
601+
value: 78.1001
602+
objectReference: {fileID: 0}
603+
- target: {fileID: 3414662637240338350, guid: 0570b6f7f713dc44a90463654bbcd8d0, type: 3}
604+
propertyPath: m_AnchoredPosition.y
605+
value: -121.400024
606+
objectReference: {fileID: 0}
589607
- target: {fileID: 4393252310969058990, guid: 0570b6f7f713dc44a90463654bbcd8d0, type: 3}
590608
propertyPath: m_Pivot.x
591609
value: 0
@@ -1396,7 +1414,6 @@ MonoBehaviour:
13961414
m_Script: {fileID: 11500000, guid: 2ca42d40476d05444acd0179c78b44cc, type: 3}
13971415
m_Name:
13981416
m_EditorClassIdentifier:
1399-
_staminaBar: {fileID: 2021829093}
14001417
--- !u!1 &1977106728
14011418
GameObject:
14021419
m_ObjectHideFlags: 0
@@ -1577,6 +1594,8 @@ MonoBehaviour:
15771594
_preventDespawnOnDisconnect: 0
15781595
_defaultDespawnType: 0
15791596
_initializedTimestamp: 0
1597+
_useLevelOfDetail: 1
1598+
_useRootLevelOfDetail: 1
15801599
NetworkObserver: {fileID: 0}
15811600
_enablePrediction: 1
15821601
_predictionType: 0
@@ -1707,6 +1726,9 @@ GameObject:
17071726
- component: {fileID: 192429404}
17081727
- component: {fileID: 7443408886491487336}
17091728
- component: {fileID: 7443408886491487339}
1729+
- component: {fileID: 7443408886491487340}
1730+
- component: {fileID: 7443408886491487341}
1731+
- component: {fileID: 7443408886491487342}
17101732
m_Layer: 0
17111733
m_Name: NetworkManager
17121734
m_TagString: Untagged
@@ -1774,3 +1796,61 @@ MonoBehaviour:
17741796
_frameRate: 500
17751797
_shareIds: 1
17761798
_startOnHeadless: 1
1799+
--- !u!114 &7443408886491487340
1800+
MonoBehaviour:
1801+
m_ObjectHideFlags: 0
1802+
m_CorrespondingSourceObject: {fileID: 0}
1803+
m_PrefabInstance: {fileID: 0}
1804+
m_PrefabAsset: {fileID: 0}
1805+
m_GameObject: {fileID: 7443408886491487334}
1806+
m_Enabled: 1
1807+
m_EditorHideFlags: 0
1808+
m_Script: {fileID: 11500000, guid: 756c28cd3141c4140ae776188ee26729, type: 3}
1809+
m_Name:
1810+
m_EditorClassIdentifier:
1811+
_runInRelease: 0
1812+
_networkTraffic:
1813+
_enableMode: 1
1814+
_updateClient: 1
1815+
_updateServer: 1
1816+
--- !u!114 &7443408886491487341
1817+
MonoBehaviour:
1818+
m_ObjectHideFlags: 0
1819+
m_CorrespondingSourceObject: {fileID: 0}
1820+
m_PrefabInstance: {fileID: 0}
1821+
m_PrefabAsset: {fileID: 0}
1822+
m_GameObject: {fileID: 7443408886491487334}
1823+
m_Enabled: 1
1824+
m_EditorHideFlags: 0
1825+
m_Script: {fileID: 11500000, guid: 8bc8f0363ddc75946a958043c5e49a83, type: 3}
1826+
m_Name:
1827+
m_EditorClassIdentifier:
1828+
_runInRelease: 0
1829+
_secondsAveraged: 1
1830+
_updateInterval: 1
1831+
_color: {r: 1, g: 1, b: 1, a: 1}
1832+
_placement: 1
1833+
_showOutgoing: 1
1834+
_showIncoming: 1
1835+
--- !u!114 &7443408886491487342
1836+
MonoBehaviour:
1837+
m_ObjectHideFlags: 0
1838+
m_CorrespondingSourceObject: {fileID: 0}
1839+
m_PrefabInstance: {fileID: 0}
1840+
m_PrefabAsset: {fileID: 0}
1841+
m_GameObject: {fileID: 7443408886491487334}
1842+
m_Enabled: 1
1843+
m_EditorHideFlags: 0
1844+
m_Script: {fileID: 11500000, guid: 7d331f979d46e8e4a9fc90070c596d44, type: 3}
1845+
m_Name:
1846+
m_EditorClassIdentifier:
1847+
_updateHostVisibility: 1
1848+
_maximumTimedObserversDuration: 3
1849+
_defaultConditions: []
1850+
_useLevelOfDetail: 1
1851+
_maximumLevelOfDetailInterval: 2
1852+
_levelOfDetailUpdateDuration: 4
1853+
_levelOfDetailDistances:
1854+
- 10
1855+
- 30
1856+
- 50

0 commit comments

Comments
 (0)