internal void SendSpawnMessage(NetworkIdentity identity, INetworkConnection conn) { // for easier debugging if (logger.LogEnabled()) { logger.Log("Server SendSpawnMessage: name=" + identity.name + " sceneId=" + identity.sceneId.ToString("X") + " netid=" + identity.NetId); } // one writer for owner, one for observers using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter()) { bool isOwner = identity.ConnectionToClient == conn; ArraySegment <byte> payload = CreateSpawnMessagePayload(isOwner, identity, ownerWriter, observersWriter); conn.Send(new SpawnMessage { netId = identity.NetId, isLocalPlayer = conn.Identity == identity, isOwner = isOwner, sceneId = identity.sceneId, assetId = identity.AssetId, // use local values for VR support position = identity.transform.localPosition, rotation = identity.transform.localRotation, scale = identity.transform.localScale, payload = payload, }); } }
public void Dispose() { NetworkWriterPool.Recycle(this); }
/// <summary> /// Start the server /// <para>If <paramref name="localClient"/> is given then will start in host mode</para> /// </summary> /// <param name="config">Config for <see cref="Peer"/></param> /// <param name="localClient">if not null then start the server and client in hostmode</param> // Has to be called "StartServer" to stop unity complaining about "Start" method public void StartServer(NetworkClient localClient = null) { ThrowIfActive(); ThrowIfSocketIsMissing(); Application.quitting += Stop; if (logger.LogEnabled()) { logger.Log($"NetworkServer Created, Mirage version: {Version.Current}"); } logger.Assert(Players.Count == 0, "Player should have been reset since previous session"); logger.Assert(connections.Count == 0, "Connections should have been reset since previous session"); World = new NetworkWorld(); SyncVarSender = new SyncVarSender(); LocalClient = localClient; MessageHandler = new MessageHandler(World, DisconnectOnException); MessageHandler.RegisterHandler <NetworkPingMessage>(World.Time.OnServerPing); ISocket socket = SocketFactory.CreateServerSocket(); var dataHandler = new DataHandler(MessageHandler, connections); Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null; Config config = PeerConfig; if (config == null) { config = new Config { // only use MaxConnections if config was null MaxConnections = MaxConnections, }; } NetworkWriterPool.Configure(config.MaxPacketSize); // Only create peer if listening if (Listening) { peer = new Peer(socket, dataHandler, config, LogFactory.GetLogger <Peer>(), Metrics); peer.OnConnected += Peer_OnConnected; peer.OnDisconnected += Peer_OnDisconnected; peer.Bind(SocketFactory.GetBindEndPoint()); } if (logger.LogEnabled()) { logger.Log("Server started listening"); } InitializeAuthEvents(); Active = true; _started?.Invoke(); if (LocalClient != null) { // we should call onStartHost after transport is ready to be used // this allows server methods like NetworkServer.Spawn to be called in there _onStartHost?.Invoke(); localClient.ConnectHost(this, dataHandler); if (logger.LogEnabled()) { logger.Log("NetworkServer StartHost"); } } }
internal void SendSpawnMessage(NetworkIdentity identity, INetworkPlayer player) { if (logger.LogEnabled()) { logger.Log($"Server SendSpawnMessage: name={identity.name} sceneId={identity.SceneId:X} netId={identity.NetId}"); } // one writer for owner, one for observers using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter()) { var isOwner = identity.Owner == player; var payload = CreateSpawnMessagePayload(isOwner, identity, ownerWriter, observersWriter); var prefabHash = identity.IsPrefab ? identity.PrefabHash : default(int?); var sceneId = identity.IsSceneObject ? identity.SceneId : default(ulong?); var msg = new SpawnMessage { netId = identity.NetId, isLocalPlayer = player.Identity == identity, isOwner = isOwner, sceneId = sceneId, prefabHash = prefabHash, payload = payload, }; // values in msg are nullable, so by default they are null // only set those values if the identity's settings say to send them if (identity.SpawnSettings.SendPosition) { msg.position = identity.transform.localPosition; } if (identity.SpawnSettings.SendRotation) { msg.rotation = identity.transform.localRotation; } if (identity.SpawnSettings.SendScale) { msg.scale = identity.transform.localScale; } player.Send(msg); } }
/// <summary> /// Start the server /// <para>If <paramref name="localClient"/> is given then will start in host mode</para> /// </summary> /// <param name="config">Config for <see cref="Peer"/></param> /// <param name="localClient">if not null then start the server and client in hostmode</param> // Has to be called "StartServer" to stop unity complaining about "Start" method public void StartServer(NetworkClient localClient = null) { ThrowIfActive(); ThrowIfSocketIsMissing(); Application.quitting += Stop; if (logger.LogEnabled()) { logger.Log($"NetworkServer created, Mirage version: {Version.Current}"); } logger.Assert(Players.Count == 0, "Player should have been reset since previous session"); logger.Assert(_connections.Count == 0, "Connections should have been reset since previous session"); World = new NetworkWorld(); SyncVarSender = new SyncVarSender(); LocalClient = localClient; MessageHandler = new MessageHandler(World, DisconnectOnException); MessageHandler.RegisterHandler <NetworkPingMessage>(World.Time.OnServerPing); var dataHandler = new DataHandler(MessageHandler, _connections); Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null; var config = PeerConfig; if (config == null) { config = new Config { // only use MaxConnections if config was null MaxConnections = MaxConnections, }; } var maxPacketSize = SocketFactory.MaxPacketSize; NetworkWriterPool.Configure(maxPacketSize); // Are we listening for incoming connections? // If yes, set up a socket for incoming connections (we're a multiplayer game). // If not, that's okay. Some games use a non-listening server for their single player game mode (Battlefield, Call of Duty...) if (Listening) { // Create a server specific socket. var socket = SocketFactory.CreateServerSocket(); // Tell the peer to use that newly created socket. _peer = new Peer(socket, maxPacketSize, dataHandler, config, LogFactory.GetLogger <Peer>(), Metrics); _peer.OnConnected += Peer_OnConnected; _peer.OnDisconnected += Peer_OnDisconnected; // Bind it to the endpoint. _peer.Bind(SocketFactory.GetBindEndPoint()); if (logger.LogEnabled()) { logger.Log($"Server started, listening for connections. Using socket {socket.GetType()}"); } if (RunInBackground) { Application.runInBackground = RunInBackground; } } else { // Nicely mention that we're going live, but not listening for connections. if (logger.LogEnabled()) { logger.Log("Server started, but not listening for connections: Attempts to connect to this instance will fail!"); } } InitializeAuthEvents(); Active = true; _started?.Invoke(); if (LocalClient != null) { // we should call onStartHost after transport is ready to be used // this allows server methods like NetworkServer.Spawn to be called in there _onStartHost?.Invoke(); localClient.ConnectHost(this, dataHandler); if (logger.LogEnabled()) { logger.Log("NetworkServer StartHost"); } } }