Ejemplo n.º 1
0
        public override bool Tick(VM vm)
        {
            if (vm.SpeedMultiplier == 0)
            {
                return(true);
            }
            //try to read a new tick from the stream
            bool success = false;

            if (Reader.BaseStream.Position < Reader.BaseStream.Length - 1)
            {
                try
                {
                    var tick = new VMNetTick();
                    tick.Deserialize(Reader);
                    InternalTick(vm, tick);
                    TickID  = tick.TickID;
                    success = true;
                }
                catch
                {
                    //might be incomplete, but that shouldn't crash the program. just assume there are no more commands.
                }
            }
            if (!success)
            {
                InternalTick(vm, new VMNetTick()
                {
                    Commands = new List <VMNetCommand>(), TickID = ++TickID, RandomSeed = vm.Context.RandomSeed
                });
            }
            return(true);
        }
Ejemplo n.º 2
0
        private void SendOneOff(NetworkClient client, VMNetTick tick) //uh, this is a little silly.
        {
            var ticks = new VMNetTickList {
                Ticks = new List <VMNetTick>()
                {
                    tick
                }, ImmediateMode = true
            };

            byte[] data;
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    ticks.SerializeInto(writer);
                }

                data = stream.ToArray();
            }

            using (var stream = new PacketStream((byte)ProtocolAbstractionLibraryD.PacketType.VM_PACKET, 0))
            {
                stream.WriteHeader();
                stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED);
                stream.WriteBytes(data);
                client.Send(stream.ToArray());
            }
        }
