//============ Connections Methods ==================// /// <summary> /// Always call this from a TinyNetConnection ShowObjectToConnection, or you will have sync issues. /// </summary> /// <param name="tinyNetId">The tiny net identifier.</param> /// <param name="conn">The connection.</param> public void ShowForConnection(TinyNetIdentity tinyNetId, TinyNetConnection conn) { if (conn.isReady) { instance.SendSpawnMessage(tinyNetId, conn); } }
/// <inheritdoc /> protected override TinyNetConnection CreateTinyNetConnection(NetPeer peer) { TinyNetConnection tinyConn; if (((string)peer.Tag).Equals(TinyNetGameManager.ApplicationGUIDString)) { tinyConn = new TinyNetLocalConnectionToClient(peer); if (TinyNetLogLevel.logDev) { TinyLogger.Log("TinyNetServer::CreateTinyNetConnection created new TinyNetLocalConnectionToClient."); } } else { tinyConn = new TinyNetConnection(peer); if (TinyNetLogLevel.logDev) { TinyLogger.Log("TinyNetServer::CreateTinyNetConnection created new TinyNetConnection."); } } peer.Tag = tinyConn; tinyNetConns.Add(tinyConn); return(tinyConn); }
/// <summary> /// Send a spawn message. /// </summary> /// <param name="netIdentity">The TinyNetIdentity of the object to spawn.</param> /// <param name="targetPeer">If null, send to all connected peers.</param> public void SendSpawnMessage(TinyNetIdentity netIdentity, TinyNetConnection targetConn = null) { if (netIdentity.ServerOnly) { return; } TinyNetObjectSpawnMessage msg = new TinyNetObjectSpawnMessage(); msg.networkID = netIdentity.TinyInstanceID.NetworkID; msg.assetIndex = TinyNetGameManager.instance.GetAssetIdFromAssetGUID(netIdentity.assetGUID); msg.position = netIdentity.transform.position; msg.frameTick = ServerTick; // Include state of TinyNetObjects. s_recycleWriter.Reset(); netIdentity.TinySerialize(s_recycleWriter, true); if (s_recycleWriter.Length > 0) { msg.initialState = s_recycleWriter.CopyData(); } if (targetConn != null) { SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, targetConn); } else { SendMessageByChannelToAllConnections(msg, DeliveryMethod.ReliableOrdered); } }
/// <summary> /// [Server only] Assigns the client authority. /// </summary> /// <param name="conn">The connection.</param> /// <returns><c>false</c> on error, true otherwise.</returns> public bool AssignClientAuthority(TinyNetConnection conn) { if (!isServer) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("AssignClientAuthority can only be call on the server for spawned objects."); } return(false); } if (!_localPlayerAuthority) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("AssignClientAuthority can only be used for NetworkIdentity component with LocalPlayerAuthority set."); } return(false); } if (_connectionToOwnerClient != null && conn != _connectionToOwnerClient) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("AssignClientAuthority for " + gameObject + " already has an owner. Use RemoveClientAuthority() first."); } return(false); } if (conn == null) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("AssignClientAuthority for " + gameObject + " owner cannot be null. Use RemoveClientAuthority() instead."); } return(false); } _connectionToOwnerClient = conn; _connectionToOwnerClient.AddOwnedObject(this); // server no longer has authority (this is called on server). Note that local client could re-acquire authority below ForceAuthority(false); OnGiveAuthority(); // send msg to that client var msg = new TinyNetClientAuthorityMessage(); msg.networkID = TinyInstanceID.NetworkID; msg.authority = true; TinyNetServer.instance.SendMessageByChannelToTargetConnection(msg, LiteNetLib.DeliveryMethod.ReliableOrdered, conn); //Saishy: Still don't have an authority callback /*if (clientAuthorityCallback != null) { * clientAuthorityCallback(conn, this, true); * }*/ return(true); }
/// <summary> /// Always call this from a TinyNetConnection RemoveFromVisList, or you will have sync issues. /// </summary> /// <param name="tinyNetId">The tiny net identifier.</param> /// <param name="conn">The connection.</param> public void HideForConnection(TinyNetIdentity tinyNetId, TinyNetConnection conn) { TinyNetObjectHideMessage msg = new TinyNetObjectHideMessage(); msg.networkID = tinyNetId.TinyInstanceID.NetworkID; SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn); }
//============ TinyNetEvents ========================// /// <inheritdoc /> protected override void OnConnectionCreated(TinyNetConnection nConn) { base.OnConnectionCreated(nConn); TinyNetEmptyMessage msg = new TinyNetEmptyMessage(); msg.msgType = TinyNetMsgType.Connect; nConn.Send(msg, DeliveryMethod.ReliableOrdered); }
/// <summary> /// Creates a player controller and adds it to the connection. /// </summary> /// <param name="conn">The connection.</param> /// <param name="playerControllerId">The player controller identifier.</param> protected virtual void CreatePlayerAndAdd(TinyNetConnection conn, int playerControllerId) { if (createPlayerAction != null) { createPlayerAction(conn, playerControllerId); return; } // If no action is set, we just use default implementation conn.SetPlayerController <TinyNetPlayerController>(new TinyNetPlayerController((short)playerControllerId, conn)); }
//============ Players Methods ======================// /// <inheritdoc /> protected override void CreatePlayerAndAdd(TinyNetConnection conn, int playerControllerId) { if (TinyNetGameManager.instance.isListenServer) { conn.SetPlayerController <TinyNetPlayerController>(TinyNetServer.instance.GetPlayerControllerFromConnection(connToHost.ConnectId, (short)playerControllerId)); return; } base.CreatePlayerAndAdd(conn, playerControllerId); }
/// <summary> /// New remote peer connected to host, or client connected to remote host /// </summary> /// <param name="peer">Connected peer object</param> public virtual void OnPeerConnected(NetPeer peer) { if (TinyNetLogLevel.logDev) { TinyLogger.Log("[" + TYPE + "] We have new peer: " + peer.EndPoint + " connectId: " + peer.ConnectId); } TinyNetConnection nConn = CreateTinyNetConnection(peer); OnConnectionCreated(nConn); }
/// <summary> /// Peer disconnected /// </summary> /// <param name="peer">disconnected peer</param> /// <param name="disconnectInfo">additional info about reason, errorCode or data received with disconnect message</param> public virtual void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) { if (TinyNetLogLevel.logDev) { TinyLogger.Log("[" + TYPE + "] disconnected from: " + peer.EndPoint + " because " + disconnectInfo.Reason); } TinyNetConnection nConn = GetTinyNetConnection(peer); OnDisconnect(nConn); RemoveTinyNetConnection(nConn); }
/// <summary> /// Removes the connection. /// </summary> /// <param name="nConn">The connection.</param> /// <returns></returns> protected virtual bool RemoveTinyNetConnection(TinyNetConnection nConn) { for (int i = 0; i < tinyNetConns.Count; i++) { if (tinyNetConns[i] == nConn) { tinyNetConns.RemoveAt(i); return(true); } } return(false); }
/// <summary> /// [Server only] Removes the client authority. /// </summary> /// <param name="conn">The connection.</param> /// <returns><c>false</c> on error, true otherwise.</returns> public bool RemoveClientAuthority(TinyNetConnection conn) { if (!isServer) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("RemoveClientAuthority can only be called on the server for spawned objects."); } return(false); } if (_connectionToOwnerClient == null) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("RemoveClientAuthority for " + gameObject + " has no clientAuthority owner."); } return(false); } if (_connectionToOwnerClient != conn) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("RemoveClientAuthority for " + gameObject + " has different owner."); } return(false); } _connectionToOwnerClient.RemoveOwnedObject(this); _connectionToOwnerClient = null; // server now has authority (this is only called on server) ForceAuthority(true); OnRemoveAuthority(); // send msg to that client var msg = new TinyNetClientAuthorityMessage(); msg.networkID = TinyInstanceID.NetworkID; msg.authority = false; TinyNetServer.instance.SendMessageByChannelToTargetConnection(msg, LiteNetLib.DeliveryMethod.ReliableOrdered, conn); //Saishy: Still don't have an authority callback /*if (clientAuthorityCallback != null) { * clientAuthorityCallback(conn, this, false); * }*/ return(true); }
//============ Object Networking ====================// /// <summary> /// Spawns the object with client authority. /// </summary> /// <param name="obj">The object to spawn.</param> /// <param name="conn">The connection that will own it.</param> /// <returns></returns> public bool SpawnWithClientAuthority(GameObject obj, TinyNetConnection conn) { Spawn(obj); var tni = obj.GetComponent <TinyNetIdentity>(); if (tni == null) { // spawning the object failed. return(false); } return(tni.AssignClientAuthority(conn)); }
//============ TinyNetEvents ========================// /// <inheritdoc /> protected override void OnConnectionCreated(TinyNetConnection nConn) { base.OnConnectionCreated(nConn); if (connToHost == nConn) { OnClientFinishedConnecting(); } TinyNetEmptyMessage msg = new TinyNetEmptyMessage(); msg.msgType = TinyNetMsgType.Connect; nConn.Send(msg, DeliveryMethod.ReliableOrdered); }
/// <summary> /// Sets the client as not ready. /// </summary> /// <param name="conn">The connection.</param> void SetClientNotReady(TinyNetConnection conn) { if (conn.isReady) { if (TinyNetLogLevel.logDebug) { TinyLogger.Log("PlayerNotReady " + conn); } conn.isReady = false; TinyNetNotReadyMessage msg = new TinyNetNotReadyMessage(); SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn); } }
/// <summary> /// Creates a <see cref="TinyNetConnection"/> /// </summary> /// <param name="peer">The <see cref="NetPeer"/>.</param> /// <returns></returns> protected override TinyNetConnection CreateTinyNetConnection(NetPeer peer) { TinyNetConnection tinyConn = TinyNetGameManager.instance.isListenServer ? new TinyNetLocalConnectionToServer(peer) : new TinyNetConnection(peer); /*TinyNetConnection tinyConn; * * if (TinyNetGameManager.instance.isServer && peer.OriginAppGUID.Equals(NetManager.ApplicationGUID)) { * tinyConn = new TinyNetLocalConnectionToServer(peer); * } else { * tinyConn = new TinyNetConnection(peer); * }*/ tinyNetConns.Add(tinyConn); //First connection is to host: if (tinyNetConns.Count == 1) { connToHost = tinyNetConns[0]; } return(tinyConn); }
//============ Players Methods ======================// /// <summary> /// Attempts to add a player controller to the connection. /// </summary> /// <param name="conn">The connection.</param> /// <param name="playerControllerId">The player controller identifier.</param> protected virtual void AddPlayerControllerToConnection(TinyNetConnection conn, int playerControllerId) { if (playerControllerId < 0) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("AddPlayerControllerToConnection() called with playerControllerId < 0"); } return; } if (playerControllerId < conn.playerControllers.Count && conn.playerControllers[playerControllerId].IsValid) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("There is already a player with that playerControllerId for this connection"); } return; } CreatePlayerAndAdd(conn, playerControllerId); }
/// <summary> /// Used by the server to have a shortcut in the case a client owns this object. /// <para>Not implemmented yet.</para> /// </summary> /// <param name="conn">The connection that owns this object.</param> /// <param name="newPlayerControllerId">The player controller identifier that owns this object.</param> public void SetConnectionToClient(TinyNetConnection conn, short newPlayerControllerId) { _ownerPlayerId = newPlayerControllerId; _ConnectionToOwnerClient = conn; }
//============ Server Methods =======================// /// <summary> /// Called when a client connect to the server. /// <para>Currently not implemented!</para> /// </summary> /// <param name="conn">The connection.</param> public void OnClientConnectToServer(TinyNetConnection conn) { }
//============ Players Methods ======================// //============ Event Handling =======================// /// <summary> /// Creates and returns a new <see cref="TinyNetPlayerController"/>. /// </summary> /// <param name="conn">The connection to create a player controller for.</param> /// <param name="playerControllerId">The player controller's id.</param> /// <returns>A new <see cref="TinyNetPlayerController"/>.</returns> public virtual TinyNetPlayerController CreatePlayerController(TinyNetConnection conn, int playerControllerId) { return(new TinyNetPlayerController((short)playerControllerId, conn)); }
/// <summary> /// Sends the message by a specific channel to target connection. /// </summary> /// <param name="msg">The message.</param> /// <param name="sendOptions">The send options.</param> /// <param name="tinyNetConn">The connection.</param> public virtual void SendMessageByChannelToTargetConnection(ITinyNetMessage msg, DeliveryMethod sendOptions, TinyNetConnection tinyNetConn) { recycleWriter.Reset(); recycleWriter.Put(msg.msgType); msg.Serialize(recycleWriter); tinyNetConn.Send(recycleWriter, sendOptions); }
//============ TinyNetEvents ========================// /// <summary> /// Called after a peer has connected and a TinyNetConnection was created for it. /// </summary> /// <param name="nConn">The connection created.</param> protected virtual void OnConnectionCreated(TinyNetConnection nConn) { }
/// <summary> /// Called after a peer has been disconnected but before the TinyNetConnection has been removed from the list. /// </summary> /// <param name="nConn">The connection that disconnected.</param> protected virtual void OnDisconnect(TinyNetConnection nConn) { }
/// <summary> /// Removes a player controller from connection. /// </summary> /// <param name="conn">The connection.</param> /// <param name="playerControllerId">The player controller identifier.</param> protected virtual void RemovePlayerControllerFromConnection(TinyNetConnection conn, short playerControllerId) { conn.RemovePlayerController(playerControllerId); }
/*public TinyNetPlayerController(GameObject go, short playerControllerId) { * gameObject = go; * tinyNetId = go.GetComponent<TinyNetIdentity>(); * * this.playerControllerId = playerControllerId; * }*/ /// <summary> /// Initializes a new instance of the <see cref="TinyNetPlayerController"/> class. /// </summary> /// <param name="playerControllerId">The player controller identifier.</param> /// <param name="nConn">The <see cref="TinyNetConnection"/>.</param> public TinyNetPlayerController(short playerControllerId, TinyNetConnection nConn) : this() { this.playerControllerId = playerControllerId; this.conn = nConn; }
//============ Clients Functions ====================// /// <summary> /// Sets the client as ready. /// </summary> /// <param name="conn">The connection.</param> void SetClientReady(TinyNetConnection conn) { if (TinyNetLogLevel.logDebug) { TinyLogger.Log("SetClientReady for conn:" + conn.ConnectId); } if (conn.isReady) { if (TinyNetLogLevel.logDebug) { TinyLogger.Log("SetClientReady conn " + conn.ConnectId + " already ready"); } return; } if (conn.playerControllers.Count == 0) { if (TinyNetLogLevel.logDebug) { TinyLogger.LogWarning("Ready with no player object"); } } conn.isReady = true; // This is only in case this is a listen server. TinyNetLocalConnectionToClient localConnection = conn as TinyNetLocalConnectionToClient; if (localConnection != null) { if (TinyNetLogLevel.logDev) { TinyLogger.Log("NetworkServer Ready handling TinyNetLocalConnectionToClient"); } // Setup spawned objects for local player // Only handle the local objects for the first player (no need to redo it when doing more local players) // and don't handle player objects here, they were done above foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values) { // Need to call OnStartClient directly here, as it's already been added to the local object dictionary // in the above SetLocalPlayer call if (tinyNetId != null && tinyNetId.gameObject != null) { if (!tinyNetId.isClient) { localConnection.ShowObjectToConnection(tinyNetId); if (TinyNetLogLevel.logDev) { TinyLogger.Log("LocalClient.SetSpawnObject calling OnStartClient"); } tinyNetId.OnStartClient(); } } } return; } // Spawn/update all current server objects if (TinyNetLogLevel.logDebug) { TinyLogger.Log("Spawning " + LocalIdentityObjects.Count + " objects for conn " + conn.ConnectId); } TinyNetObjectSpawnFinishedMessage msg = new TinyNetObjectSpawnFinishedMessage(); msg.state = 0; //State 0 means we are starting the spawn messages 'spam'. SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn); foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values) { if (tinyNetId == null) { if (TinyNetLogLevel.logWarn) { TinyLogger.LogWarning("Invalid object found in server local object list (null TinyNetIdentity)."); } continue; } if (!tinyNetId.gameObject.activeSelf) { continue; } if (TinyNetLogLevel.logDebug) { TinyLogger.Log("Sending spawn message for current server objects name='" + tinyNetId.gameObject.name + "' netId=" + tinyNetId.TinyInstanceID); } conn.ShowObjectToConnection(tinyNetId); } if (TinyNetLogLevel.logDebug) { TinyLogger.Log("Spawning objects for conn " + conn.ConnectId + " finished"); } msg.state = 1; //We finished spamming the spawn messages! SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn); }
/// <summary> /// Creates a player controller and adds it to the connection. /// </summary> /// <param name="conn">The connection.</param> /// <param name="playerControllerId">The player controller identifier.</param> protected virtual void CreatePlayerAndAdd(TinyNetConnection conn, int playerControllerId) { conn.SetPlayerController <TinyNetPlayerController>(TinyNetGameManager.instance.CreatePlayerController(conn, playerControllerId)); }