public static void SerializeNetworkedGameState( BinaryWriter writer, NetworkedGameState networkedGameState, NetworkedGameState oldNetworkedGameState ) { for (var i = 0; i < networkedGameState.NetworkedComponentInfoLists.Count; i++) { var networkedComponentTypeInfo = networkedGameState.NetworkedComponentTypeInfos[i]; var componentInfos = networkedGameState.NetworkedComponentInfoLists[i]; var oldComponentInfos = oldNetworkedGameState.NetworkedComponentInfoLists[i]; Serialize(writer, componentInfos, (binaryWriter, componentInfo, index) => { var componentStateId = NetLib.GetIdFromState(networkedComponentTypeInfo, componentInfo.ComponentState); binaryWriter.Write(componentStateId); var oldComponentInfoIndex = oldComponentInfos .FindIndex(oci => NetLib.GetIdFromState(networkedComponentTypeInfo, oci.ComponentState) == componentStateId ); var oldComponentState = (oldComponentInfoIndex >= 0) ? oldComponentInfos[oldComponentInfoIndex].ComponentState : null; var changeMask = GetChangeMask(networkedComponentTypeInfo, componentInfo.ComponentState, oldComponentState); binaryWriter.Write(changeMask); SerializeGivenChangeMask( binaryWriter, networkedComponentTypeInfo, componentInfo.ComponentState, changeMask ); }); } }
private void OnReceiveGameState(NetworkedGameState receivedGameState) { if (!ShouldApplyStateSnapshots) { return; } if (OsFps.Instance.IsRemoteClient) { Profiler.BeginSample("Client Get Current Networked Game State"); var oldComponentInfoLists = NetLib.GetComponentInfosToSynchronize( receivedGameState.NetworkedComponentTypeInfos ); Profiler.EndSample(); Profiler.BeginSample("Client Apply Networked Game State"); for (var i = 0; i < receivedGameState.NetworkedComponentInfoLists.Count; i++) { var componentInfos = receivedGameState.NetworkedComponentInfoLists[i]; var networkedComponentTypeInfo = receivedGameState.NetworkedComponentTypeInfos[i]; var componentType = networkedComponentTypeInfo.StateType; var oldComponentInfos = oldComponentInfoLists[i]; NetLib.ApplyState( networkedComponentTypeInfo, oldComponentInfos, componentInfos, createGameObjectFromState ); } Profiler.EndSample(); } }
private void LogReceivedStateDelta(NetworkedGameState networkedGameState) { OsFps.Logger.Log(networkedGameState.SequenceNumber); for (var i = 0; i < networkedGameState.NetworkedComponentTypeInfos.Count; i++) { var networkedComponentTypeInfo = networkedGameState.NetworkedComponentTypeInfos[i]; var networkedComponentInfos = networkedGameState.NetworkedComponentInfoLists[i]; foreach (var componentInfo in networkedComponentInfos) { var synchronizedFieldNames = BitUtilities.GetSetBitIndices(componentInfo.ChangeMask) .Select(bitIndex => { if (bitIndex >= networkedComponentTypeInfo.ThingsToSynchronize.Count) { return(null); } var thingToSynchronize = networkedComponentTypeInfo.ThingsToSynchronize[bitIndex]; var thingName = (thingToSynchronize.FieldInfo != null) ? thingToSynchronize.FieldInfo.Name : thingToSynchronize.PropertyInfo.Name; return(thingName); }) .Where(x => x != null) .ToArray(); OsFps.Logger.Log(networkedComponentTypeInfo.StateType.Name + ": " + Convert.ToString(componentInfo.ChangeMask, 2) + " | " + string.Join(", ", synchronizedFieldNames)); } } }
public static NetworkedGameState DeserializeNetworkedGameState( BinaryReader reader, uint sequenceNumber, NetworkedGameState networkedGameStateRelativeTo ) { var networkedComponentTypeInfos = networkedGameStateRelativeTo.NetworkedComponentTypeInfos; var networkedComponentInfoLists = networkedComponentTypeInfos .Select((networkedComponentTypeInfo, networkedComponentTypeInfosIndex) => { var oldComponentInfos = networkedGameStateRelativeTo .NetworkedComponentInfoLists[networkedComponentTypeInfosIndex]; var componentInfos = new List <NetworkedComponentInfo>(); Deserialize(reader, componentInfos, (binaryReader, componentInfoIndex) => { var componentStateId = reader.ReadUInt32(); var oldComponentInfoIndex = oldComponentInfos .FindIndex(oci => NetLib.GetIdFromState(networkedComponentTypeInfo, oci.ComponentState) == componentStateId ); NetworkedComponentInfo oldComponentInfo; if (oldComponentInfoIndex < 0) { var stateType = networkedComponentTypeInfo.StateType; oldComponentInfo = new NetworkedComponentInfo { ComponentState = Activator.CreateInstance(stateType) }; } else { oldComponentInfo = oldComponentInfos[oldComponentInfoIndex]; oldComponentInfo = new NetworkedComponentInfo { ComponentState = ObjectExtensions.DeepCopy(oldComponentInfo.ComponentState) }; } DeserializeDelta( binaryReader, networkedComponentTypeInfo, ref oldComponentInfo ); return(oldComponentInfo); }); return(componentInfos); }) .ToList(); return(new NetworkedGameState { SequenceNumber = sequenceNumber, NetworkedComponentTypeInfos = networkedComponentTypeInfos, NetworkedComponentInfoLists = networkedComponentInfoLists }); }
public static NetworkedGameState GetCurrentNetworkedGameState(bool generateSequenceNumber) { var sequenceNumber = generateSequenceNumber ? GenerateGameStateSequenceNumber() : 0; var networkedGameState = new NetworkedGameState { SequenceNumber = sequenceNumber, NetworkedComponentTypeInfos = networkedComponentTypeInfos, NetworkedComponentInfoLists = GetComponentInfosToSynchronize(networkedComponentTypeInfos) }; return(networkedGameState); }
private void SendGameStateDiff(int connectionId, NetworkedGameState gameState, NetworkedGameState oldGameState) { byte[] messageBytes; using (var memoryStream = new MemoryStream()) { using (var writer = new BinaryWriter(memoryStream)) { writer.Write(NetLib.StateSynchronizationMessageId); writer.Write(gameState.SequenceNumber); writer.Write(oldGameState.SequenceNumber); NetworkSerializationUtils.SerializeNetworkedGameState(writer, gameState, oldGameState); } messageBytes = memoryStream.ToArray(); } SendMessageToClient(connectionId, unreliableFragmentedChannelId, messageBytes); }
public void AddGameState(NetworkedGameState gameState) { ListExtensions.AppendWithMaxLength(cachedSentGameStates, gameState, maxCachedSentGameStates); }