public void AnnounceToAll(EPacket packet, byte[] data, int channel) { foreach (var c in Clients) { Send(c.Identity, packet, data, channel); } }
public void CloseWrite(string channelName, Identity user, EPacket type) { if (!type.IsChunk()) { LogUtils.LogNetwork("Error: Failed to stream non chunk: " + type); } else { NetworkCallAttribute networkCall; var index = GetCall(channelName, out networkCall); if (index == -1) { return; } byte[] buffer; GetPacket(type, index, out buffer); if (IsOwner && (user == Connection.ClientID)) { Receive(Connection.ClientID, buffer); } else if (Connection.IsServer() && (user == Connection.ServerID)) { Receive(Connection.ServerID, buffer); } else { Connection.Send(user, type, buffer, ID); } } }
public void Receive(ArraySegment <byte> buffer) { if (State == EConnectionState.Disconnected) { return; } EPacket eType = PacketReader.DecodePacketType(buffer.Array[buffer.Offset]); if (eType == EPacket.Persistence) { GameStatePersistence.Receive(buffer); } else { if (m_PackageReader == null) { m_PackageReader = new PacketReader(); } Packet packet = m_PackageReader.Read(new ByteReader(buffer)); if (packet != null) { m_PackageReader = null; Dispatcher.Dispatch(State, packet); } } }
public virtual void Send(Identity receiver, EPacket type, byte[] data, int length, int channel) { if (receiver == null) { throw new ArgumentNullException(nameof(receiver)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } var tmp = data.ToList(); tmp.Insert(0, type.GetID()); data = tmp.ToArray(); length += 1; // if ((IsClient() && receiver == ClientID && ClientID != null) || (IsServer() && receiver == ServerID && ServerID != null)) // { // LogUtils.Debug("Server/Client sending to itself"); // Receive(receiver, data, length, channel); // return; // } if (!receiver.IsValid()) { LogUtils.LogError("Failed to send to invalid ID."); return; } LogUtils.LogNetwork("Sending packet: " + type + ", receiver: " + receiver + (receiver == ServerID ? " (Server)" : "") + ", ch: " + channel + ", size: " + data.Length); SendMethod sendType; if (type.IsUnreliable()) { sendType = !type.IsInstant() ? SendMethod.SEND_UNRELIABLE : SendMethod.SEND_UNRELIABLE_NO_DELAY; } else { sendType = !type.IsInstant() ? SendMethod.SEND_RELIABLE_WITH_BUFFERING: SendMethod.SEND_RELIABLE; } if (OnPreSend(receiver, type, data, length, channel)) { return; } if (!Provider.Write(receiver, data, (ulong)length, sendType, channel)) { LogUtils.LogError("Failed to send data to " + receiver); } }
public static ArraySegment <byte> MakeRaw(EPacket eType, byte[] payload) { Packet packet = new Packet(eType, payload); MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); new PacketWriter(packet).Write(writer); return(stream.ToArray()); }
protected override bool OnPreSend(Identity receiver, EPacket type, byte[] data, int length, int channel) { if (ServerID == ClientID) { _server.Receive(ServerID, data, length, channel); return(true); } return(false); }
protected override bool OnPreSend(Identity receiver, EPacket type, byte[] data, int length, int channel) { if (!IsSinglePlayer || receiver != ServerID) { return(false); } SinglePlayerConnection.Receive(ServerID, data, length, channel); return(true); }
private void GetPacket(EPacket type, int index, out int size, out byte[] packet, byte[] bytes, int length) { size = 4 + length; packet = bytes; packet[0] = (byte)type; packet[1] = (byte)index; byte[] buffer = BitConverter.GetBytes((ushort)length); packet[2] = buffer[0]; packet[3] = buffer[1]; }
private static void AssertIsPersistencePayload(ArraySegment <byte> buffer) { if (buffer.Array == null) { throw new ArgumentNullException(nameof(buffer)); } EPacket eType = PacketReader.DecodePacketType(buffer.Array[buffer.Offset]); if (eType != EPacket.Persistence) { throw new ArgumentException(nameof(buffer)); } }
public void CloseWrite(string channelName, ECall mode, EPacket type) { LogUtils.Debug(nameof(CloseWrite) + ": " + channelName); if (!type.IsChunk()) { LogUtils.LogNetwork("Error: Failed to stream non chunk: " + type); } else { NetworkCallAttribute networkCall; var index = GetCall(channelName, out networkCall); if (index == -1) { return; } byte[] buffer; GetPacket(type, index, out buffer); Send(mode, type, buffer); } }
/// <summary> /// Reads a <see cref="Packet" /> from the given reader. Returns null if the packet is fragmented and /// parts are still missing. /// </summary> /// <param name="reader"></param> /// <returns>Serialized packet or null if the packet is fragmented and not yet complete.</returns> public Packet Read(ByteReader reader) { // 1 Byte header byte header = reader.Binary.ReadByte(); EPacket eType = DecodePacketType(header); // 4 Bytes size of payload int iPayloadSize = reader.Binary.ReadInt32(); // handle fragmented packages if ((header & Packet.BitMaskFragment_More) != Packet.BitMaskFragment_None) { if (m_FragmentedBuffer == null) { m_FragmentedStream = new MemoryStream(); m_FragmentedBuffer = new BinaryWriter(m_FragmentedStream); } m_FragmentedBuffer.Write(reader.Binary.ReadBytes(iPayloadSize)); return(null); } if ((header & Packet.BitMaskFragment_End) != Packet.BitMaskFragment_None) { if (m_FragmentedBuffer == null) { throw new PacketSerializingException( $"Package ({eType}) was flagged as END of a fragmented packet: got no START."); } m_FragmentedBuffer.Write(reader.Binary.ReadBytes(iPayloadSize)); Done = true; return(new Packet(eType, m_FragmentedStream)); } Done = true; return(new Packet(eType, reader.Binary.ReadBytes(iPayloadSize))); }
public static bool IsUpdate(this EPacket p) { return(GetAttr(p).IsUpdate); }
public static byte EncodePacketType(EPacket eType) { return((byte)(Convert.ToByte(eType) & Packet.BitMaskType)); }
public Packet(EPacket eType, MemoryStream stream) : this(eType, stream.ToArray()) { }
public Packet(EPacket eType, byte[] payload) : this(eType, new ArraySegment <byte>(payload)) { }
public virtual void Send(Identity receiver, EPacket type, byte[] data, int channel) { Send(receiver, type, data, data.Length, channel); }
private static EPacketAttr GetAttr(EPacket p) { return((EPacketAttr)Attribute.GetCustomAttribute(ForValue(p), typeof(EPacketAttr))); }
public static bool IsChunk(this EPacket p) { return(GetAttr(p).IsChunk); }
public static void DTestArray() { string[] strArray = new string[5]; int[] intArray = new int[5]; StructField[] structArray = new StructField[5]; ClassField[] classArray = new ClassField[5]; DocumentEnum[] enumArray = new DocumentEnum[5]; for (int i = 0; i < strArray.Length; i += 1) { strArray[i] = i.ToString(); intArray[i] = i; enumArray[i] = DocumentEnum.ID; structArray[i] = new StructField() { PublicAge = i }; classArray[i] = new ClassField() { PublicAge = i }; } //动态创建Action委托 Delegate newMethod = EHandler.CreateMethod <ENull>((il) => { EMethod method = typeof(Console); //从运行时获取数组并入栈到IL层临时变量 EArray stringArrayModel = strArray; ELoop.For(stringArrayModel, (currentElement) => { method.ExecuteMethod <string>("WriteLine", currentElement); }); EArray intArrayModel = intArray; ELoop.For(3, 5, 1, intArrayModel, (currentElement) => { method.ExecuteMethod <int>("WriteLine", currentElement); }); EArray arrayModel = EArray.CreateArraySpecifiedLength <int>(10); arrayModel.StoreArray(5, 6); arrayModel.StoreArray(6, 6); arrayModel.StoreArray(7, 6); ELoop.For(0, 10, 1, arrayModel, (currentElement) => { method.ExecuteMethod <int>("WriteLine", currentElement); }); //从运行时获取数组并入栈到IL层临时变量 EArray structArrayModel = EArray.CreateArrayFromRuntimeArray(structArray); ELoop.For(structArrayModel, (currentElement) => { EModel model = EModel.CreateModelFromAction(currentElement, typeof(StructField)); model.LFieldValue("PublicAge"); method.ExecuteMethod <int>("WriteLine"); }); EArray classArrayModel = EArray.CreateArrayFromRuntimeArray(classArray); ELoop.For(classArrayModel, (currentElement) => { EModel model = EModel.CreateModelFromAction(currentElement, typeof(ClassField)); model.LFieldValue("PublicAge"); method.ExecuteMethod <int>("WriteLine"); }); EArray enumArrayModel = EArray.CreateArrayFromRuntimeArray(enumArray); ELoop.For(enumArrayModel, (currentElement) => { EModel model = EModel.CreateModelFromAction(currentElement, typeof(DocumentEnum)); model.Load(); EPacket.Packet(typeof(DocumentEnum)); method.ExecuteMethod <object>("WriteLine"); }); }).Compile(); ((Action)newMethod)(); }
public PacketHandlerAttribute(EConnectionState state, EPacket eType) { State = state; Type = eType; }
public void Send(ECall mode, Vector3 point, float radius, EPacket type, byte[] packet) { Send(mode, point, radius, type, packet, packet.Length); }
internal override void Receive(Identity source, byte[] packet, int size, int channel) { base.Receive(source, packet, size, channel); var net = ((OffsetNet + Time.realtimeSinceStartup) - LastNet); EPacket parsedPacket = (EPacket)packet[0]; StripPacketByte(ref packet, ref size); if (parsedPacket.IsUpdate()) { if (source == ServerID) { foreach (Channel ch in Receivers) { ch.Receive(source, packet, 0, size); } } else { if (Clients.All(client => client.Identity != source)) { return; } foreach (Channel ch in Receivers.Where(ch => ch.ID == channel)) { ch.Receive(source, packet, 0, size); } } return; } PendingUser currentPending; switch (parsedPacket) { case EPacket.WORKSHOP: { //workshop list {none for now} List <ulong> workshoplist = new List <ulong>(); byte[] args = new byte[1 + (workshoplist.Count * 8)]; args[0] = (byte)workshoplist.Count; for (byte i = 0; i < workshoplist.Count; i = (byte)(i + 1)) { BitConverter.GetBytes(workshoplist[i]).CopyTo(args, (1 + (i * 8))); } Send(source, EPacket.WORKSHOP, args, args.Length, 0); return; } case EPacket.TICK: { object[] objects = { net }; byte[] buffer2 = ObjectSerializer.GetBytes(0, objects); Send(source, EPacket.TIME, buffer2, 0); return; } case EPacket.TIME: foreach (User c in Clients.Where(c => c.Identity == source)) { if (!(c.LastPing > 0f)) { return; } c.LastNet = Time.realtimeSinceStartup; c.Lag(Time.realtimeSinceStartup - c.LastPing); c.LastPing = -1f; return; } return; case EPacket.CONNECT: { if (_pendingPlayers.Any(p => p.Identity == source)) { Reject(source, ERejectionReason.ALREADY_PENDING); return; } if (Clients.Any(c => c.Identity == source)) { Reject(source, ERejectionReason.ALREADY_CONNECTED); return; } Type[] argTypes = { // [0] name, [1] group, [2] version, [3] ping typeof(string), typeof(ulong), typeof(string), typeof(float) }; var args = ObjectSerializer.GetObjects(0, 0, packet, argTypes); var playerName = (string)args[0]; var group = (ulong)args[1]; var version = (string)args[2]; var ping = (float)args[3]; LogUtils.Log("Player connecting: " + playerName); if (version != GameInfo.VERSION) { Reject(source, ERejectionReason.WRONG_VERSION); return; } if ((Clients.Count + 1) > MultiplayerProvider.MultiplayerProvider.MAX_PLAYERS) { Reject(source, ERejectionReason.SERVER_FULL); return; } var pendingPlayer = new PendingUser(source, playerName, group, ping); _pendingPlayers.Add(pendingPlayer); if (Provider.SupportsAuthentification) { Send(source, EPacket.VERIFY, new byte[] { }, 0, 0); return; } pendingPlayer.HasAuthentication = true; Accept(pendingPlayer); return; } default: if (parsedPacket != EPacket.AUTHENTICATE) { LogUtils.LogError("Failed to handle message: " + parsedPacket); return; } currentPending = _pendingPlayers.FirstOrDefault(p => p.Identity == source); break; } if (currentPending == null) { Reject(source, ERejectionReason.NOT_PENDING); } else if ((Clients.Count + 1) > MultiplayerProvider.MultiplayerProvider.MAX_PLAYERS) { Reject(source, ERejectionReason.SERVER_FULL); } else { object[] args = ObjectSerializer.GetObjects(0, 0, packet, typeof(byte[])); if (!((ServerMultiplayerProvider)Provider).VerifyTicket(source, (byte[])args[0])) { Reject(source, ERejectionReason.AUTH_VERIFICATION); } } }
public void Send(ECall mode, Vector3 point, float radius, EPacket type, byte[] packet, int size) { radius *= radius; switch (mode) { case ECall.Server: if (Connection.IsServer()) { Receive(Connection.ServerID, packet, 0, size); } else { Connection.Send(Connection.ServerID, type, packet, size, ID); } break; case ECall.All: if (!(Connection.IsServer())) { Connection.Send(Connection.ServerID, type, packet, size, ID); } foreach (User user in Connection.Clients) { if ((user.Identity == Connection.ClientID) || (user.Player == null)) { continue; } Vector3 vector = user.Player.transform.position - point; if (vector.sqrMagnitude < radius) { Connection.Send(user.Identity, type, packet, size, ID); } } if (Connection.IsServer()) { Receive(Connection.ServerID, packet, 0, size); } else { Receive(Connection.ClientID, packet, 0, size); } break; case ECall.Others: if (!(Connection.IsServer())) { Connection.Send(Connection.ServerID, type, packet, size, ID); } foreach (User user in Connection.Clients) { if ((user.Identity == Connection.ClientID) || (user.Player == null)) { continue; } Vector3 vector2 = user.Player.transform.position - point; if (vector2.sqrMagnitude < radius) { Connection.Send(user.Identity, type, packet, size, ID); } } break; case ECall.Owner: if (IsOwner) { Receive(Owner, packet, 0, size); } else { Connection.Send(Owner, type, packet, size, ID); } break; case ECall.NotOwner: if (!(Connection.IsServer())) { Connection.Send(Connection.ServerID, type, packet, size, ID); } foreach (User user in Connection.Clients) { if ((user.Identity == Owner) || (user.Player == null)) { continue; } Vector3 vector3 = user.Player.transform.position - point; if (vector3.sqrMagnitude < radius) { Connection.Send(user.Identity, type, packet, size, ID); } } break; case ECall.Clients: foreach (User user in Connection.Clients) { if ((user.Identity == Connection.ClientID) || (user.Player == null)) { continue; } Vector3 vector4 = user.Player.transform.position - point; if (vector4.sqrMagnitude < radius) { Connection.Send(user.Identity, type, packet, size, ID); } } if (Connection.IsServer()) { Receive(Connection.ClientID, packet, 0, size); } break; case ECall.Peers: foreach (User user in Connection.Clients) { if ((user.Identity == Connection.ClientID) || (user.Player == null)) { continue; } Vector3 vector5 = user.Player.transform.position - point; if (vector5.sqrMagnitude < radius) { Connection.Send(user.Identity, type, packet, size, ID); } } break; } }
public static bool IsUnreliable(this EPacket p) { return(GetAttr(p).IsUnreliable); }
public static bool IsInstant(this EPacket p) { return(GetAttr(p).IsInstant); }
internal override void Receive(Identity id, byte[] packet, int size, int channel) { base.Receive(id, packet, size, channel); EPacket parsedPacket = (EPacket)packet[0]; StripPacketByte(ref packet, ref size); if (parsedPacket.IsUpdate()) { foreach (Channel ch in Receivers.Where(ch => ch.ID == channel)) { ch.Receive(id, packet, 0, size); } return; } if (id != ServerID) { return; } switch (parsedPacket) { case EPacket.WORKSHOP: //todo break; case EPacket.TICK: { var data = ObjectSerializer.GetBytes(0, Time.realtimeSinceStartup); Send(ServerID, EPacket.TIME, data, 0); break; } case EPacket.TIME: { object[] args = ObjectSerializer.GetObjects(0, 0, packet, typeof(float)); LastNet = Time.realtimeSinceStartup; OffsetNet = ((float)args[0]) + ((Time.realtimeSinceStartup - LastPing) / 2f); Lag(Time.realtimeSinceStartup - LastPing); break; } case EPacket.SHUTDOWN: Disconnect(); break; case EPacket.CONNECTED: { { Type[] argTypes = { //[0] id, [1] name, [2] group, [3] position, [4], angle, [5] channel typeof(Identity), typeof(string), typeof(ulong), typeof(Vector3), typeof(Vector3), typeof(int), typeof(bool) }; object[] args = ObjectSerializer.GetObjects(0, 0, packet, argTypes); if (IsSinglePlayer) { return; } if (World.Loaded) { AddPlayer(Provider.Deserialilze((Identity)args[0]), (string)args[1], (ulong)args[2], (Vector3)args[3], (Vector3)args[4], (int)args[5], (bool)args[6]); } else { QueuePlayer(Provider.Deserialilze((Identity)args[0]), (string)args[1], (ulong)args[2], (Vector3)args[3], (Vector3)args[4], (int)args[5], (bool)args[6]); } break; } } case EPacket.VERIFY: LogUtils.Debug("Opening ticket"); byte[] ticket = ((ClientMultiplayerProvider)Provider).OpenTicket(); if (ticket == null) { LogUtils.Debug("ticket equals null"); Disconnect(); break; } Send(ServerID, EPacket.AUTHENTICATE, ticket, ticket.Length, 0); break; case EPacket.DISCONNECTED: { //If singleplayer (local server) we will already do this at ServerConnection if (IsSinglePlayer) { return; } object[] args = ObjectSerializer.GetObjects(0, 0, packet, typeof(byte)); var index = (byte)args[0]; var user = GetUser(index); PlayerQuitEvent @event = new PlayerQuitEvent(user.Player); EventManager.Instance.CallEvent(@event); RemovePlayer(index); break; } case EPacket.REJECTED: case EPacket.KICKED: Disconnect(); break; case EPacket.ACCEPTED: { object[] args = ObjectSerializer.GetObjects(0, 0, packet, typeof(ulong), typeof(int)); LogUtils.Debug("Setting MainPlayer channel to: " + (int)args[1]); ((ClientMultiplayerProvider)Provider).SetIdentity((ulong)args[0]); ((ClientMultiplayerProvider)Provider).AdvertiseGame(ServerID, _currentIp, _currentPort); ((ClientMultiplayerProvider)Provider).SetConnectInfo(_currentIp, _currentPort); IsFavoritedServer = ((ClientMultiplayerProvider)Provider).IsFavoritedServer(_currentIp, _currentPort); ((ClientMultiplayerProvider)Provider).FavoriteServer(_currentIp, _currentPort); break; } case EPacket.UPDATE_CHANNELS: { object[] args = ObjectSerializer.GetObjects(0, 0, packet, ChannelCount.GetType()); ChannelCount = (int)args[0]; break; } default: LogUtils.LogWarning("Couldn't handle packet: " + parsedPacket); break; } }
public static byte GetID(this EPacket p) { return((byte)p); }
private Packet(EPacket eType, ArraySegment <byte> payload) { Type = eType; Payload = payload; }
private static MemberInfo ForValue(EPacket p) { return(typeof(EPacket).GetField(Enum.GetName(typeof(EPacket), p))); }
protected virtual bool OnPreSend(Identity receiver, EPacket type, byte[] data, int length, int channel) { return(false); }