コード例 #1
0
ファイル: VMClientDriver.cs プロジェクト: kevinmel2000/FreeSO
 public void ServerMessage(VMNetMessage message)
 {
     lock (ServerMessages)
     {
         ServerMessages.Enqueue(message);
     }
 }
コード例 #2
0
 private void Send(VMNetClient client, VMNetMessage message)
 {
     if (OnDirectMessage != null)
     {
         OnDirectMessage(client, message);
     }
 }
コード例 #3
0
 private void Broadcast(VMNetMessage message, HashSet <VMNetClient> ignore)
 {
     if (OnTickBroadcast != null)
     {
         OnTickBroadcast(message, ignore);
     }
 }
コード例 #4
0
ファイル: FSOSandboxServer.cs プロジェクト: jwofles/ForkSO
 public void SendMessage(VMNetClient cli, VMNetMessage msg)
 {
     if (cli.NetHandle == null)
     {
         return;
     }
     ((IoSession)cli.NetHandle).Write(msg);
 }
コード例 #5
0
        private void TickBroadcast(VMNetMessage msg, HashSet <VMNetClient> ignore)
        {
            HashSet <uint> ignoreIDs = new HashSet <uint>(ignore.Select(x => x.PersistID));

            Host.Broadcast(ignoreIDs, new FSOVMTickBroadcast()
            {
                Data = msg.Data
            });
        }
コード例 #6
0
 public void SubmitMessage(uint id, VMNetMessage msg)
 {
     lock (Clients)
     {
         if (Clients.TryGetValue(id, out var cli))
         {
             cli.SubmitMessage(msg);
         }
     }
 }
コード例 #7
0
        public void HandleMessage(VMNetClient client, VMNetMessage message)
        {
            var cmd = new VMNetCommand();

            try {
                using (var reader = new BinaryReader(new MemoryStream(message.Data))) {
                    if (!cmd.TryDeserialize(reader, false))
                    {
                        return;                                     //ignore things that should never be sent to the server
                    }
                }
            }
            catch (Exception e)
            {
                //corrupt commands are currently a death sentence for the client. nothing should be corrupt over TCP except in rare cases.
                client.FatalDCMessage = "RECEIVED BAD COMMAND: " + e.ToString();
                ClientsToDC.Add(client);
                return;
            }

            if (cmd.Type == VMCommandType.SimJoin)
            {
                //note: currently avatars no longer send sim join commands, the server does when it gets the database info.
                if (SandboxBans.Contains(client.RemoteIP))
                {
                    SendGenericMessage(client, "Banned", "You have been banned from this sandbox server!");
                    ClientsToDC.Add(client);
                    return;
                }
                else if (((VMNetSimJoinCmd)cmd.Command).Version != VMNetSimJoinCmd.CurVer)
                {
                    SendGenericMessage(client, "Version Mismatch", "Your game version does not match the server's. Please update your game.");
                    ClientsToDC.Add(client);
                    return;
                }
                SendCommand(cmd.Command); //just go for it. will start the avatar retrieval process.
                return;
            }
            else if (cmd.Type == VMCommandType.RequestResync)
            {
                lock (ClientsToSync)
                {
                    //todo: throttle
                    ProblemTick = ((VMRequestResyncCmd)cmd.Command).TickID;
                    ResyncClients.Add(client); //under clientstosync lock
                }
            }
            else if (cmd.Type != VMCommandType.ChatParameters)
            {
                client.InactivityTicks = 0;
            }

            cmd.Command.ActorUID = client.PersistID;
            SendCommand(cmd.Command);
        }