Ejemplo n.º 3
0
        public override bool Tick(VM vm)
        {
            HandleClients();

            lock (QueuedCmds) {
                var tick = new VMNetTick();
                tick.Commands   = new List <VMNetCommand>(QueuedCmds);
                tick.TickID     = TickID++;
                tick.RandomSeed = vm.Context.RandomSeed;

                InternalTick(vm, tick);
                QueuedCmds.Clear();

                TickBuffer.Add(tick);
                if (TickBuffer.Count >= TICKS_PER_PACKET)
                {
                    lock (ClientsToSync)
                    {
                        SendTickBuffer();
                        SendState(vm);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 4
0
        protected void InternalTick(VM vm, VMNetTick tick)
        {
            if (!tick.ImmediateMode && (tick.Commands.Count == 0 || !(tick.Commands[0].Command is VMStateSyncCmd)) && vm.Context.RandomSeed != tick.RandomSeed)
            {
                if (DesyncCooldown == 0)
                {
                    System.Console.WriteLine("DESYNC - Requested state from host");
                    vm.SendCommand(new VMRequestResyncCmd());
                    DesyncCooldown = 30 * 30;
                }
                else
                {
                    System.Console.WriteLine("WARN - DESYNC - Too soon to try again!");
                }
            }

            vm.Context.RandomSeed = tick.RandomSeed;
            bool doTick = !tick.ImmediateMode;

            foreach (var cmd in tick.Commands)
            {
                if (cmd.Command is VMStateSyncCmd)
                {
                    if (LastTick + 1 != tick.TickID)
                    {
                        System.Console.WriteLine("Jump to tick " + tick.TickID);
                    }
                    doTick = false;
                }

                var caller = vm.GetAvatarByPersist(cmd.Command.ActorUID);
                cmd.Command.Execute(vm, caller);
            }
            if (tick.TickID < LastTick)
            {
                System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
            }
            else if (doTick && vm.Context.Ready)
            {
                if (tick.TickID > LastTick + 1)
                {
                    System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
                }
#if VM_DESYNC_DEBUG
                vm.Trace.NewTick(tick.TickID);
#endif
                vm.InternalTick(tick.TickID);
                if (DesyncCooldown > 0)
                {
                    DesyncCooldown--;
                }
            }
            LastTick = tick.TickID;
        }
Ejemplo n.º 5
0
        public override bool Tick(VM vm)
        {
            HandleClients();

            lock (QueuedCmds) {
                //verify the queued commands. Remove ones which fail (or defer til later)
                for (int i = 0; i < QueuedCmds.Count; i++)
                {
                    var caller = vm.GetObjectByPersist(QueuedCmds[i].Command.ActorUID);
                    if (!(caller is VMAvatar))
                    {
                        caller = null;
                    }
                    if (!QueuedCmds[i].Command.Verify(vm, (VMAvatar)caller))
                    {
                        QueuedCmds.RemoveAt(i--);
                    }
                    else if (QueuedCmds[i].Type == VMCommandType.SimJoin)
                    {
                        var cmd = (VMNetSimJoinCmd)QueuedCmds[i].Command;
                        if (cmd.Client != null)
                        {
                            lock (ClientToUID)
                            {
                                ClientToUID.Add(cmd.Client, cmd.ActorUID);
                                UIDtoClient.Add(cmd.ActorUID, cmd.Client);
                            }
                        }
                    }
                }

                var tick = new VMNetTick();
                tick.Commands   = new List <VMNetCommand>(QueuedCmds);
                tick.TickID     = TickID++;
                tick.RandomSeed = vm.Context.RandomSeed;
                QueuedCmds.Clear();
                InternalTick(vm, tick);

                TickBuffer.Add(tick);
                if (TickBuffer.Count >= TICKS_PER_PACKET)
                {
                    lock (ClientsToSync)
                    {
                        SendTickBuffer();
                        SendState(vm);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 6
0
        protected void InternalTick(VM vm, VMNetTick tick)
        {
            if (!tick.ImmediateMode && (tick.Commands.Count == 0 || !(tick.Commands[0].Command is VMStateSyncCmd)) && vm.Context.RandomSeed != tick.RandomSeed)
            {
                if (DesyncCooldown == 0)
                {
                    System.Console.WriteLine("DESYNC - Requested state from host");
                    vm.SendCommand(new VMRequestResyncCmd());
                    DesyncCooldown = 30 * 3;
                }
                else
                {
                    System.Console.WriteLine("WARN - DESYNC - Too soon to try again!");
                }
                ExceptionOnDesync = true;
            }
            vm.Context.RandomSeed = tick.RandomSeed;
            bool doTick = !tick.ImmediateMode;

            foreach (var cmd in tick.Commands)
            {
                if (cmd.Command is VMStateSyncCmd)
                {
                    doTick = false;
                }

                var caller = vm.GetObjectByPersist(cmd.Command.ActorUID);
                if (!(caller is VMAvatar))
                {
                    caller = null;
                }
                cmd.Command.Execute(vm, (VMAvatar)caller);
            }
            if (doTick && vm.Context.Ready)
            {
                vm.InternalTick();
                if (DesyncCooldown > 0)
                {
                    DesyncCooldown--;
                }
            }
        }
Ejemplo n.º 7
0
        protected void InternalTick(VM vm, VMNetTick tick)
        {
            if ((tick.Commands.Count == 0 || !(tick.Commands[0].Command is VMStateSyncCmd)) && vm.Context.RandomSeed != tick.RandomSeed)
            {
                if (DesyncCooldown == 0)
                {
                    System.Console.WriteLine("DESYNC - Requested state from host");
                    vm.SendCommand(new VMRequestResyncCmd());
                    DesyncCooldown = 30 * 3;
                }
                else
                {
                    System.Console.WriteLine("WARN - DESYNC - Too soon to try again!");
                }
                ExceptionOnDesync = true;
            }
            vm.Context.RandomSeed = tick.RandomSeed;
            bool doTick = true;

            foreach (var cmd in tick.Commands)
            {
                if (cmd.Command is VMStateSyncCmd)
                {
                    doTick = false;
                }
                cmd.Command.Execute(vm);
            }
            if (doTick)
            {
                vm.InternalTick();
            }
            if (DesyncCooldown > 0)
            {
                DesyncCooldown--;
            }
        }
Ejemplo n.º 8
0
        public override bool Tick(VM vm)
        {
            HandleClients(vm);

            //copy the queue when we can acquire a lock
            List <VMNetCommand> cmdQueue;

            lock (QueuedCmds)
            {
                cmdQueue = new List <VMNetCommand>(QueuedCmds);
                QueuedCmds.Clear();
            }

            //verify the queued commands. Remove ones which fail (or defer til later)
            for (int i = 0; i < cmdQueue.Count; i++)
            {
                var caller = vm.GetAvatarByPersist(cmdQueue[i].Command.ActorUID);
                if (!cmdQueue[i].Command.Verify(vm, caller))
                {
                    cmdQueue.RemoveAt(i--);
                }
            }

            var tick = new VMNetTick();

            tick.Commands = new List <VMNetCommand>(cmdQueue);
            tick.TickID   = TickID;
            if (vm.SpeedMultiplier > 0)
            {
                tick.TickID = TickID++;
            }
            tick.RandomSeed = vm.Context.RandomSeed;
            cmdQueue.Clear();
            InternalTick(vm, tick);

            if (LastDesyncPcts.Count == 6 && LastDesyncPcts.Average() > 0.5f)
            {
                vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Debug,
                                                   "Automatic self resync - " + LastDesyncPcts.Count + " desyncs close by with an average of " +
                                                   (LastDesyncPcts.Average() * 100) + "% affected."));
                LastDesyncPcts.Clear();
                SelfResync = true;
            }
            if (SelfResync)
            {
                SelfResync = false;
                var save = vm.Save();
                vm.Load(save);
                vm.EODHost.SelfResync();
            }

            TickBuffer.Add(tick);

            if (TickBuffer.Count >= TICKS_PER_PACKET)
            {
                lock (ClientsToSync)
                {
                    SendTickBuffer();
                    SendState(vm);
                }
            }

            return(true);
        }
Ejemplo n.º 9
0
        public bool AsyncBreak; //if

        protected void InternalTick(VM vm, VMNetTick tick)
        {
            CurrentTick = tick.TickID;
            if (CurrentTick > GreatestTick)
            {
                GreatestTick = CurrentTick;
            }
            if (!tick.ImmediateMode && (tick.Commands.Count == 0 || !(tick.Commands[0].Command is VMStateSyncCmd)) && vm.Context.RandomSeed != tick.RandomSeed)
            {
                if (DesyncCooldown == 0)
                {
                    System.Console.WriteLine("DESYNC - Requested state from host");
                    if (DesyncTick == 0)
                    {
                        DesyncTick = CurrentTick - 1;
                    }
                    vm.SendCommand(new VMRequestResyncCmd());
                    DesyncCooldown = 30 * 30;
                }
                else
                {
                    System.Console.WriteLine("WARN - DESYNC - Expected " + tick.RandomSeed + ", was at " + vm.Context.RandomSeed);
                }
            }

            if (RecordStream != null)
            {
                RecordTick(tick);
            }
            vm.Context.RandomSeed = tick.RandomSeed;
            AsyncBreak            = false;
            bool doTick = !tick.ImmediateMode;

            foreach (var cmd in tick.Commands)
            {
                if (cmd.Command is VMStateSyncCmd && ((VMStateSyncCmd)cmd.Command).Run)
                {
                    if (LastTick + 1 != tick.TickID)
                    {
                        System.Console.WriteLine("Jump to tick " + tick.TickID);
                    }
                    if (!(this is VMFSORDriver))
                    {
                        doTick = false;                          //something weird here. this can break loading from saves casually - but must not be active for resyncs.
                    }
                    //disable just for fsor playback
                }

                var caller = vm.GetAvatarByPersist(cmd.Command.ActorUID);
                Executing = cmd;
                cmd.Command.Execute(vm, caller);
                Executing = null;
                if (vm.FSOVAsyncLoading)
                {
                    tick.Commands.Remove(cmd); //don't worry about modifying an enumerated collection - we are exiting anyways.
                    AsyncBreak = true;
                    return;
                }
            }

            if (tick.TickID < LastTick)
            {
                System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
            }
            else if (doTick && vm.Context.Ready)
            {
                if (tick.TickID > LastTick + 1)
                {
                    System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
                }
                vm.Trace?.NewTick(tick.TickID);
                vm.InternalTick(tick.TickID);
                if (DesyncCooldown > 0)
                {
                    DesyncCooldown--;
                }
            }
            LastTick = tick.TickID;
        }
Ejemplo n.º 10
0
 public void RecordTick(VMNetTick tick)
 {
     tick.SerializeInto(RecordStream);
 }
Ejemplo n.º 11
0
        public override bool Tick(VM vm)
        {
            HandleClients(vm);

            //copy the queue when we can acquire a lock
            List <VMNetCommand> cmdQueue;

            lock (QueuedCmds)
            {
                cmdQueue = new List <VMNetCommand>(QueuedCmds);
                QueuedCmds.Clear();
            }

            //verify the queued commands. Remove ones which fail (or defer til later)
            for (int i = 0; i < cmdQueue.Count; i++)
            {
                var caller = vm.GetAvatarByPersist(cmdQueue[i].Command.ActorUID);
                if (!cmdQueue[i].Command.Verify(vm, caller))
                {
                    cmdQueue.RemoveAt(i--);
                }
            }

            var tick = new VMNetTick();

            tick.Commands = new List <VMNetCommand>(cmdQueue);
            if (vm.SpeedMultiplier > 0)
            {
                tick.TickID = TickID++;
            }
            tick.RandomSeed = vm.Context.RandomSeed;
            cmdQueue.Clear();
            InternalTick(vm, tick);

            TickBuffer.Add(tick);

            lock (ClientsToSyncLater)
            {
                if (LastResyncCooldown > 0)
                {
                    LastResyncCooldown--;
                }
                else if (ClientsToSyncLater.Count > 0)
                {
                    lock (ClientsToSync)
                    {
                        foreach (var client in ClientsToSyncLater)
                        {
                            ClientsToSync.Add(client);
                        }
                        ClientsToSyncLater.Clear();
                    }
                    LastResyncCooldown = CLIENT_RESYNC_COOLDOWN;
                }
            }
            if (TickBuffer.Count >= TICKS_PER_PACKET)
            {
                lock (ClientsToSync)
                {
                    SendTickBuffer();
                    SendState(vm);
                }
            }

            return(true);
        }
Ejemplo n.º 12
0
        protected void InternalTick(VM vm, VMNetTick tick)
        {
            if (!tick.ImmediateMode && (tick.Commands.Count == 0 || !(tick.Commands[0].Command is VMStateSyncCmd)) && vm.Context.RandomSeed != tick.RandomSeed)
            {
                if (DesyncCooldown == 0)
                {
                    System.Console.WriteLine("DESYNC - Requested state from host");
                    vm.SendCommand(new VMRequestResyncCmd());
                    DesyncCooldown = 30 * 30;
                }
                else
                {
                    System.Console.WriteLine("WARN - DESYNC - Too soon to try again!");
                }
            }

            if (RecordStream != null)
            {
                RecordTick(tick);
            }

            vm.Context.RandomSeed = tick.RandomSeed;
            bool doTick = !tick.ImmediateMode;

            foreach (var cmd in tick.Commands)
            {
                if (cmd.Command is VMStateSyncCmd && ((VMStateSyncCmd)cmd.Command).Run)
                {
                    if (LastTick + 1 != tick.TickID)
                    {
                        System.Console.WriteLine("Jump to tick " + tick.TickID);
                    }
                    if (!(this is VMFSORDriver))
                    {
                        doTick = false;                          //something weird here. this can break loading from saves casually - but must not be active for resyncs.
                    }
                    //disable just for fsor playback
                }

                var caller = vm.GetAvatarByPersist(cmd.Command.ActorUID);
                cmd.Command.Execute(vm, caller);
            }
            if (tick.TickID < LastTick)
            {
                System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
            }
            else if (doTick && vm.Context.Ready)
            {
                if (tick.TickID > LastTick + 1)
                {
                    System.Console.WriteLine("Tick wrong! Got " + tick.TickID + ", Missed " + ((int)tick.TickID - (LastTick + 1)));
                }
#if VM_DESYNC_DEBUG
                vm.Trace.NewTick(tick.TickID);
#endif
                vm.InternalTick(tick.TickID);
                if (DesyncCooldown > 0)
                {
                    DesyncCooldown--;
                }
            }
            LastTick = tick.TickID;
        }