@@ -25,7 +25,10 @@ var _states: Dictionary = {} #<tick, Dictionary<String, Variant>>
2525var _inputs : Dictionary = {} # <tick, Dictionary<String, Variant>>
2626var _serialized_inputs : Dictionary = {} # <tick, PackedByteArray>
2727var _serialized_states : Dictionary = {} # <tick, PackedByteArray>
28- var _serialized_inputs_to_send : Array [PackedByteArray ] = []
28+
29+ var _serialized_inputs_to_broadcast : Array [PackedByteArray ] = []
30+ var _inputs_to_broadcast : Dictionary = {}
31+
2932var _latest_state : int = - 1
3033var _earliest_input : int
3134var _sent_full_state_to_peer_ids : Array [int ] = []
@@ -210,31 +213,29 @@ func _after_tick(_delta: float, _tick: int):
210213 _inputs [_tick ] = local_input
211214
212215 if (NetworkRollback .enable_input_serialization ):
213- var serialized_current_input : PackedByteArray = PropertiesSerializer .serialize_input_properties (_auth_input_props , _tick )
216+ var serialized_current_input : PackedByteArray = PropertiesSerializer .serialize_input_properties (_auth_input_props )
214217 _serialized_inputs [_tick ] = serialized_current_input
215218
216- if (_serialized_inputs_to_send .size () == NetworkRollback .input_redundancy ):
217- _serialized_inputs_to_send .remove_at (0 )
218- _serialized_inputs_to_send .append (serialized_current_input )
219+ if (_serialized_inputs_to_broadcast .size () == NetworkRollback .input_redundancy ):
220+ _serialized_inputs_to_broadcast .remove_at (0 )
221+ _serialized_inputs_to_broadcast .append (serialized_current_input )
219222
220- if (_serialized_inputs_to_send .is_empty () == false ):
221- var merged_serialized_inputs : PackedByteArray
222- merged_serialized_inputs .resize (0 )
223- for picked_serialized_input in _serialized_inputs_to_send :
224- merged_serialized_inputs .append_array (picked_serialized_input )
225-
226- _attempt_submit_serialized_inputs (merged_serialized_inputs )
223+ # The inputs will be deserialized from the tick of the first input to be broadcasted
224+ # Since they are sorted into that order (lowest towards highest)
225+ var tick_of_first_input_to_broadcast : int = _tick - _serialized_inputs_to_broadcast .size () + 1
226+ var merged_serialized_inputs : PackedByteArray
227+ merged_serialized_inputs .resize (4 )
228+ merged_serialized_inputs .encode_u32 (0 , tick_of_first_input_to_broadcast )
229+ for picked_serialized_input in _serialized_inputs_to_broadcast :
230+ merged_serialized_inputs .append_array (picked_serialized_input )
231+
232+ _attempt_submit_serialized_inputs (merged_serialized_inputs )
227233 else :
228- # Send the last n inputs for each property
229- var inputs = {}
230- for i in range (0 , NetworkRollback .input_redundancy ):
231- var tick_input : Dictionary = _inputs .get (_tick - i , {})
232- for property in tick_input :
233- if not inputs .has (property ):
234- inputs [property ] = []
235- inputs [property ].push_back (tick_input [property ])
236-
237- _attempt_submit_raw_input (inputs )
234+ if (_inputs_to_broadcast .size () == NetworkRollback .input_redundancy ):
235+ _inputs_to_broadcast .erase (_inputs_to_broadcast .keys ().min ())
236+ _inputs_to_broadcast [_tick ] = local_input
237+
238+ _attempt_submit_raw_input (_inputs_to_broadcast )
238239
239240 history_cleanup ()
240241func history_cleanup () -> void :
@@ -327,67 +328,58 @@ func _get_history(buffer: Dictionary, tick: int) -> Dictionary:
327328@rpc ("any_peer" , "unreliable" , "call_remote" )
328329func _submit_serialized_inputs (serialized_inputs : PackedByteArray ):
329330 var sender : int = multiplayer .get_remote_sender_id ()
331+ var tick_timestamp : int = serialized_inputs .decode_u32 (0 )
330332
331- # TODO: Security check to ensure no other client sent this (when enable_input_broadcast == false), see sanitization in submit_raw_inputs
332-
333- var picked_tick : int
333+ var received_properties_deserialized : Dictionary = {}
334+
335+ var picked_tick : int = tick_timestamp
334336 var picked_input_values_size : int # The size of the serialized input containing all properties (excluding tick timestamp[0,1,2,3] and the size itself on byte[4])
335337 var picked_single_input : PackedByteArray
336- var picked_byte_index : int = 0
338+ var picked_byte_index : int = 4
337339 while (picked_byte_index < serialized_inputs .size ()):
338- picked_tick = serialized_inputs .decode_u32 (picked_byte_index )
339- picked_byte_index += 4
340340 picked_input_values_size = serialized_inputs .decode_u8 (picked_byte_index )
341341 picked_byte_index += 1
342342
343343 if (_inputs .has (picked_tick ) == false ): # New input!
344344 picked_single_input = serialized_inputs .slice (picked_byte_index , picked_byte_index + picked_input_values_size )
345- var received_properties : Dictionary
346345 if (_auth_input_props .is_empty ()):
347- received_properties = PropertiesSerializer .deserialize_input_properties (picked_single_input , _record_input_props )
346+ received_properties_deserialized [ picked_tick ] = PropertiesSerializer .deserialize_input_properties (picked_single_input , _record_input_props )
348347 else :
349- received_properties = PropertiesSerializer .deserialize_input_properties (picked_single_input , _auth_input_props )
350-
351- _earliest_input = min (_earliest_input , picked_tick )
352-
353- if (_inputs .has (picked_tick ) == false ):
354- _inputs [picked_tick ] = received_properties
355- else :
356- for picked_property_path in received_properties :
357- _inputs [picked_tick ][picked_property_path ] = received_properties [picked_property_path ]
358-
348+ received_properties_deserialized [picked_tick ] = PropertiesSerializer .deserialize_input_properties (picked_single_input , _auth_input_props )
359349
360350 picked_byte_index += picked_input_values_size
351+ picked_tick += 1
361352
362- @rpc ("any_peer" , "unreliable" , "call_remote" )
363- func _submit_raw_input (input : Dictionary , tick : int ):
353+ submit_input (received_properties_deserialized , tick_timestamp , multiplayer .get_remote_sender_id ())
354+
355+ @rpc ("any_peer" , "unreliable" , "call_local" )
356+ func _submit_raw_input (inputs : Dictionary , tick : int ):
364357 var sender : int = multiplayer .get_remote_sender_id ()
358+ submit_input (inputs , tick , sender )
365359
360+ func submit_input (inputs : Dictionary , tick : int , sender : int ):
366361 var sanitized = {}
367- for property in input :
368- var pe : PropertyEntry = _property_cache .get_entry (property )
369- var value = input [property ]
370- var input_owner : int = pe .node .get_multiplayer_authority ()
371-
372- if input_owner != sender :
373- _logger .warning ("Received input for node owned by %s from %s , sender has no authority!" \
374- % [input_owner , sender ])
375- continue
376-
377- sanitized [property ] = value
362+ for picked_tick in inputs :
363+ sanitized [picked_tick ] = {}
364+ for property in inputs [picked_tick ]:
365+ var pe : PropertyEntry = _property_cache .get_entry (property )
366+ var value = inputs [picked_tick ][property ]
367+ var input_owner : int = pe .node .get_multiplayer_authority ()
368+
369+ if input_owner != sender :
370+ _logger .warning ("Received input for node owned by %s from %s , sender has no authority!" \
371+ % [input_owner , sender ])
372+ continue
373+
374+ sanitized [picked_tick ][property ] = value
378375
379376 if sanitized .size () > 0 :
380- for property in sanitized :
381- for i in range (0 , sanitized [property ].size ()):
382- var t = tick - i
383- var old_input = _inputs .get (t , {}).get (property )
384- var new_input = sanitized [property ][i ]
385-
386- if old_input == null :
387- # We received an array of current and previous inputs, merge them into our history.
388- _inputs [t ] = _inputs .get (t , {})
389- _inputs [t ][property ] = new_input
390- _earliest_input = min (_earliest_input , t )
377+ for picked_tick in sanitized :
378+ var old_input : Dictionary = _inputs .get (picked_tick , {})
379+ if (old_input .is_empty ()): # New input! Merge it into our history
380+ _inputs [picked_tick ] = sanitized [picked_tick ]
381+ _earliest_input = min (_earliest_input , picked_tick )
382+
391383 else :
392384 _logger .warning ("Received invalid input from %s for tick %s for %s " % [sender , tick , root .name ])
393385
0 commit comments