コード例 #8
0
        private void JoinLotRegulator_OnTransition(string transition, object data)
        {
            GameThread.InUpdate(() =>
            {
                switch (transition)
                {
                case "UnexpectedDisconnect":
                    //todo: what if we disconnect from lot but not city? the reverse?
                    break;

                case "Disconnected":
                    Screen.CleanupLastWorld();
                    if (ReconnectLotID != 0)
                    {
                        GameThread.SetTimeout(() => {
                            if (ReconnectLotID != 0)
                            {
                                JoinLot(ReconnectLotID);
                            }
                        }, 100);
                    }
                    //destroy the currently active lot (if possible)
                    break;

                case "PartiallyConnected":
                    Screen.InitializeLot();
                    Screen.vm.MyUID = Network.MyCharacter;
                    //initialize a lot
                    break;

                case "LotCommandStream":
                    //forward the command to the VM
                    //doesn't really need to be next update... but we don't want to catch the VM in a half-init state.
                    if (data == null)
                    {
                        break;
                    }
                    VMNetMessage msg = null;
                    if (data is FSOVMTickBroadcast)
                    {
                        msg = new VMNetMessage(VMNetMessageType.BroadcastTick, ((FSOVMTickBroadcast)data).Data);
                    }
                    else
                    {
                        msg = new VMNetMessage(VMNetMessageType.Direct, ((FSOVMDirectToClient)data).Data);
                    }

                    Screen.Driver?.ServerMessage(msg);
                    break;
                }
            });
        }
コード例 #9
0
ファイル: FSOSandboxServer.cs プロジェクト: jwofles/ForkSO
        public void Broadcast(VMNetMessage msg, HashSet <VMNetClient> ignore)
        {
            List <IoSession> cliClone;

            lock (Sessions) cliClone = new List <IoSession>(Sessions);
            foreach (var s in cliClone)
            {
                if (ignore.Contains(s.GetAttribute('c')))
                {
                    continue;
                }
                s.Write(msg);
            }
        }
コード例 #10
0
        private void DirectMessage(VMNetClient target, VMNetMessage msg)
        {
            object packet = (msg.Type == VMNetMessageType.Direct) ?
                            (object)(new FSOVMDirectToClient()
            {
                Data = msg.Data
            })
                : (object)(new FSOVMTickBroadcast()
            {
                Data = msg.Data
            });

            Host.Send(target.PersistID, packet);
        }
コード例 #11
0
        private void HandleServerMessage(VMNetMessage message)
        {
            if (message.Type == VMNetMessageType.Direct)
            {
                var cmd = new VMNetCommand();
                try
                {
                    using (var reader = new BinaryReader(new MemoryStream(message.Data)))
                    {
                        cmd.Deserialize(reader);
                    }
                    cmd.Command.Execute(VMHook, VMHook.GetAvatarByPersist(cmd.Command.ActorUID));
                }
                catch (Exception e)
                {
                    CloseReason = VMCloseNetReason.NetExceptionDirect;
                    CloseString = "An exception occurred while running a direct tick from the server, so the lot connection was terminated: \n\n" + e.ToString();
                    Shutdown();
                    return;
                }
            }
            else
            {
                var tick = new VMNetTickList();
                try
                {
                    using (var reader = new BinaryReader(new MemoryStream(message.Data)))
                    {
                        tick.Deserialize(reader);
                    }
                }
                catch (Exception e)
                {
                    CloseReason = VMCloseNetReason.NetException;
                    CloseString = "An exception occurred while running a broadcast tick from the server, so the lot connection was terminated: \n\n" + e.ToString();
                    Shutdown();
                    return;
                }

                for (int i = 0; i < tick.Ticks.Count; i++)
                {
                    tick.Ticks[i].ImmediateMode = tick.ImmediateMode;
                    TickBuffer.Enqueue(tick.Ticks[i]);
                }
            }
        }
