示例#1
0
        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();
        }
示例#2
0
        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)
        }