private void SendState(VM vm) { if (ClientsToSync.Count == 0) { return; } var watch = new Stopwatch(); watch.Start(); var state = vm.Save(); var statecmd = new VMStateSyncCmd { State = state }; #if VM_DESYNC_DEBUG statecmd.Trace = vm.Trace.GetTick(ProblemTick); #endif var cmd = new VMNetCommand(statecmd); //currently just hack this on the tick system. might switch later var ticks = new VMNetTickList { Ticks = new List <VMNetTick> { new VMNetTick { Commands = new List <VMNetCommand> { cmd }, RandomSeed = 0, //will be restored by client from cmd TickID = TickID } } }; byte[] data; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } data = stream.ToArray(); } foreach (var client in ClientsToSync) { Send(client, new VMNetMessage(VMNetMessageType.BroadcastTick, data)); } ClientsToSync.Clear(); watch.Stop(); }
private void SendState(VM vm) { if (ResyncClients.Count != 0 && LastSync == null && !SyncSerializing) { //only add resync clients when we can give them a (near) clean sync. if (TickID - LastDesyncTick > DESYNC_LOOP_FREQ) { LastDesyncPcts.Clear(); } LastDesyncTick = TickID; LastDesyncPcts.Add(ResyncClients.Count / (float)vm.Context.ObjectQueries.AvatarsByPersist.Count); foreach (var cli in ResyncClients) //under clientstosync lock { ClientsToSync.Add(cli); } ResyncClients.Clear(); } if (ClientsToSync.Count == 0) { return; } if (LastSync == null && !SyncSerializing) { SyncSerializing = true; TicksSinceSync = new List <byte[]>(); //start saving a history. var state = vm.Save(); //must be saved on lot thread. we can serialize elsewhere tho. var statecmd = new VMStateSyncCmd { State = state }; if (vm.Trace != null) { statecmd.Traces = vm.Trace.History; } var cmd = new VMNetCommand(statecmd); //currently just hack this on the tick system. might switch later var ticks = new VMNetTickList { Ticks = new List <VMNetTick> { new VMNetTick { Commands = new List <VMNetCommand> { cmd }, RandomSeed = 0, //will be restored by client from cmd TickID = TickID } } }; Task.Run(() => { byte[] data; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } data = stream.ToArray(); } LastSync = data; SyncSerializing = false; }); } else if (LastSync != null) { foreach (var client in ClientsToSync) { Send(client, new VMNetMessage(VMNetMessageType.BroadcastTick, LastSync)); foreach (var tick in TicksSinceSync) //catch this client up with what happened since the last state was created. { Send(client, new VMNetMessage(VMNetMessageType.BroadcastTick, tick)); } } ClientsToSync.Clear(); NewClients.Clear(); //note that the lock for clientstosync is valid for newclients too. //don't clear last sync and history, since it can be used again if someone wants to join soon. } //if neither of the above happen, we're waiting for the serialization to complete (in the task) }