コード例 #12
0
ファイル: VMClientDriver.cs プロジェクト: kevinmel2000/FreeSO
        private void HandleServerMessage(VMNetMessage message)
        {
            if (message.Type == VMNetMessageType.Direct)
            {
                var cmd = new VMNetCommand();
                try
                {
                    using (var reader = new BinaryReader(new MemoryStream(message.Data)))
                    {
                        cmd.Deserialize(reader);
                    }
                    cmd.Command.Execute(VMHook);
                }
                catch (Exception e)
                {
                    Shutdown();
                    return;
                }
            }
            else
            {
                var tick = new VMNetTickList();
                try
                {
                    using (var reader = new BinaryReader(new MemoryStream(message.Data)))
                    {
                        tick.Deserialize(reader);
                    }
                }
                catch (Exception e)
                {
                    Shutdown();
                    return;
                }

                for (int i = 0; i < tick.Ticks.Count; i++)
                {
                    tick.Ticks[i].ImmediateMode = tick.ImmediateMode;
                    TickBuffer.Enqueue(tick.Ticks[i]);
                }
            }
        }
コード例 #13
0
        protected override bool DoDecode(IoSession session, IoBuffer buffer, IProtocolDecoderOutput output)
        {
            if (buffer.Remaining < 8)
            {
                return(false);
            }

            /**
             * We expect aries, voltron or electron packets
             */
            var startPosition = buffer.Position;

            buffer.Order = ByteOrder.LittleEndian;
            uint packetType  = buffer.GetUInt32(); //currently unused
            uint payloadSize = buffer.GetUInt32();

            if (buffer.Remaining < payloadSize)
            {
                /** Not all here yet **/
                buffer.Position = startPosition;
                return(false);
            }

            var type = (VMNetMessageType)buffer.Get();
            var data = new List <byte>();

            for (int i = 0; i < payloadSize - 1; i++)
            {
                data.Add(buffer.Get());
            }
            var packet = new VMNetMessage(type, data.ToArray());

            output.Write(packet);

            return(true);
        }
