/// <summary> /// Replace the Bytes with new bytes given a start and count /// </summary> /// <param name="bytes">Bytes to be replacing with</param> /// <param name="start">Start index</param> /// <param name="count">The amount of bytes being removed</param> public void ReplaceInsertBytes(BMSByte bytes, int start, int count) { Bytes.RemoveRange(start, count); Bytes.InsertRange(start, bytes); }
/// <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); } }
/// <summary> /// The final steps for preparing the NetworkingStream /// </summary> /// <param name="socket">The NetWorker socket to be used</param> /// <param name="identifierType">The type of Identifier it is going to prepare</param> /// <param name="behaviorNetworkId">NetworkedBehavior to use</param> /// <param name="extra">Extra parameters to prepare</param> /// <param name="receivers">Who shall be receiving this NetworkingStream</param> /// <param name="bufferedRPC">To know if this is a Buffered RPC</param> /// <param name="customidentifier">A custom Identifier to be passed through</param> /// <returns></returns> public NetworkingStream PrepareFinal(NetWorker socket, IdentifierType identifierType, ulong behaviorNetworkId, BMSByte extra = null, NetworkReceivers receivers = NetworkReceivers.All, bool bufferedRPC = false, uint customidentifier = 0, ulong senderId = 0) { lock (networkedObjectMutex) { if (senderId == 0) { senderId = socket.Me != null ? socket.Me.NetworkId : 0; } NetworkedBehaviorId = behaviorNetworkId; RealSenderId = senderId; Receivers = receivers; Customidentifier = customidentifier; BufferedRPC = Receivers == NetworkReceivers.AllBuffered || Receivers == NetworkReceivers.OthersBuffered; Bytes.Clear(); ObjectMapper.MapBytes(bytes, (int)ProtocolType); ObjectMapper.MapBytes(bytes, (int)receivers); ObjectMapper.MapBytes(bytes, socket.Uniqueidentifier); if (ProtocolType != Networking.ProtocolType.HTTP && ProtocolType != Networking.ProtocolType.QuickUDP && ProtocolType != Networking.ProtocolType.QuickTCP) { this.identifierType = identifierType; if (identifierType == IdentifierType.None) { Bytes.BlockCopy <byte>(((byte)identifier_NONE), 1); } else if (identifierType == IdentifierType.RPC) { Bytes.BlockCopy <byte>(((byte)identifier_RPC), 1); Bytes.BlockCopy <byte>(((byte)(bufferedRPC ? 1 : 0)), 1); } else if (identifierType == IdentifierType.Player) { Bytes.BlockCopy <byte>(((byte)identifier_PLAYER), 1); } else if (identifierType == IdentifierType.NetworkedBehavior) { Bytes.BlockCopy <byte>(((byte)identifier_NETWORKED_BEHAVIOR), 1); } else if (identifierType == IdentifierType.Disconnect) { Bytes.BlockCopy <byte>(((byte)identifier_DISCONNECT), 1); } else if (identifierType == IdentifierType.Custom) { Bytes.BlockCopy <byte>(((byte)identifier_CUSTOM), 1); } ObjectMapper.MapBytes(bytes, behaviorNetworkId); } if (identifierType == IdentifierType.Custom) { ObjectMapper.MapBytes(bytes, Customidentifier); } if (extra != null) { Bytes.BlockCopy(extra.byteArr, extra.StartIndex(), extra.Size); } if (!ReferenceEquals(NetworkingManager.Instance, null)) { ObjectMapper.MapBytes(Bytes, NetworkingManager.Instance.CurrentFrame); } else { ObjectMapper.MapBytes(Bytes, (byte)0); } if (ProtocolType == Networking.ProtocolType.TCP) { List <byte> head = new List <byte>(BitConverter.GetBytes(Bytes.Size + 1)); head.Add(0); Bytes.InsertRange(0, head.ToArray()); } Ready = true; return(this); } }
/// <summary> /// Prepare the NetworkingStream to be used /// </summary> /// <param name="socket">The NetWorker socket to be used</param> /// <param name="identifierType">The type of Identifier it is going to prepare</param> /// <param name="networkedBehavior">NetworkedBehavior to use</param> /// <param name="extra">Extra parameters to prepare</param> /// <param name="receivers">Who shall be receiving this NetworkingStream</param> /// <param name="bufferedRPC">To know if this is a Buffered RPC</param> /// <param name="customidentifier">A custom Identifier to be passed through</param> /// <returns></returns> public NetworkingStream Prepare(NetWorker socket, IdentifierType identifierType, SimpleNetworkedMonoBehavior networkedBehavior, BMSByte extra = null, NetworkReceivers receivers = NetworkReceivers.All, bool bufferedRPC = false, uint customidentifier = 0, ulong senderId = 0) { if (ReferenceEquals(networkedBehavior, null) && (extra == null || extra.Size == 0)) { throw new NetworkException(9, "Prepare was called but nothing was sent to write"); } NetworkedBehaviorId = 0; lock (networkedObjectMutex) { NetworkedBehavior = networkedBehavior; } return(PrepareFinal(socket, identifierType, !ReferenceEquals(NetworkedBehavior, null) ? NetworkedBehavior.NetworkedId : 0, extra, receivers, bufferedRPC, customidentifier, senderId)); }
/// <summary> /// Constructor of the NetworkingStream with a given protocol type /// </summary> /// <param name="protocolType">The type of protocol being usedo n this networking stream</param> public NetworkingStream(Networking.ProtocolType protocolType) { Bytes = new BMSByte(); this.ProtocolType = protocolType; }
/// <summary> /// Get a byte[] out of a Networking Stream /// </summary> /// <param name="args">Arguments passed through to get mapped</param> /// <returns>A byte[] of the mapped arguments</returns> public static BMSByte MapBytes(BMSByte bytes, params object[] args) { foreach (object o in args) { #if UNITY_EDITOR if (o == null) { throw new NetworkException("You are trying to serialize a null object, null objects have no dimentions and can not be mapped across the network"); } #endif Type type = o.GetType(); if (type == typeof(string)) { var strBytes = Encoding.UTF8.GetBytes((string)o); // TODO: Need to make custom string serialization to binary bytes.Append(BitConverter.GetBytes(strBytes.Length)); if (strBytes.Length > 0) { bytes.Append(strBytes); } } else if (type == typeof(sbyte)) { bytes.BlockCopy <sbyte>(o, 1); } else if (type == typeof(byte)) { bytes.BlockCopy <byte>(o, 1); } else if (type == typeof(char)) { bytes.BlockCopy <char>(o, 1); } else if (type == typeof(bool)) { bytes.Append(BitConverter.GetBytes((bool)o)); } else if (type == typeof(short)) { bytes.Append(BitConverter.GetBytes((short)o)); } else if (type == typeof(ushort)) { bytes.Append(BitConverter.GetBytes((ushort)o)); } else if (type == typeof(int)) { bytes.Append(BitConverter.GetBytes((int)o)); } else if (type == typeof(uint)) { bytes.Append(BitConverter.GetBytes((uint)o)); } else if (type == typeof(long)) { bytes.Append(BitConverter.GetBytes((long)o)); } else if (type == typeof(ulong)) { bytes.Append(BitConverter.GetBytes((ulong)o)); } else if (type == typeof(float)) { bytes.Append(BitConverter.GetBytes((float)o)); } else if (type == typeof(double)) { bytes.Append(BitConverter.GetBytes((double)o)); } else if (type == typeof(Vector2)) { bytes.Append(BitConverter.GetBytes(((Vector2)o).x)); bytes.Append(BitConverter.GetBytes(((Vector2)o).y)); } else if (type == typeof(Vector3)) { bytes.Append(BitConverter.GetBytes(((Vector3)o).x)); bytes.Append(BitConverter.GetBytes(((Vector3)o).y)); bytes.Append(BitConverter.GetBytes(((Vector3)o).z)); } else if (type == typeof(Vector4)) { bytes.Append(BitConverter.GetBytes(((Vector4)o).x)); bytes.Append(BitConverter.GetBytes(((Vector4)o).y)); bytes.Append(BitConverter.GetBytes(((Vector4)o).z)); bytes.Append(BitConverter.GetBytes(((Vector4)o).w)); } else if (type == typeof(Color)) { bytes.Append(BitConverter.GetBytes(((Color)o).r)); bytes.Append(BitConverter.GetBytes(((Color)o).g)); bytes.Append(BitConverter.GetBytes(((Color)o).b)); bytes.Append(BitConverter.GetBytes(((Color)o).a)); } else if (type == typeof(Quaternion)) { bytes.Append(BitConverter.GetBytes(((Quaternion)o).x)); bytes.Append(BitConverter.GetBytes(((Quaternion)o).y)); bytes.Append(BitConverter.GetBytes(((Quaternion)o).z)); bytes.Append(BitConverter.GetBytes(((Quaternion)o).w)); } else if (type == typeof(byte[])) { bytes.Append(BitConverter.GetBytes(((byte[])o).Length)); bytes.Append((byte[])o); } else if (type == typeof(BMSByte)) { bytes.Append(BitConverter.GetBytes(((BMSByte)o).Size)); bytes.BlockCopy(((BMSByte)o).byteArr, ((BMSByte)o).StartIndex(), ((BMSByte)o).Size); } else { throw new NetworkException(11, "The type " + type.ToString() + " is not allowed to be sent over the network (yet)"); } } return(bytes); }