public override void SendFrame(ArraySegment <byte> data, byte evNumber, byte voiceId, int channelId, LocalVoice localVoice) { // this uses a pooled slice, which is released within the send method (here RaiseEvent at the bottom) ByteArraySlice frameData = this.LoadBalancingPeer.ByteArraySlicePool.Acquire(data.Count + 2); frameData.Buffer[0] = voiceId; frameData.Buffer[1] = evNumber; Buffer.BlockCopy(data.Array, 0, frameData.Buffer, 2, data.Count); frameData.Count = data.Count + 2; // need to set the count, as we manipulated the buffer directly SendOptions sendOpt = new SendOptions() { Reliability = localVoice.Reliable, Channel = this.photonChannelForCodec(localVoice.info.Codec), Encrypt = localVoice.Encrypt }; RaiseEventOptions opt = new RaiseEventOptions(); if (localVoice.DebugEchoMode) { opt.Receivers = ReceiverGroup.All; } opt.InterestGroup = localVoice.InterestGroup; this.OpRaiseEvent(VoiceEvent.FrameCode, frameData, opt, sendOpt); // each voice has it's own connection? else, we could aggregate voices data in less count of datagrams this.LoadBalancingPeer.SendOutgoingCommands(); }
internal void onVoiceFrameEvent(object content0, int channelId, int playerId, int localPlayerId) { byte[] content = null; int contentLength = 0; int sliceOffset = 0; ByteArraySlice slice = content0 as ByteArraySlice; if (slice != null) { content = slice.Buffer; contentLength = slice.Count; sliceOffset = slice.Offset; } else { content = content0 as byte[]; contentLength = content.Length; } if (content == null || contentLength < 3) { this.LogError("[PV] onVoiceFrameEvent did not receive data (readable as byte[]) " + content0); } else { byte dataOffset = (byte)content[sliceOffset]; byte voiceId = (byte)content[sliceOffset + 1]; byte evNumber = (byte)content[sliceOffset + 2]; FrameFlags flags = 0; if (dataOffset > 3) { flags = (FrameFlags)content[3]; } FrameBuffer buffer; if (slice != null) { buffer = new FrameBuffer(slice.Buffer, slice.Offset + dataOffset, contentLength - dataOffset, flags, () => slice.Release()); } else { buffer = new FrameBuffer(content, dataOffset, contentLength - dataOffset, flags, null); } this.voiceClient.onFrame(channelId, playerId, voiceId, evNumber, buffer, playerId == localPlayerId); } }
internal void onVoiceFrameEvent(object content0, int channelId, int playerId, int localPlayerId) { byte[] content = null; int contentLength = 0; ByteArraySlice slice = content0 as ByteArraySlice; if (slice != null) { content = slice.Buffer; contentLength = slice.Count; } else { content = content0 as byte[]; contentLength = content.Length; } if (content == null || contentLength < 3) { this.LogError("[PV] onVoiceFrameEvent did not receive data (readable as byte[]) " + content0); } else { byte dataOffset = (byte)content[0]; byte voiceId = (byte)content[1]; byte evNumber = (byte)content[2]; FrameFlags flags = 0; if (dataOffset > 3) { flags = (FrameFlags)content[3]; } byte[] receivedBytes = new byte[contentLength - dataOffset]; // TODO: pool this and release when decoded (problem: size is different for most frames) Buffer.BlockCopy(content, dataOffset, receivedBytes, 0, receivedBytes.Length); if (slice != null) { slice.Release(); } this.voiceClient.onFrame(channelId, playerId, voiceId, evNumber, receivedBytes, flags, playerId == localPlayerId); } }
//private static List<int> reliableTargets = new List<int>(); //private static List<int> unreliableTargets = new List<int>(); public static void Send(this byte[] buffer, int bitposition, UnityEngine.Object refObj, SerializationFlags flags, bool flush = false) { var currentRoom = PhotonNetwork.CurrentRoom; if (PhotonNetwork.OfflineMode || currentRoom == null || currentRoom.Players == null) { return; } bool sendToSelf = (flags & SerializationFlags.SendToSelf) != 0; // no need to send OnSerialize messages while being alone (these are not buffered anyway) if (!sendToSelf && !TickEngineSettings.single.sendWhenSolo && currentRoom.Players.Count <= 1) { return; } ReceiveGroup sendTo = sendToSelf ? ReceiveGroup.All : ReceiveGroup.Others; int bytecount = (bitposition + 7) >> 3; var nc = PhotonNetwork.NetworkingClient; DeliveryMode deliveryMode; if (newPlayers.Count > 0) { deliveryMode = DeliveryMode.Reliable; newPlayers.Clear(); } else { bool forceReliable = (flags & SerializationFlags.ForceReliable) != 0; deliveryMode = unreliableCapable ? (forceReliable ? DeliveryMode.ReliableUnsequenced : DeliveryMode.Unreliable) : DeliveryMode.Reliable; } //if (deliveryMode != DeliveryMode.Unreliable) // Debug.LogError("Forced Reliable Send"); SendOptions sendOptions = new SendOptions() { DeliveryMode = deliveryMode }; var peer = PhotonNetwork.NetworkingClient.LoadBalancingPeer; #if PUN_2_19_OR_NEWER if (peer.SerializationProtocolType == SerializationProtocol.GpBinaryV16) { System.ArraySegment <byte> slice = new System.ArraySegment <byte>(buffer, 0, bytecount); nc.OpRaiseEvent(NetMsgCallbacks.DEF_MSG_ID, slice, opts[(int)sendTo], sendOptions); } else { ByteArraySlice slice = peer.ByteArraySlicePool.Acquire(buffer, 0, bytecount); nc.OpRaiseEvent(NetMsgCallbacks.DEF_MSG_ID, slice, opts[(int)sendTo], sendOptions); } #else System.ArraySegment <byte> slice = new System.ArraySegment <byte>(buffer, 0, bytecount); nc.OpRaiseEvent(NetMsgCallbacks.DEF_MSG_ID, slice, opts[(int)sendTo], sendOptions); #endif if (flush) { while (peer.SendOutgoingCommands()) { ; } } }