コード例 #14
0
        public void InitializeLot(string lotName, bool external)
        {
            if (lotName == "")
            {
                return;
            }
            var recording = lotName.ToLowerInvariant().EndsWith(".fsor");

            CleanupLastWorld();

            Content.Content.Get().Upgrades.LoadJSONTuning();

            if (FSOEnvironment.Enable3D)
            {
                var rc = new LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                World = rc;
            }
            else
            {
                World = new World(GameFacade.GraphicsDevice);
            }
            World.Opacity = 1;
            GameFacade.Scenes.Add(World);

            var settings = GlobalSettings.Default;
            var myState  = new VMNetAvatarPersistState()
            {
                Name         = settings.LastUser,
                DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
                BodyOutfit   = settings.DebugBody,
                HeadOutfit   = settings.DebugHead,
                PersistID    = (uint)(new Random()).Next(),
                SkinTone     = (byte)settings.DebugSkin,
                Gender       = (short)(settings.DebugGender ? 0 : 1),
                Permissions  = SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
                //CustomGUID = 0x396CD3D1,
                Budget = 1000000,
            };

            if (recording)
            {
                var stream = new FileStream(lotName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var rd     = new VMFSORDriver(stream);
                Driver = rd;
            }
            else if (external)
            {
                var cd = new VMClientDriver(ClientStateChange);
                SandCli             = new FSOSandboxClient();
                cd.OnClientCommand += (msg) => { SandCli.Write(new VMNetMessage(VMNetMessageType.Command, msg)); };
                cd.OnShutdown      += (reason) => SandCli.Disconnect();
                SandCli.OnMessage  += cd.ServerMessage;
                SandCli.Connect(lotName);
                Driver = cd;

                var dat = new MemoryStream();
                var str = new BinaryWriter(dat);
                myState.SerializeInto(str);
                var ava = new VMNetMessage(VMNetMessageType.AvatarData, dat.ToArray());
                dat.Close();
                SandCli.OnConnectComplete += () =>
                {
                    SandCli.Write(ava);
                };
            }
            else
            {
                var globalLink = new VMTSOGlobalLinkStub();
                globalLink.Database = new SimAntics.Engine.TSOGlobalLink.VMTSOStandaloneDatabase();
                var sd = new VMServerDriver(globalLink);
                SandServer = new FSOSandboxServer();

                Driver                   = sd;
                sd.OnDropClient         += SandServer.ForceDisconnect;
                sd.OnTickBroadcast      += SandServer.Broadcast;
                sd.OnDirectMessage      += SandServer.SendMessage;
                SandServer.OnConnect    += sd.ConnectClient;
                SandServer.OnDisconnect += sd.DisconnectClient;
                SandServer.OnMessage    += sd.HandleMessage;

                SandServer.Start((ushort)37564);
            }

            //Driver.OnClientCommand += VMSendCommand;
            //Driver.OnShutdown += VMShutdown;

            vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
            vm.ListenBHAVChanges();
            vm.Init();

            LotControl = new UILotControl(vm, World);
            this.AddAt(0, LotControl);

            var time    = DateTime.UtcNow;
            var tsoTime = TSOTime.FromUTC(time);

            vm.Context.Clock.Hours   = tsoTime.Item1;
            vm.Context.Clock.Minutes = tsoTime.Item2;
            if (m_ZoomLevel > 3)
            {
                World.Visible      = false;
                LotControl.Visible = false;
            }

            if (IDEHook.IDE != null)
            {
                IDEHook.IDE.StartIDE(vm);
            }

            vm.OnFullRefresh      += VMRefreshed;
            vm.OnChatEvent        += Vm_OnChatEvent;
            vm.OnEODMessage       += LotControl.EODs.OnEODMessage;
            vm.OnRequestLotSwitch += VMLotSwitch;
            vm.OnGenericVMEvent   += Vm_OnGenericVMEvent;

            if (!external && !recording)
            {
                if (!Downtown && ActiveFamily != null)
                {
                    ActiveFamily.SelectWholeFamily();
                    vm.TS1State.ActivateFamily(vm, ActiveFamily);
                }
                BlueprintReset(lotName);

                var experimentalTuning = new Common.Model.DynamicTuning(new List <Common.Model.DynTuningEntry> {
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 15, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 5, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 6, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 7, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 8, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 9, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "feature", tuning_table = 0, tuning_index = 0, value = 1
                    },                                                                                                            //ts1/tso engine animation timings (1.2x faster)
                });
                vm.ForwardCommand(new VMNetTuningCmd {
                    Tuning = experimentalTuning
                });

                vm.TSOState.PropertyCategory = 255; //11 is community
                vm.TSOState.ActivateValidator(vm);
                vm.Context.Clock.Hours = 0;
                vm.TSOState.Size      &= unchecked ((int)0xFFFF0000);
                vm.TSOState.Size      |= (10) | (3 << 8);
                vm.Context.UpdateTSOBuildableArea();

                if (vm.GetGlobalValue(11) > -1)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            vm.TSOState.Terrain.Roads[x, y] = 0xF; //crossroads everywhere
                        }
                    }
                    VMLotTerrainRestoreTools.RestoreTerrain(vm);
                }

                var myClient = new VMNetClient
                {
                    PersistID   = myState.PersistID,
                    RemoteIP    = "local",
                    AvatarState = myState
                };

                var server = (VMServerDriver)Driver;
                server.ConnectClient(myClient);

                GameFacade.Cursor.SetCursor(CursorType.Normal);
                ZoomLevel = 1;
            }
            vm.MyUID  = myState.PersistID;
            ZoomLevel = 1;
        }
