public void ServerMessage(VMNetMessage message) { lock (ServerMessages) { ServerMessages.Enqueue(message); } }
private void Send(VMNetClient client, VMNetMessage message) { if (OnDirectMessage != null) { OnDirectMessage(client, message); } }
private void Broadcast(VMNetMessage message, HashSet <VMNetClient> ignore) { if (OnTickBroadcast != null) { OnTickBroadcast(message, ignore); } }
public void SendMessage(VMNetClient cli, VMNetMessage msg) { if (cli.NetHandle == null) { return; } ((IoSession)cli.NetHandle).Write(msg); }
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 }); }
public void SubmitMessage(uint id, VMNetMessage msg) { lock (Clients) { if (Clients.TryGetValue(id, out var cli)) { cli.SubmitMessage(msg); } } }
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); }
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; } }); }
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); } }
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); }
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]); } } }
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]); } } }
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); }
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; }
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; }