/// <summary> /// Constructor for the NetworkingStream with a passed in stream /// </summary> /// <param name="stream">The stream passed in to be used</param> public NetworkingStreamRPC(NetworkingStream stream, bool skipCall = false) { FailedExecution = false; // TODO: Check for null NetworkedBehavior or if it is the base class if (!skipCall && ReferenceEquals(stream.NetworkedBehavior, null)) { return; } #if NETFX_CORE IEnumerable <PropertyInfo> properties = stream.GetType().GetRuntimeProperties(); #else PropertyInfo[] properties = stream.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); #endif foreach (PropertyInfo property in properties) { if (property.CanRead && property.CanWrite) { property.SetValue(this, property.GetValue(stream, null), null); } } if (!skipCall) { FailedExecution = !NetworkedBehavior.InvokeRPC(this); } else { Bytes = new BMSByte().Clone(stream.Bytes); } }
/// <summary> /// Write the Networking Stream to the server /// </summary> /// <param name="stream">Networking Stream to be used</param> public override void Write(NetworkingStream stream) { // TODO: Find out if this was a relay if (stream.identifierType == NetworkingStream.IdentifierType.RPC && (stream.Receivers == NetworkReceivers.AllBuffered || stream.Receivers == NetworkReceivers.OthersBuffered)) { ServerBufferRPC(stream); } if (stream.Receivers == NetworkReceivers.Server || stream.Receivers == NetworkReceivers.ServerAndOwner) { return; } byte[] sendData = stream.Bytes.Compress().byteArr; for (int i = 0; i < Players.Count; i++) { if ((stream.Receivers == NetworkReceivers.Others || stream.Receivers == NetworkReceivers.OthersBuffered) && Players[i] == stream.Sender) { continue; } if (!((TcpClient)Players[i].SocketEndpoint).Connected) { Disconnect(Players[i]); continue; } Send(sendData, sendData.Length, Players[i].SocketEndpoint); } }
/// <summary> /// Check the argument update with the stream and start index /// </summary> /// <param name="stream">Stream to be updated</param> /// <param name="start">Start index</param> public ulong SetupInstantiateId(NetworkingStream stream, int start) { ulong id = 0; if (MethodName == INSTANTIATE_METHOD_NAME) { string objName = stream.Bytes.GetString(start + 16); if (!NetworkingManager.TryPullIdFromObject(objName, ref id)) { throw new NetworkException("Invalid object being instantiated"); } if (id == 0) { throw new NetworkException("Invalid object being instantiated"); } idReplacer = BitConverter.GetBytes(id); for (int i = 0; i < idReplacer.Length; i++) { stream.Bytes.byteArr[start + sizeof(ulong) + i] = idReplacer[i]; } } return(id); }
protected override async void SendAsync(NetworkingStream stream) { if (stream.Receivers == NetworkReceivers.Server || stream.Receivers == NetworkReceivers.ServerAndOwner) { return; } for (int i = 0; i < Players.Count; i++) { if ((stream.Receivers == NetworkReceivers.Others || stream.Receivers == NetworkReceivers.OthersBuffered) && Players[i] == stream.Sender) { continue; } try { DataWriter writer = new DataWriter(((StreamSocket)Players[i].SocketEndpoint).OutputStream); writer.WriteBytes(stream.Bytes.byteArr); // Send synchronously await writer.StoreAsync(); OnDataSent(stream); writer.DetachStream(); writer.Dispose(); } catch // (Exception e) { ClientDisconnected(i); //Networking.Error(e.Message); } } }
/// <summary> /// Get a mapped value out of the Networking Stream /// </summary> /// <typeparam name="T">Value to get out of it</typeparam> /// <param name="stream">Networking Stream to be used</param> /// <returns>Returns a mapped value from the Networking Stream</returns> public static T Map <T>(NetworkingStream stream) { object obj = null; if (typeof(T) == typeof(string)) { obj = MapString(stream); } else if (typeof(T) == typeof(Vector2)) { obj = MapVector2(stream); } else if (typeof(T) == typeof(Vector3)) { obj = MapVector3(stream); } else if (typeof(T) == typeof(Vector4) || typeof(T) == typeof(Color) || typeof(T) == typeof(Quaternion)) { obj = MapVector4(typeof(T), stream); } else if (typeof(T) == typeof(byte[])) { obj = MapByteArray(stream); } else if (typeof(T) == typeof(BMSByte)) { obj = MapBMSByte(stream); } else { obj = MapBasicType(typeof(T), stream); } return((T)obj); }
protected bool ReadStream(NetworkingPlayer sender, NetworkingStream stream) { if (IsServer) { if (stream.Receivers == NetworkReceivers.MessageGroup && Me.MessageGroup != stream.Sender.MessageGroup) { return(true); } } // Don't execute this logic on the server if the server doesn't own the object if (!ReferenceEquals(stream.NetworkedBehavior, null) && stream.Receivers == NetworkReceivers.Owner) { return(true); } if (stream.identifierType == NetworkingStream.IdentifierType.RPC) { lock (rpcMutex) { if ((new NetworkingStreamRPC(stream)).FailedExecution) { return(false); } } } return(true); }
public void Deserialize(NetworkingStream stream) { foreach (PropertyInfo property in Properties) { property.SetValue(this, ObjectMapper.Map(property.PropertyType, stream), null); } }
private void PlayerLoadedLevel(NetworkingPlayer player, NetworkingStream stream) { int levelLoaded = ObjectMapper.Map <int>(stream); Unity.MainThreadManager.Run(() => { // The level that was loaded is not the current level #if UNITY_4_6 || UNITY_4_7 if (levelLoaded != Application.loadedLevel) #else if (levelLoaded != Unity.UnitySceneManager.GetCurrentSceneBuildIndex()) #endif { return; } if (clientLoadedLevel != null) { clientLoadedLevel(player); } if (allClientsLoaded == null) { return; } if (++currentClientsLoaded >= OwningNetWorker.Players.Count) { allClientsLoaded(); currentClientsLoaded = 0; } }); }
/// <summary> /// Compares a type of object to the Networking Stream /// </summary> /// <typeparam name="T">Value type to get out of it</typeparam> /// <param name="stream">Stream to be used</param> /// <param name="o">Object being compared with</param> /// <returns>Returns the type of comparison passed</returns> public static bool Compare <T>(NetworkingStream stream, object o) { stream.StartPeek(); object obj = null; if (typeof(T) == typeof(string)) { obj = MapString(stream); } else if (typeof(T) == typeof(Vector3)) { obj = MapVector3(stream); } else if (typeof(T) == typeof(Vector4) || typeof(T) == typeof(Color) || typeof(T) == typeof(Quaternion)) { obj = MapVector4(typeof(T), stream); } else if (typeof(T) == typeof(byte[])) { obj = MapByteArray(stream); } else if (typeof(T) == typeof(BMSByte)) { obj = MapBMSByte(stream); } else { obj = MapBasicType(typeof(T), stream); } stream.StopPeek(); return(Equals(o, obj)); }
private static void GetHostsRequestToClient(NetworkingPlayer sender, NetworkingStream stream) { int count = ObjectMapper.Map <int>(stream); List <HostInfo> hostList = new List <HostInfo>(); for (int i = 0; i < count; i++) { hostList.Add(new HostInfo() { ipAddress = ObjectMapper.Map <string>(stream), port = ObjectMapper.Map <ushort>(stream), maxPlayers = ObjectMapper.Map <int>(stream), name = ObjectMapper.Map <string>(stream), password = ObjectMapper.Map <string>(stream), gameType = ObjectMapper.Map <string>(stream), connectedPlayers = ObjectMapper.Map <int>(stream), comment = ObjectMapper.Map <string>(stream), sceneName = ObjectMapper.Map <string>(stream) }); } Networking.Disconnect(PORT); requestHostsCallback(hostList.ToArray()); }
protected override async void SendAsync(NetworkingStream stream) { try { DataWriter writer = new DataWriter(socket.OutputStream); //uint length = writer.MeasureString(message); writer.WriteBytes(stream.Bytes.byteArr); // Try to store (send?) synchronously await writer.StoreAsync(); OnDataSent(stream); writer.DetachStream(); writer.Dispose(); } catch (Exception e) { // If this is an unknown status, // it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(e.HResult) == SocketErrorStatus.Unknown) { throw; } ErrorDisconnect(e.Message); } }
private void GetHostsRequestToServer(NetworkingPlayer sender, NetworkingStream stream) { ushort pageNumber = ObjectMapper.Map <ushort>(stream); List <HostInfo> subList = new List <HostInfo>(); for (int i = pageNumber * COUNT_PER_PAGE; i < COUNT_PER_PAGE; i++) { if (hosts.Count <= i) { break; } subList.Add(hosts[i]); } BMSByte data = new BMSByte(); ObjectMapper.MapBytes(data, subList.Count); foreach (HostInfo host in hosts) { ObjectMapper.MapBytes(data, host.IpAddress, host.port, host.maxPlayers, host.name, host.password, host.gameType, host.connectedPlayers, host.comment, host.sceneName); } Networking.WriteCustom(WriteCustomMapping.MASTER_SERVER_GET_HOSTS, socket, data, sender, true); }
private void PlayerLoadedLevel(NetworkingPlayer player, NetworkingStream stream) { int levelLoaded = ObjectMapper.Map <int>(stream); Unity.MainThreadManager.Run(() => { // The level that was loaded is not the current level if (levelLoaded != Application.loadedLevel) { return; } if (clientLoadedLevel != null) { clientLoadedLevel(player); } if (allClientsLoaded == null) { return; } if (++currentClientsLoaded >= OwningNetWorker.Players.Count) { allClientsLoaded(); currentClientsLoaded = 0; } }); }
/// <summary> /// Get a Vector3 out of a Networking Stream /// </summary> /// <param name="stream">Networking Stream to be used</param> /// <returns>A Vector3 out of the Networking Stream</returns> public static object MapVector3(NetworkingStream stream) { x = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); y = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); z = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); return(new Vector3(x, y, z)); }
protected override async void ReadAsync() { DataReader reader = new DataReader(socket.InputStream); //reader.InputStreamOptions = InputStreamOptions.Partial; while (true) { try { byte[] bytes = null; uint messageSize = await reader.LoadAsync(sizeof(uint)); if (messageSize != sizeof(uint)) { Disconnect(); // socket was closed return; } bytes = new byte[messageSize]; reader.ReadBytes(bytes); messageSize = BitConverter.ToUInt32(bytes, 0); await reader.LoadAsync(messageSize); bytes = new byte[messageSize]; // TODO: This may read the first 4 bytes again for the size, make sure it doesn't reader.ReadBytes(bytes); //UnityEngine.Debug.LogError(bytes.Length); readBuffer.Clone(bytes); NetworkingStream stream = new NetworkingStream().Consume(this, null, readBuffer); DataRead(null, stream); if (stream.identifierType == NetworkingStream.IdentifierType.Disconnect) { OnDisconnected(ObjectMapper.Map <string>(stream)); Disconnect(); } } catch (Exception e) { // If this is an unknown status, // it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(e.HResult) == SocketErrorStatus.Unknown) { throw; } ErrorDisconnect(e.Message); } await Task.Delay(ThreadSpeed); } }
public override void Write(NetworkingStream stream) { if (!Connected) { throw new NetworkException("You must first be connected to a Network before you can send packets."); } SendAsync(stream); }
/// <summary> /// Get a mapped basic type of object from the Networking Stream /// </summary> /// <param name="type">Type of object to be mapped</param> /// <param name="stream">Networking Stream to be used</param> /// <returns>Returns a mapped object of the given type</returns> public static object MapBasicType(Type type, NetworkingStream stream) { if (type == typeof(sbyte)) { return((sbyte)stream.Read(sizeof(sbyte))[0]); } else if (type == typeof(byte)) { return((byte)stream.Read(sizeof(byte))[0]); } else if (type == typeof(char)) { return((byte)stream.Read(sizeof(byte))[0]); } else if (type == typeof(short)) { return(BitConverter.ToInt16(stream.Read(sizeof(short)), 0)); } else if (type == typeof(ushort)) { return(BitConverter.ToUInt16(stream.Read(sizeof(short)), 0)); } else if (type == typeof(bool)) { return(BitConverter.ToBoolean(stream.Read(sizeof(bool)), 0)); } else if (type == typeof(int)) { return(BitConverter.ToInt32(stream.Read(sizeof(int)), 0)); } else if (type == typeof(uint)) { return(BitConverter.ToUInt32(stream.Read(sizeof(int)), 0)); } else if (type == typeof(float)) { return(BitConverter.ToSingle(stream.Read(sizeof(float)), 0)); } else if (type == typeof(long)) { return(BitConverter.ToInt64(stream.Read(sizeof(long)), 0)); } else if (type == typeof(ulong)) { return(BitConverter.ToUInt64(stream.Read(sizeof(long)), 0)); } else if (type == typeof(double)) { return(BitConverter.ToDouble(stream.Read(sizeof(double)), 0)); } else { throw new NetworkException(11, "The type " + type.ToString() + " is not allowed to be sent over the Network (yet)"); } }
/// <summary> /// Get a byte array of a Networking Stream /// </summary> /// <param name="type">Type of object to be mapped</param> /// <param name="stream">Networking Stream to be used</param> /// <returns>A byte array that was read from the Networking Stream</returns> public static object MapByteArray(NetworkingStream stream) { byteArrSize = Map <int>(stream); byte[] readBytes = stream.Read(byteArrSize); byte[] value = new byte[byteArrSize]; for (int i = 0; i < value.Length; i++) { value[i] = readBytes[i]; } return(value); }
public async void ConnectAndRead(string hostAddress, ushort port, NetworkingStream stream) { try { serverHost = new HostName(hostAddress); // Try to connect asynchronously await socket.ConnectAsync(serverHost, port.ToString()); Connected = true; OnConnected(); SendAsync(stream); byte[] bytes = null; Task tReadResponse = Task.Run(async() => { DataReader reader = new DataReader(socket.InputStream); uint messageSize = await reader.LoadAsync(sizeof(uint)); if (messageSize != sizeof(uint)) { Disconnect(); // socket was closed return; } bytes = new byte[messageSize]; reader.ReadBytes(bytes); messageSize = BitConverter.ToUInt32(bytes, 0); await reader.LoadAsync(messageSize); bytes = new byte[messageSize]; // TODO: This may read the first 4 bytes again for the size, make sure it doesn't reader.ReadBytes(bytes); }); tReadResponse.Wait(); Disconnect(); BMSByte tmp = new BMSByte(); tmp.Clone(bytes); //return new NetworkingStream(Networking.ProtocolType.TCP).Consume(this, null, tmp); } catch (Exception e) { ErrorDisconnect(e.Message); } }
private void Deserialize(NetworkingStream stream) { lock (serializerMutex) { foreach (FieldInfo field in fields) { field.SetValue(this, ObjectMapper.Map(field.FieldType, stream)); } if (transportFinishedInvoker != null) { transportFinishedInvoker(this); } } }
private void UnRegisterServerRequest(NetworkingPlayer sender, NetworkingStream stream) { ushort port = ObjectMapper.Map <ushort>(stream); for (int i = 0; i < hosts.Count; i++) { if (hosts[i].ipAddress == sender.Ip && hosts[i].port == port) { hosts.RemoveAt(i); break; } } socket.Disconnect(sender, "UnRegister Complete"); }
/// <summary> /// Write to the server with a Networking Stream /// </summary> /// <param name="stream">Networking Stream to write</param> public override void Write(NetworkingStream stream) { if (!Connected) { throw new NetworkException(5, "The network could not be written to because no connection has been opened"); } if (!netStream.CanWrite) { return; } // Send the message to the connected TcpServer. Send(stream.Bytes.Compress().byteArr, stream.Bytes.Size); OnDataSent(stream); }
public static void QueueRPCForInstantiate(ulong id, NetworkingStream stream) { if (id < ObjectCounter) { return; } lock (missingIdMutex) { if (!missingIdBuffer.ContainsKey(id)) { missingIdBuffer.Add(id, new List <NetworkingStreamRPC>()); } missingIdBuffer[id].Add(new NetworkingStreamRPC(stream, true)); } }
private void PollPlayersResponse(NetworkingPlayer sender, NetworkingStream stream) { int count = ObjectMapper.Map <int>(stream); List <NetworkingPlayer> playerList = new List <NetworkingPlayer>(); for (int i = 0; i < count; i++) { playerList.Add(new NetworkingPlayer(ObjectMapper.Map <ulong>(stream), string.Empty, string.Empty, ObjectMapper.Map <string>(stream))); } if (pollPlayersCallback != null) { pollPlayersCallback(playerList); } OwningNetWorker.AssignPlayers(playerList); }
/// <summary> /// Map a type of object from a Networking stream to a object /// </summary> /// <param name="type">Type of object to map</param> /// <param name="stream">Networking Stream to be used</param> /// <returns>Returns the mapped object</returns> public static object Map(Type type, NetworkingStream stream) { object obj = null; if (type == typeof(string)) { obj = MapString(stream); } else if (type == typeof(Vector2)) { obj = MapVector2(stream); } else if (type == typeof(Vector3)) { obj = MapVector3(stream); } else if (type == typeof(Vector4) || type == typeof(Color) || type == typeof(Quaternion)) { obj = MapVector4(type, stream); } else if (type == typeof(byte[])) { obj = MapByteArray(stream); byte[] tmp = new byte[byteArrSize]; for (int i = 0; i < tmp.Length; i++) { tmp[i] = ((byte[])obj)[i]; } obj = tmp; } else if (type == typeof(BMSByte)) { obj = MapBMSByte(stream); } else if (type.IsEnum()) { obj = MapBasicType(Enum.GetUnderlyingType(type), stream); } else { obj = MapBasicType(type, stream); } return(obj); }
private void UpdateServerRequest(NetworkingPlayer sender, NetworkingStream stream) { ushort port = ObjectMapper.Map <ushort>(stream); HostInfo host = null; try { host = hosts.First(h => h.IpAddress == sender.Ip.Split('+')[0] && h.port == port); } catch { } if (host == null) { socket.Disconnect(sender, "Host not found"); return; } host.connectedPlayers = ObjectMapper.Map <int>(stream); socket.Disconnect(sender, "Update Complete"); Debug.Log("Updated a server " + host.IpAddress + ":" + host.port); }
public async void ConnectAndWrite(string hostAddress, ushort port, NetworkingStream stream) { try { serverHost = new HostName(hostAddress); await socket.ConnectAsync(serverHost, port.ToString()); Connected = true; OnConnected(); SendAsync(stream); Disconnect(); } catch (Exception e) { ErrorDisconnect(e.Message); } }
/// <summary> /// Called when the Network as interpreted that a cache message has been sent from the server /// </summary> /// <param name="player">The server</param> /// <param name="stream">The data that was received</param> private static void NetworkReadClient(NetworkingPlayer player, NetworkingStream stream) { byte type = ObjectMapper.Map <byte>(stream); int responseHookId = ObjectMapper.Map <int>(stream); object obj = null; if (typeMap[type] == typeof(Vector2)) { obj = ObjectMapper.Map <Vector2>(stream); } else if (typeMap[type] == typeof(Vector3)) { obj = ObjectMapper.Map <Vector3>(stream); } else if (typeMap[type] == typeof(Vector4)) { obj = ObjectMapper.Map <Vector4>(stream); } else if (typeMap[type] == typeof(Color)) { obj = ObjectMapper.Map <Color>(stream); } else if (typeMap[type] == typeof(Quaternion)) { obj = ObjectMapper.Map <Quaternion>(stream); } else if (typeMap[type] == typeof(string)) { obj = ObjectMapper.Map <string>(stream); } else { obj = ObjectMapper.Map(typeMap[type], stream); } if (responseHooks.ContainsKey(responseHookId)) { responseHooks[responseHookId](obj); responseHooks.Remove(responseHookId); } }
/// <summary> /// Called when the Network as interpreted that a cache message has been sent from the client /// </summary> /// <param name="player">The player that requested data from the cache</param> /// <param name="stream">The data that was received</param> public static void NetworkReadServer(NetworkingPlayer player, NetworkingStream stream) { byte type = ObjectMapper.Map <byte>(stream); int responseHookId = ObjectMapper.Map <int>(stream); string key = ObjectMapper.Map <string>(stream); object obj = Get(key); // TODO: Let the client know it is null if (obj == null) { return; } BMSByte data = new BMSByte(); ObjectMapper.MapBytes(data, type, responseHookId, obj); Networking.WriteCustom(WriteCustomMapping.CACHE_READ_CLIENT, Socket, data, player, true); }
/// <summary> /// Get a Vector4 out of a Networking Stream /// </summary> /// <param name="type">Type of object to be mapped</param> /// <param name="stream">Networking Stream to be used</param> /// <returns>A type of Vector4 (Vector4/Color/Quaternion) out of the Networking Stream</returns> public static object MapVector4(Type type, NetworkingStream stream) { x = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); y = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); z = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); w = BitConverter.ToSingle(stream.Read(sizeof(float)), 0); if (type == typeof(Vector4)) { return(new Vector4(x, y, z, w)); } else if (type == typeof(Color)) { return(new Color(x, y, z, w)); } else // if (type == typeof(Quaternion)) { return(new Quaternion(x, y, z, w)); } }