コード例 #15
0
        public void InitializeLot(string lotName, bool external)
        {
            if (lotName == "")
            {
                return;
            }
            var recording = lotName.ToLowerInvariant().EndsWith(".fsor");

            CleanupLastWorld();

            if (FSOEnvironment.Enable3D)
            {
                var rc = new LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                World = rc;
            }
            else
            {
                World = new World(GameFacade.GraphicsDevice);
            }
            World.Opacity = 1;
            GameFacade.Scenes.Add(World);

            var settings = GlobalSettings.Default;
            var myState  = new VMNetAvatarPersistState()
            {
                Name         = settings.LastUser,
                DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
                BodyOutfit   = settings.DebugBody,
                HeadOutfit   = settings.DebugHead,
                PersistID    = (uint)(new Random()).Next(),
                SkinTone     = (byte)settings.DebugSkin,
                Gender       = (short)(settings.DebugGender ? 0 : 1),
                Permissions  = SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
                Budget       = 1000000,
            };

            if (recording)
            {
                var stream = new FileStream(lotName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var rd     = new VMFSORDriver(stream);
                Driver = rd;
            }
            else if (external)
            {
                var cd = new VMClientDriver(ClientStateChange);
                SandCli             = new FSOSandboxClient();
                cd.OnClientCommand += (msg) => { SandCli.Write(new VMNetMessage(VMNetMessageType.Command, msg)); };
                cd.OnShutdown      += (reason) => SandCli.Disconnect();
                SandCli.OnMessage  += cd.ServerMessage;
                SandCli.Connect(lotName);
                Driver = cd;

                var dat = new MemoryStream();
                var str = new BinaryWriter(dat);
                myState.SerializeInto(str);
                var ava = new VMNetMessage(VMNetMessageType.AvatarData, dat.ToArray());
                dat.Close();
                SandCli.OnConnectComplete += () =>
                {
                    SandCli.Write(ava);
                };
            }
            else
            {
                var globalLink = new VMTSOGlobalLinkStub();
                var sd         = new VMServerDriver(globalLink);
                SandServer = new FSOSandboxServer();

                Driver                   = sd;
                sd.OnDropClient         += SandServer.ForceDisconnect;
                sd.OnTickBroadcast      += SandServer.Broadcast;
                sd.OnDirectMessage      += SandServer.SendMessage;
                SandServer.OnConnect    += sd.ConnectClient;
                SandServer.OnDisconnect += sd.DisconnectClient;
                SandServer.OnMessage    += sd.HandleMessage;

                SandServer.Start((ushort)37564);
            }

            //Driver.OnClientCommand += VMSendCommand;
            //Driver.OnShutdown += VMShutdown;

            vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
            vm.ListenBHAVChanges();
            vm.Init();

            LotControl = new UILotControl(vm, World);
            this.AddAt(0, LotControl);

            var time    = DateTime.UtcNow;
            var tsoTime = TSOTime.FromUTC(time);

            vm.Context.Clock.Hours   = tsoTime.Item1;
            vm.Context.Clock.Minutes = tsoTime.Item2;
            if (m_ZoomLevel > 3)
            {
                World.Visible      = false;
                LotControl.Visible = false;
            }

            if (IDEHook.IDE != null)
            {
                IDEHook.IDE.StartIDE(vm);
            }

            vm.OnFullRefresh      += VMRefreshed;
            vm.OnChatEvent        += Vm_OnChatEvent;
            vm.OnEODMessage       += LotControl.EODs.OnEODMessage;
            vm.OnRequestLotSwitch += VMLotSwitch;
            vm.OnGenericVMEvent   += Vm_OnGenericVMEvent;

            if (!external && !recording)
            {
                if (!Downtown && ActiveFamily != null)
                {
                    ActiveFamily.SelectWholeFamily();
                    vm.ActivateFamily(ActiveFamily);
                }
                BlueprintReset(lotName);

                vm.TSOState.PropertyCategory = 255;
                vm.Context.Clock.Hours       = 0;
                vm.TSOState.Size             = (10) | (3 << 8);
                vm.Context.UpdateTSOBuildableArea();
                var myClient = new VMNetClient
                {
                    PersistID   = myState.PersistID,
                    RemoteIP    = "local",
                    AvatarState = myState
                };

                var server = (VMServerDriver)Driver;
                server.ConnectClient(myClient);

                GameFacade.Cursor.SetCursor(CursorType.Normal);
                ZoomLevel = 1;
            }
            vm.MyUID  = myState.PersistID;
            ZoomLevel = 1;
        }