protected void StreamReceived(NetworkingPlayer sender, BMSByte bytes) { if (TrackBandwidth) BandwidthIn += (ulong)bytes.Size; lock (tmp) { bytes.MoveStartIndex(1); readStream.Reset(); if (base.ProcessReceivedData(sender, bytes, bytes[0])) return; // TODO: Not needed after initialization readStream.SetProtocolType(Networking.ProtocolType.TCP); if (readStream.Consume(this, sender, bytes) == null) return; // Do not process player because it is processed through the listener if (readStream.identifierType == NetworkingStream.IdentifierType.Player) { if (!Connected) OnConnected(); return; } if (readStream.Ready) { // TODO: These need to be done better since there are many of them if (readStream.Bytes.Size < 22) { try { if (ObjectMapper.Compare<string>(readStream, "update")) UpdateNewPlayer(sender); if (ObjectMapper.Compare<string>(readStream, "disconnect")) { // TODO: If this eventually sends something to the player they will not exist Disconnect(sender); return; } } catch { throw new NetworkException(12, "Mal-formed defalut communication"); } } } if (ReadStream(sender, readStream) && IsServer) RelayStream(readStream); DataRead(sender, readStream); } }
private void OwningNetWorker_rawDataRead(NetworkingPlayer sender, BMSByte data) { // In this test we are just writing a string across the network string message = System.Text.Encoding.UTF8.GetString(data.byteArr, data.StartIndex(), data.Size); Debug.Log("Hello " + message); }
public override void Disconnect(NetworkingPlayer player, string reason = "") { }
public override void Write(NetworkingPlayer player, NetworkingStream stream) { throw new NetworkException(11, "This is a method planned for the future and has not been implemented yet."); }
/// <summary> /// Tells the client to change their scene to the given scene. This is often called /// after the server has changed to that scene to ensure that the server will always /// load up the scene before the client does /// </summary> /// <param name="netWorker">The current <see cref="NetWorker"/> that will be sending the message</param> /// <param name="targetPlayer">The particular player that will be receiving this message</param> /// <param name="sceneName">The name of the scene in which the client should load</param> public static void ChangeClientScene(NetWorker netWorker, NetworkingPlayer targetPlayer, string sceneName) { if (!netWorker.IsServer) throw new NetworkException("Only the server can call this method, the specified NetWorker is not a server"); BMSByte data = new BMSByte(); data.Clone(Encryptor.Encoding.GetBytes(sceneName)); data.InsertRange(0, new byte[1] { 2 }); netWorker.WriteRaw(targetPlayer, data); }
/// <summary> /// Allows the server to send a raw message to a particular player /// </summary> /// <param name="netWorker"></param> /// <param name="targetPlayer"></param> /// <param name="data"></param> public static void WriteRaw(NetWorker netWorker, NetworkingPlayer targetPlayer, BMSByte data) { data.InsertRange(0, new byte[1] { 1 }); netWorker.WriteRaw(targetPlayer, data); }
/// <summary> /// Writes a <see cref="NetworkingStream"/> to a particular <see cref="NetWorker"/> that is /// running on a particular port directly to a player (if the port is a server) /// </summary> /// <param name="port">The port that the <see cref="NetWorker"/> is listening on</param> /// <param name="player">The player that this server will be writing this message to</param> /// <param name="stream">The data stream that is to be written to the player</param> /// <exception cref="NetworkException">Thrown when there is not a <see cref="NetWorker"/> on the supplied port</exception> /// <exception cref="NetworkException">Thrown when the <see cref="NetWorker"/> on the specified port is not a server</exception> public static void Write(ushort port, NetworkingPlayer player, NetworkingStream stream) { if (!Sockets.ContainsKey(port)) throw new NetworkException("There isn't a server running using the specified port on this machine"); if (!Sockets[port].IsServer) throw new NetworkException("Writing to particular players can only be done by the server, the NetWorker on the specified port is not a server"); Sockets[port].Write(player, stream); }
/// <summary> /// Disconnects a player on a given port /// </summary> /// <param name="port">Port to disconnect from</param> /// <param name="player">Player to disconnect</param> /// <exception cref="NetworkException">Thrown when there is not a <see cref="NetWorker"/> on the supplied port</exception> /// <exception cref="NetworkException">Thrown when the <see cref="NetWorker"/> on the specified port is not a server</exception> public static void Disconnect(ushort port, NetworkingPlayer player) { if (!Sockets.ContainsKey(port)) throw new NetworkException("There isn't a server running using the specified port on this machine"); if (!Sockets[port].IsServer) throw new NetworkException("Disconnecting players can only be managed by the server, the NetWorker on the specified port is not a server"); Sockets[port].Disconnect(player); }
abstract public void Write(NetworkingPlayer player, NetworkingStream stream);
/// <summary> /// Disconnect a player on this NetWorker(Socket) /// </summary> /// <param name="player">Player to disconnect</param> public virtual void Disconnect(NetworkingPlayer player, string reason = null) { if (alreadyUpdated.Contains(player)) alreadyUpdated.Remove(player); OnPlayerDisconnected(player); }
} PlayerConnectionEvent playerDisconnectedInvoker; // Because iOS doesn't have a JIT - Multi-cast function pointer. protected void OnPlayerDisconnected(NetworkingPlayer player) { if (playerDisconnectedInvoker != null) { if (Networking.IsBareMetal) playerDisconnectedInvoker(player); else { BeardedManStudios.Network.Unity.MainThreadManager.Run(delegate() { playerDisconnectedInvoker(player); }); } } Connections--; }
protected void OnCustomDataRead(string id, NetworkingPlayer player, NetworkingStream stream) { if (customDataRead.ContainsKey(id)) customDataRead[id](player, stream); }
private void ClientDisconnected(NetworkingPlayer player) { OnPlayerDisconnected(player); Players.Remove(player); }
public override void Write(NetworkingPlayer player, NetworkingStream stream) { }
/// <summary> /// This method is called when a player connects or disconnects in order to update the player count on Arbiter /// </summary> /// <param name="player">The player that just connected or disconnected</param> private void UpdatePlayerCount(NetworkingPlayer player) { ForgeMasterServer.UpdateServer(masterServerIp, socket.Port, socket.Players.Count); }
/// <summary> /// Write to the NetWorker(Socket) with a given Update Identifier, Player, and Network Stream /// </summary> /// <param name="updateidentifier">Unique update identifier to be used</param> /// <param name="player">Player to write with</param> /// <param name="stream">Network stream being written with</param> /// <param name="reliable">If this is a reliable send</param> /// <param name="packets">Packets to send</param> public virtual void Write(uint updateidentifier, NetworkingPlayer player, NetworkingStream stream, bool reliable = false, List<BMSByte> packets = null) { }
/// <summary> /// Assign a sender to the NetworkingStream /// </summary> /// <param name="sender">The player for this NetworkingStream</param> /// <param name="targetBehavior">The owning behavior of this stream</param> public void AssignSender(NetworkingPlayer sender, SimpleNetworkedMonoBehavior targetBehavior) { Sender = sender; AssignBehavior(targetBehavior); }
public virtual void WriteRaw(NetworkingPlayer player, BMSByte data, string reliableId = "") { }
/// <summary> /// Disconnect a player on a given NetWorker(Socket) /// </summary> /// <param name="socket">NetWorker(Socket) to be disconnected from</param> /// <param name="player">The player reference to disconnect</param> /// <exception cref="NetworkException">Thrown when the <see cref="NetWorker"/> on the specified port is not a server</exception> /// <example> /// // Disconnect the first player on the primary socket /// Networking.Disconnect(Networking.PrimarySocket, Networking.PrimarySocket.Players[0]); /// </example> public static void Disconnect(NetWorker socket, NetworkingPlayer player) { if (!socket.IsServer) throw new NetworkException("Disconnecting players can only be managed by the server, the NetWorker on the specified port is not a server"); socket.Disconnect(player); }
/// <summary> /// Read the data of a player and data stream /// </summary> /// <param name="player">Player to read from</param> /// <param name="stream">Network stream being read from</param> public void DataRead(NetworkingPlayer player, NetworkingStream stream) { #if BMS_DEBUGGING_UNITY UnityEngine.Debug.Log("[NetWorker DataRead Player IP] " + (player != null ? player.Ip : string.Empty)); UnityEngine.Debug.Log("[NetWorker DataRead Player NetworkID] " + (player != null ? player.NetworkId.ToString() : string.Empty)); UnityEngine.Debug.Log("[NetWorker DataRead Stream Bytes] " + ((stream != null && stream.Bytes != null) ? stream.Bytes.Count.ToString() : string.Empty)); UnityEngine.Debug.Log("[NetWorker DataRead Stream NetworkID] " + (stream != null ? stream.NetworkId.ToString() : string.Empty)); #endif OnDataRead(player, stream); if (stream.identifierType == NetworkingStream.IdentifierType.RPC) { #if BMS_DEBUGGING_UNITY UnityEngine.Debug.Log("[NetWorker DataRead New Stream RPC]"); #endif lock (rpcMutex) { new NetworkingStreamRPC(stream); } } }
/// <summary> /// Writes a <see cref="NetworkingStream"/> to a particular <see cref="NetWorker"/> directly to a player (if the port is a server) /// </summary> /// <param name="socket">NetWorker(Socket) to write with</param> /// <param name="player">Player to be written to server</param> /// <param name="stream">The stream of data to be written</param> /// <exception cref="NetworkException">Thrown when there is not a <see cref="NetWorker"/> on the supplied port</exception> /// <exception cref="NetworkException">Thrown when the <see cref="NetWorker"/> on the specified port is not a server</exception> public static void Write(NetWorker socket, NetworkingPlayer player, NetworkingStream stream) { if (!socket.IsServer) throw new NetworkException("Writing to particular players can only be done by the server, the NetWorker on the specified port is not a server"); socket.Write(player, stream); }
protected void RelayRawStream(NetworkingPlayer sender, BMSByte bytes) { if (Networking.ControlledRaw) return; WriteRaw(bytes, false); }
/// <summary> /// TODO /// </summary> /// <param name="id">Unique identifier to be used</param> /// <param name="netWorker">The NetWorker(Socket) to write with</param> /// <param name="data">Data to send over</param> /// <param name="reliableUDP">If this be a reliable UDP</param> public static void WriteCustom(string id, NetWorker netWorker, BMSByte data, NetworkingPlayer target, bool reliableUDP = false) { if (!netWorker.IsServer) throw new NetworkException("Currently this overload of WriteCustom is only supported being called on the server."); if (netWorker is CrossPlatformUDP) { netWorker.Write(id, target, new NetworkingStream().Prepare( netWorker, NetworkingStream.IdentifierType.Custom, null, data, NetworkReceivers.Others, reliableUDP, id ), reliableUDP); } else { netWorker.Write(target, new NetworkingStream().Prepare( netWorker, NetworkingStream.IdentifierType.Custom, null, data, NetworkReceivers.Others, reliableUDP, id )); } }
protected async void UpdateNewPlayer(NetworkingPlayer player)
/// <summary> /// Tells the client to change their scene to the given scene. This is often called /// after the server has changed to that scene to ensure that the server will always /// load up the scene before the client does /// </summary> /// <param name="port">The port of the <see cref="NetWorker"/> that is to send the message</param> /// <param name="targetPlayer">The particular player that will be receiving this message</param> /// <param name="sceneName">The name of the scene in which the client should load</param> public static void ChangeClientScene(ushort port, NetworkingPlayer targetPlayer, string sceneName) { if (!Sockets.ContainsKey(port)) throw new NetworkException("There isn't a server running using the specified port on this machine"); if (!Sockets[port].IsServer) throw new NetworkException("Writing to particular players can only be done by the server, the NetWorker on the specified port is not a server"); BMSByte data = new BMSByte(); data.Clone(Encryptor.Encoding.GetBytes(sceneName)); data.InsertRange(0, new byte[1] { 2 }); Sockets[port].WriteRaw(data, false); }
protected void UpdateNewPlayer(NetworkingPlayer player) #endif { if (alreadyUpdated.Contains(player)) return; alreadyUpdated.Add(player); if (rpcBuffer.Count > 0) { foreach (KeyValuePair<ulong, List<NetworkingStream>> kv in rpcBuffer) { foreach (NetworkingStream stream in kv.Value) { Write(player, stream); } } } if (udpRpcBuffer.Count > 0) { foreach (KeyValuePair<ulong, List<KeyValuePair<uint, NetworkingStream>>> kv in udpRpcBuffer) { foreach (KeyValuePair<uint, NetworkingStream> stream in kv.Value) { Write(stream.Key, player, stream.Value, true); } } } }
/// <summary> /// Get all the new player updates /// </summary> public override void GetNewPlayerUpdates() { Me = new NetworkingPlayer(Uniqueidentifier, "127.0.0.1", null, string.Empty); BMSByte tmp = new BMSByte(); ObjectMapper.MapBytes(tmp, "update"); lock(writeMutex) { writeStream.SetProtocolType(Networking.ProtocolType.TCP); writeStream.Prepare(this, NetworkingStream.IdentifierType.None, null, tmp, NetworkReceivers.Server); Write(writeStream); } }
protected void CleanUDPRPCForPlayer(NetworkingPlayer player) { if (udpRpcBuffer.ContainsKey(player.NetworkId)) udpRpcBuffer.Remove(player.NetworkId); }
/// <summary> /// Setup the Simple Networked Monobehavior stack with a NetWorker, owner, network id, and owner id /// </summary> /// <param name="owningSocket">The NetWorker to be setup with</param> /// <param name="isOwner">If this object is the owner</param> /// <param name="networkId">The NetworkID for this Simple Networked Monobehavior</param> /// <param name="ownerId">The OwnerID for this Simple Networked Monobehavior</param> public virtual void Setup(NetWorker owningSocket, bool isOwner, ulong networkId, ulong ownerId) { if (owningSocket == null) ThrowNetworkerException(); OwningNetWorker = owningSocket; IsOwner = isOwner; OwnerId = ownerId; NetworkedId = networkId; networkedBehaviors.Add(NetworkedId, this); if (OwningNetWorker.IsServer) { foreach (NetworkingPlayer player in OwningNetWorker.Players) { if (ownerId == player.NetworkId) { OwningPlayer = player; break; } } } else if (OwningNetWorker.Me != null && ownerId == OwningNetWorker.Me.NetworkId) OwningPlayer = OwningNetWorker.Me; NetworkStart(); }
private void ReadFromNetwork(NetworkingPlayer sender, NetworkingStream stream) { ServerDeserialize(stream); }
/// <summary> /// Used for the server to call an RPC method on a NetWorker(Socket) on a particular player /// </summary> /// <param name="methodName">Method(Function) name to call</param> /// <param name="socket">The NetWorker(Socket) being used</param> /// <param name="player">The NetworkingPlayer who will execute this RPC</param> /// <param name="arguments">The RPC function parameters to be passed in</param> public void AuthoritativeRPC(string methodName, NetWorker socket, NetworkingPlayer player, bool runOnServer, params object[] arguments) { MethodInfo rpc = GetStreamRPC(methodName, NetworkReceivers.All, arguments); if (socket is CrossPlatformUDP) ((CrossPlatformUDP)socket).Write("BMS_INTERNAL_Rpc_" + methodName, player, rpcNetworkingStream, true); else socket.Write(player, rpcNetworkingStream); if (socket.IsServer && runOnServer) { CallOnMainThread(delegate(object[] args) { rpc.Invoke(this, arguments); }); } }
/// <summary> /// Setup this NetworkedMonoBehavior with the owner of this object along with the networked ID /// </summary> /// <param name="owningSocket">The socket that owns this object</param> /// <param name="isOwner">Is this the owner of this object</param> /// <param name="networkId">Network ID of who owns it</param> /// <param name="ownerId">The network identifyer for the player who owns this object</param> public override void Setup(NetWorker owningSocket, bool isOwner, ulong networkId, ulong ownerId, bool isSceneObject = false) { base.Setup(owningSocket, isOwner, networkId, ownerId, isSceneObject); bool foundServerAuthority = false, clientPrediction = false; foreach (NetworkedMonoBehavior behavior in GetComponents<NetworkedMonoBehavior>()) { if (behavior.serverIsAuthority) { foundServerAuthority = true; clientPrediction = behavior.clientSidePrediction; break; } } if (rigidbodyRef != null) { if ((!OwningNetWorker.IsServer && foundServerAuthority && !clientPrediction) || (!IsOwner && !foundServerAuthority)) { rigidbodyRef.constraints = RigidbodyConstraints.FreezeAll; rigidbodyRef.useGravity = false; } } if (isPlayer && OwningNetWorker.IsServer) serverTargetPlayer = OwningPlayer; if (turnedOffCollider) { if ((OwningNetWorker.IsServer && foundServerAuthority) || (IsOwner && !foundServerAuthority)) { turnedOffCollider = false; colliderRef.enabled = true; } } }
/// <summary> /// To consume the data of the NetWorker with a player's data /// </summary> /// <param name="socket">The NetWorker socket to be used</param> /// <param name="sender">The player who is sending the data</param> /// <param name="message">Data that is being sent</param> /// <returns></returns> public NetworkingStream Consume(NetWorker socket, NetworkingPlayer sender, BMSByte message) { lock (networkedObjectMutex) { Sender = sender; NetworkedBehaviorId = 0; ByteReadIndex = 0; Bytes.Clone(message); FrameIndex = message[message.StartIndex() + message.Size - 1]; ProtocolType = (Networking.ProtocolType)ObjectMapper.Map <int>(this); Receivers = (NetworkReceivers)ObjectMapper.Map <int>(this); RealSenderId = ObjectMapper.Map <ulong>(this); if (ProtocolType == Networking.ProtocolType.HTTP || ProtocolType == Networking.ProtocolType.QuickUDP || ProtocolType == Networking.ProtocolType.QuickTCP) { Ready = true; return(this); } char identifier = (char)ReadByte(); // ObjectMapper.Map<char>(this); if (identifier == identifier_NONE) { identifierType = IdentifierType.None; } else if (identifier == identifier_RPC) { identifierType = IdentifierType.RPC; BufferedRPC = ReadByte() == 1; } else if (identifier == identifier_PLAYER) { identifierType = IdentifierType.Player; } else if (identifier == identifier_NETWORKED_BEHAVIOR) { identifierType = IdentifierType.NetworkedBehavior; } else if (identifier == identifier_DISCONNECT) { identifierType = IdentifierType.Disconnect; } else if (identifier == identifier_CUSTOM) { identifierType = IdentifierType.Custom; } NetworkedBehaviorId = ObjectMapper.Map <ulong>(this); NetworkedBehavior = SimpleNetworkedMonoBehavior.Locate(NetworkedBehaviorId); if (NetworkedBehaviorId > 0 && ReferenceEquals(NetworkedBehavior, null) && identifierType != IdentifierType.RPC) { return(null); } // Remove the size of ProtocolType, identifier, NetworkId, etc. Bytes.RemoveStart(ByteReadIndex); ByteReadIndex = 0; if (socket.Uniqueidentifier == 0 && !socket.IsServer && identifierType == IdentifierType.Player) { if (socket != null) { socket.AssignUniqueId(ObjectMapper.Map <ulong>(this)); Bytes.RemoveStart(sizeof(ulong)); } else { Bytes.RemoveStart(sizeof(ulong)); } if (socket != null && !socket.IsServer) { if (!socket.MasterServerFlag) { if (socket.UsingUnityEngine && ((ReferenceEquals(NetworkingManager.Instance, null) || !NetworkingManager.Instance.IsSetup || ReferenceEquals(NetworkingManager.Instance.OwningNetWorker, null)))) { NetworkingManager.setupActions.Add(socket.GetNewPlayerUpdates); } else { socket.GetNewPlayerUpdates(); } } } } ByteReadIndex = 0; if (identifierType == IdentifierType.NetworkedBehavior && !ReferenceEquals(NetworkedBehavior, null)) { if (NetworkedBehavior is NetworkedMonoBehavior) { ((NetworkedMonoBehavior)NetworkedBehavior).PrepareDeserialize(this); } else { throw new Exception("Only NetworkedMonoBehaviors can be used for serialization and deserialization across the network, object with id " + NetworkedBehavior.NetworkedId + " is not a \"NetworkedMonoBehavior\""); } } if (identifierType == IdentifierType.Custom) { Customidentifier = ObjectMapper.Map <uint>(this); Bytes.RemoveStart(sizeof(uint)); } ByteReadIndex = 0; Ready = true; if (NetworkedBehaviorId > 0 && ReferenceEquals(NetworkedBehavior, null)) { if (identifierType == IdentifierType.RPC) { SimpleNetworkedMonoBehavior.QueueRPCForInstantiate(NetworkedBehaviorId, this); SkipReplication = true; return(this); } return(null); } return(this); } }