internal NetworkMessageInfo(NetworkBaseLocal network, NetworkFlags flags, NetworkViewBase nv) { sender = network._localPlayer; localTimestamp = NetworkTime.localTime; serverTimestamp = network._GetMonotonicServerTime(localTimestamp); rawServerTimestamp = network._GetRawServerTime(localTimestamp); networkView = nv as NV; this.flags = flags; }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, InternalCode internCode) : this( network, NetworkFlags.TypeUnsafe | NetworkFlags.NoTimestamp | NetworkFlags.Unbuffered, Channel.RPC, String.Empty, internCode, NetworkPlayer.unassigned, NetworkPlayer.unassigned, NetworkViewID.unassigned) { }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, NetworkFlags flags, Channel channel, InternalCode internCode, NetworkPlayer target) : this( network, flags, channel, String.Empty, internCode, target, NetworkPlayer.unassigned, NetworkViewID.unassigned) { }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, NetworkFlags flags, Channel channel, InternalCode internCode, RPCMode mode, NetworkPlayer exclusion) : this( network, ((mode & RPCMode.Buffered) != 0) ? flags : (flags | NetworkFlags.Unbuffered), channel, String.Empty, internCode, (mode == RPCMode.Server) ? NetworkPlayer.server : NetworkPlayer.unassigned, exclusion, NetworkViewID.unassigned) { }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, NetworkFlags flags, Channel channel, string name, RPCMode mode, NetworkViewID viewID) : this( network, flags, channel, name, mode, (mode == RPCMode.AllExceptOwner || mode == RPCMode.OthersExceptOwner) ? network._FindNetworkViewOwner(viewID) : ((mode == RPCMode.Buffered) ? NetworkPlayer.server : NetworkPlayer.unassigned), // TODO: fix fulhacks! viewID) { }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, NetworkFlags flags, Channel channel, string name, RPCMode mode, NetworkPlayer exclusion, NetworkViewID viewID) : this( network, ((mode & RPCMode.Buffered) != 0) ? flags : (flags | NetworkFlags.Unbuffered), channel, name, InternalCode.None, (mode == RPCMode.Server) ? NetworkPlayer.server : ((mode == RPCMode.Owner) ? network._FindNetworkViewOwner(viewID) : NetworkPlayer.unassigned), exclusion, viewID) { }
// Constructor used when creating and destroying network objects public NetworkMessage(NetworkBaseLocal network) { flags = 0; stream = null; connection = null; channel = NetChannel.ReliableUnordered; localTimeSent = NetworkTime.localTime; monotonicServerTimeSent = network._GetMonotonicServerTime(localTimeSent); rawServerTimeSent = network._GetRawServerTime(localTimeSent); name = String.Empty; internCode = InternalCode.None; sender = network._localPlayer; target = NetworkPlayer.unassigned; exclude = NetworkPlayer.unassigned; viewID = NetworkViewID.unassigned; }
internal NetworkConfig(NetworkBaseLocal network) { _network = network; }
// Outgoing message public NetworkMessage(NetworkBaseLocal network, NetworkFlags flags, Channel channel, string name, InternalCode internCode, NetworkPlayer target, NetworkPlayer exclusion, NetworkViewID viewID) { if (target != NetworkPlayer.unassigned) { flags |= NetworkFlags.Unbuffered; } this.flags = flags; this.channel = ((flags & NetworkFlags.Unreliable) == 0) ? (NetChannel)channel : NetChannel.Unreliable; if (isBuffered) { if (!(isReliable)) { Utility.Exception("Message can not be buffered and unreliable"); } } // TODO: optimize by calculating initial buffer size by bit-flags & args // TODO: optimize by stripping unnecessary data if we have a direct connection i.e. is server // TODO: remove the default 4 bytes allocated by the default NetBuffer constructor. #if !NO_POOLING if (isReliable) { stream = new BitStream(true, isTypeSafe); //The Bitstream for reliable RPCs (including buffered RPCs) should not be written to pooled Bitreams, that would be dangerous during resend. } else { stream = (isTypeSafe) ? _bitStreamPoolOutgoingTypeSafe.GetNext() : _bitStreamPoolOutgoing.GetNext(); } #else stream = new BitStream(true, isTypeSafe); #endif var buffer = stream._buffer; connection = null; this.name = name; this.internCode = internCode; sender = network._localPlayer; this.target = target; exclude = exclusion; this.viewID = viewID; // write header to stream: HeaderFlags headerFlags = 0; // TODO: optimize away exclude and target PlayerID when sent from a regular uLink Server by faking it into a simple broadcast message if (isBroadcast) { headerFlags |= (hasExcludeID)? HeaderFlags.HasBroadcastExcludePlayerID : HeaderFlags.Broadcast; } else if (hasTargetID) { headerFlags |= HeaderFlags.HasTargetPlayerID; } if (hasViewID && isInternal) { headerFlags |= HeaderFlags.HasInternalCodeAndViewID; } else if (hasViewID) { headerFlags |= (isBuffered) ? HeaderFlags.HasNameAndViewIDAndIsBuffered : HeaderFlags.HasNameAndViewID; } else { headerFlags |= HeaderFlags.HasInternalCode; } if (hasTimestamp) { headerFlags |= (isBuffered) ? HeaderFlags.Has40BitTimestamp : HeaderFlags.Has16BitTimestamp; } if (isTypeSafe) { headerFlags |= HeaderFlags.HasTypeCodes; } buffer.Write((byte)headerFlags); if (hasTargetID) { this.target._Write(buffer); } if (hasExcludeID) { exclude._Write(buffer); } if (hasViewID) { this.viewID._Write(buffer); } if (isInternal) { buffer.Write((byte)internCode); } else { buffer.Write(name); } if (hasTimestamp) { localTimeSent = NetworkTime.localTime; rawServerTimeSent = localTimeSent + network.rawServerTimeOffset; #if PIKKO_BUILD ulong timestampInMillis = (ulong)NetTime.ToMillis(localTimestamp); #else rawServerTimeSent = localTimeSent + network.rawServerTimeOffset; ulong timestampInMillis = (ulong)NetTime.ToMillis(rawServerTimeSent); #endif buffer.Write(timestampInMillis, (isBuffered) ? 40 : 16); } buffer.PositionBits = buffer.LengthBits; }
// Outgoing forwarded message (non-auth server uses this) public NetworkMessage(NetworkBaseLocal network, NetworkMessage msg, NetworkPlayer originalSender) { flags = msg.flags; connection = msg.connection; channel = msg.channel; localTimeSent = msg.localTimeSent; monotonicServerTimeSent = msg.monotonicServerTimeSent; rawServerTimeSent = msg.rawServerTimeSent; name = msg.name; internCode = msg.internCode; sender = originalSender; target = msg.target; exclude = msg.exclude; viewID = msg.viewID; stream = new BitStream(isTypeSafe); var buffer = stream._buffer; HeaderFlags headerFlags = 0; if (sender != network._localPlayer) { headerFlags |= HeaderFlags.HasOriginalSenderPlayerID; } if (isBroadcast) { headerFlags |= (hasExcludeID) ? HeaderFlags.HasBroadcastExcludePlayerID : HeaderFlags.Broadcast; } else if (hasTargetID) { headerFlags |= HeaderFlags.HasTargetPlayerID; } if (hasViewID && isInternal) { headerFlags |= HeaderFlags.HasInternalCodeAndViewID; } else if (hasViewID) { headerFlags |= (isBuffered) ? HeaderFlags.HasNameAndViewIDAndIsBuffered : HeaderFlags.HasNameAndViewID; } else { headerFlags |= HeaderFlags.HasInternalCode; } // TODO: use 24bit timestamp if needed if (hasTimestamp) { headerFlags |= HeaderFlags.Has16BitTimestamp; } if (isTypeSafe) { headerFlags |= HeaderFlags.HasTypeCodes; } buffer.Write((byte)headerFlags); if (sender != network._localPlayer) { sender._Write(buffer); } if (hasTargetID) { target._Write(buffer); } if (hasExcludeID) { exclude._Write(buffer); } if (hasViewID) { viewID._Write(buffer); } if (internCode == InternalCode.None) { buffer.Write(name); } else { buffer.Write((byte)internCode); } if (hasTimestamp) { #if PIKKO_BUILD ulong timestampInMillis = (ulong)NetTime.ToMillis(localTimestamp); #else ulong timestampInMillis = (ulong)NetTime.ToMillis(rawServerTimeSent); #endif // TODO: use 24bit timestamp if needed buffer.Write(timestampInMillis, 16); } buffer.PositionBits = buffer.LengthBits; int argpos = msg.stream._buffer.PositionBytes; stream._buffer.Write(msg.stream._buffer.Data, argpos, msg.stream._buffer.LengthBytes - argpos); }
// Outgoing forwarded message (non-auth server uses this) public NetworkMessage(NetworkBaseLocal network, NetworkMessage msg) : this(network, msg, msg.sender) { }
//Incoming message public NetworkMessage(NetworkBaseLocal network, NetBuffer buffer, NetConnection connection, NetChannel channel, bool wasEncrypted, double localTimeRecv) { flags = 0; if (!wasEncrypted) { flags |= NetworkFlags.Unencrypted; } flags = (((int)channel & (int)NetChannel.ReliableUnordered) == (int)NetChannel.ReliableUnordered) ? flags &= ~NetworkFlags.Unreliable : flags |= NetworkFlags.Unreliable; var headerFlags = (HeaderFlags)buffer.ReadByte(); // TODO: make sure a regular uLink server doesn't accept messages with a original sender. We should create static create Message methods instead of the constructor? if ((headerFlags & HeaderFlags.HasOriginalSenderPlayerID) == HeaderFlags.HasOriginalSenderPlayerID) { sender = new NetworkPlayer(buffer); } else { sender = NetworkBaseLocal._GetConnectionPlayerID(connection); } switch (headerFlags & HeaderFlags.DestinationType) { case HeaderFlags.ToServer: target = NetworkPlayer.server; exclude = NetworkPlayer.unassigned; break; case HeaderFlags.HasTargetPlayerID: target = new NetworkPlayer(buffer); exclude = NetworkPlayer.unassigned; break; case HeaderFlags.Broadcast: target = NetworkPlayer.unassigned; exclude = NetworkPlayer.unassigned; break; case HeaderFlags.HasBroadcastExcludePlayerID: target = NetworkPlayer.unassigned; exclude = new NetworkPlayer(buffer); break; } switch (headerFlags & HeaderFlags.ExecutionType) { case HeaderFlags.HasInternalCode: viewID = NetworkViewID.unassigned; name = String.Empty; internCode = (InternalCode)buffer.ReadByte(); flags |= NetworkFlags.Unbuffered; break; case HeaderFlags.HasNameAndViewID: viewID = new NetworkViewID(buffer); name = buffer.ReadString(); internCode = InternalCode.None; flags |= NetworkFlags.Unbuffered; break; case HeaderFlags.HasInternalCodeAndViewID: viewID = new NetworkViewID(buffer); name = String.Empty; internCode = (InternalCode)buffer.ReadByte(); if (internCode != InternalCode.Create) { flags |= NetworkFlags.Unbuffered; } break; case HeaderFlags.HasNameAndViewIDAndIsBuffered: viewID = new NetworkViewID(buffer); name = buffer.ReadString(); internCode = InternalCode.None; break; } if ((headerFlags & HeaderFlags.TimestampType) != HeaderFlags.NoTimestamp) { int numberOfBits; switch (headerFlags & HeaderFlags.TimestampType) { case HeaderFlags.Has16BitTimestamp: numberOfBits = 16; break; case HeaderFlags.Has24BitTimestamp: numberOfBits = 24; break; case HeaderFlags.Has40BitTimestamp: numberOfBits = 40; break; default: numberOfBits = 0; break; // something is wrong } ulong encodedTimestamp = buffer.ReadUInt64(numberOfBits); #if PIKKO_BUILD double serverTimeRecv = localTimeRecv; #else double serverTimeRecv = network._EnsureAndUpdateMonotonicTimestamp(localTimeRecv + network.rawServerTimeOffset); #endif double monotonicTransitTime = _GetElapsedTimeFromEncodedTimestamp(serverTimeRecv, encodedTimestamp, numberOfBits); #if !PIKKO_BUILD monotonicServerTimeSent = serverTimeRecv - monotonicTransitTime; // TODO: ugly hack: double rawServerTimeRecv = localTimeRecv + network.rawServerTimeOffset; double rawTransitTime = _GetElapsedTimeFromEncodedTimestamp(rawServerTimeRecv, encodedTimestamp, numberOfBits); rawServerTimeSent = rawServerTimeRecv - rawTransitTime; localTimeSent = localTimeRecv - rawTransitTime; #endif } if ((headerFlags & HeaderFlags.HasTypeCodes) == 0) { flags |= NetworkFlags.TypeUnsafe; } stream = new BitStream(buffer, isTypeSafe); this.connection = connection; this.channel = channel; }
//Incoming message (backward-compatibility) public NetworkMessage(NetworkBaseLocal network, NetBuffer buffer, NetConnection connection, NetChannel channel, bool wasEncrypted) : this(network, buffer, connection, channel, wasEncrypted, NetworkTime.localTime) { }
internal NetworkPlayer(NetworkBaseLocal network) { id = network._localPlayer.id; }
internal NetworkEmulation(NetworkBaseLocal network) { _network = network; }