mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
commit
745519982e
@ -14,7 +14,7 @@ public ULocalConnectionToClient(LocalClient localClient) : base ("localClient")
|
||||
this.localClient = localClient;
|
||||
}
|
||||
|
||||
protected override bool SendBytes(byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
internal override bool SendBytes(byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
{
|
||||
localClient.InvokeBytesOnClient(bytes);
|
||||
return true;
|
||||
@ -29,7 +29,7 @@ public ULocalConnectionToServer() : base("localServer")
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool SendBytes(byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
internal override bool SendBytes(byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
{
|
||||
if (bytes.Length == 0)
|
||||
{
|
||||
|
@ -153,17 +153,14 @@ internal void RemovePlayerController()
|
||||
|
||||
public virtual bool Send(short msgType, MessageBase msg, int channelId = Channels.DefaultReliable)
|
||||
{
|
||||
NetworkWriter writer = new NetworkWriter();
|
||||
msg.Serialize(writer);
|
||||
|
||||
// pack message and send
|
||||
byte[] message = Protocol.PackMessage((ushort)msgType, writer.ToArray());
|
||||
byte[] message = Protocol.PackMessage((ushort)msgType, msg);
|
||||
return SendBytes(message, channelId);
|
||||
}
|
||||
|
||||
// protected because no one except NetworkConnection should ever send bytes directly to the client, as they
|
||||
// would be detected as some kind of message. send messages instead.
|
||||
protected virtual bool SendBytes( byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
// internal because no one except Mirror should send bytes directly to
|
||||
// the client. they would be detected as a message. send messages instead.
|
||||
internal virtual bool SendBytes( byte[] bytes, int channelId = Channels.DefaultReliable)
|
||||
{
|
||||
if (logNetworkMessages) { Debug.Log("ConnectionSend con:" + connectionId + " bytes:" + BitConverter.ToString(bytes)); }
|
||||
|
||||
|
@ -447,10 +447,17 @@ internal bool OnSerializeSafely(NetworkBehaviour comp, NetworkWriter writer, boo
|
||||
return result;
|
||||
}
|
||||
|
||||
// OnSerializeAllSafely is in hot path. caching the writer is really
|
||||
// worth it to avoid large amounts of allocations.
|
||||
static NetworkWriter onSerializeWriter = new NetworkWriter();
|
||||
|
||||
// serialize all components (or only dirty ones if not initial state)
|
||||
// -> returns serialized data of everything dirty, null if nothing was dirty
|
||||
internal byte[] OnSerializeAllSafely(bool initialState)
|
||||
{
|
||||
// reset cached writer's position
|
||||
onSerializeWriter.Position = 0;
|
||||
|
||||
if (m_NetworkBehaviours.Length > 64)
|
||||
{
|
||||
Debug.LogError("Only 64 NetworkBehaviour components are allowed for NetworkIdentity: " + name + " because of the dirtyComponentMask");
|
||||
@ -461,8 +468,7 @@ internal byte[] OnSerializeAllSafely(bool initialState)
|
||||
if (dirtyComponentsMask == 0L)
|
||||
return null;
|
||||
|
||||
NetworkWriter writer = new NetworkWriter();
|
||||
writer.WritePackedUInt64(dirtyComponentsMask); // WritePacked64 so we don't write full 8 bytes if we don't have to
|
||||
onSerializeWriter.WritePackedUInt64(dirtyComponentsMask); // WritePacked64 so we don't write full 8 bytes if we don't have to
|
||||
|
||||
foreach (NetworkBehaviour comp in m_NetworkBehaviours)
|
||||
{
|
||||
@ -473,7 +479,7 @@ internal byte[] OnSerializeAllSafely(bool initialState)
|
||||
{
|
||||
// serialize the data
|
||||
if (LogFilter.Debug) { Debug.Log("OnSerializeAllSafely: " + name + " -> " + comp.GetType() + " initial=" + initialState); }
|
||||
OnSerializeSafely(comp, writer, initialState);
|
||||
OnSerializeSafely(comp, onSerializeWriter, initialState);
|
||||
|
||||
// Clear dirty bits only if we are synchronizing data and not sending a spawn message.
|
||||
// This preserves the behavior in HLAPI
|
||||
@ -484,7 +490,7 @@ internal byte[] OnSerializeAllSafely(bool initialState)
|
||||
}
|
||||
}
|
||||
|
||||
return writer.ToArray();
|
||||
return onSerializeWriter.ToArray();
|
||||
}
|
||||
|
||||
private ulong GetDirtyMask(NetworkBehaviour[] components, bool initialState)
|
||||
@ -903,6 +909,11 @@ internal void Reset()
|
||||
clientAuthorityOwner = null;
|
||||
}
|
||||
|
||||
|
||||
// UNetUpdate is in hot path. caching the vars msg is really worth it to
|
||||
// avoid large amounts of allocations.
|
||||
static UpdateVarsMessage varsMessage = new UpdateVarsMessage();
|
||||
|
||||
// invoked by unity runtime immediately after the regular "Update()" function.
|
||||
internal void UNetUpdate()
|
||||
{
|
||||
@ -915,14 +926,10 @@ internal void UNetUpdate()
|
||||
byte[] payload = OnSerializeAllSafely(false);
|
||||
if (payload != null)
|
||||
{
|
||||
// construct message and send
|
||||
UpdateVarsMessage message = new UpdateVarsMessage
|
||||
{
|
||||
netId = netId,
|
||||
payload = payload
|
||||
};
|
||||
|
||||
NetworkServer.SendToReady(this, (short)MsgType.UpdateVars, message);
|
||||
// populate cached UpdateVarsMessage and send
|
||||
varsMessage.netId = netId;
|
||||
varsMessage.payload = payload;
|
||||
NetworkServer.SendToReady(this, (short)MsgType.UpdateVars, varsMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,10 +186,14 @@ static bool SendToObservers(NetworkIdentity identity, short msgType, MessageBase
|
||||
|
||||
if (identity != null && identity.observers != null)
|
||||
{
|
||||
// pack message into byte[] once
|
||||
byte[] bytes = Protocol.PackMessage((ushort)msgType, msg);
|
||||
|
||||
// send to all observers
|
||||
bool result = true;
|
||||
foreach (KeyValuePair<int, NetworkConnection> kvp in identity.observers)
|
||||
{
|
||||
result &= kvp.Value.Send(msgType, msg);
|
||||
result &= kvp.Value.SendBytes(bytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -200,10 +204,14 @@ public static bool SendToAll(short msgType, MessageBase msg, int channelId = Cha
|
||||
{
|
||||
if (LogFilter.Debug) { Debug.Log("Server.SendToAll id:" + msgType); }
|
||||
|
||||
// pack message into byte[] once
|
||||
byte[] bytes = Protocol.PackMessage((ushort)msgType, msg);
|
||||
|
||||
// send to all
|
||||
bool result = true;
|
||||
foreach (KeyValuePair<int, NetworkConnection> kvp in connections)
|
||||
{
|
||||
result &= kvp.Value.Send(msgType, msg, channelId);
|
||||
result &= kvp.Value.SendBytes(bytes, channelId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -214,12 +222,16 @@ public static bool SendToReady(NetworkIdentity identity, short msgType, MessageB
|
||||
|
||||
if (identity != null && identity.observers != null)
|
||||
{
|
||||
// pack message into byte[] once
|
||||
byte[] bytes = Protocol.PackMessage((ushort)msgType, msg);
|
||||
|
||||
// send to all ready observers
|
||||
bool result = true;
|
||||
foreach (KeyValuePair<int, NetworkConnection> kvp in identity.observers)
|
||||
{
|
||||
if (kvp.Value.isReady)
|
||||
{
|
||||
result &= kvp.Value.Send(msgType, msg, channelId);
|
||||
result &= kvp.Value.SendBytes(bytes, channelId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -98,22 +98,25 @@ public static class Channels
|
||||
// -> this reduces bandwidth by 10% if average message size is 20 bytes (probably even shorter)
|
||||
public static class Protocol
|
||||
{
|
||||
// PackMessage is in hot path. caching the writer is really worth it to
|
||||
// avoid large amounts of allocations.
|
||||
static NetworkWriter packWriter = new NetworkWriter();
|
||||
|
||||
// pack message before sending
|
||||
public static byte[] PackMessage(ushort msgType, byte[] content)
|
||||
// -> pass writer instead of byte[] so we can reuse it
|
||||
public static byte[] PackMessage(ushort msgType, MessageBase msg)
|
||||
{
|
||||
// original HLAPI's 'content' part is never null, so we don't have to handle that case.
|
||||
// just create an empty array if null.
|
||||
if (content == null) content = new byte[0];
|
||||
// reset cached writer's position
|
||||
packWriter.Position = 0;
|
||||
|
||||
NetworkWriter writer = new NetworkWriter();
|
||||
// write message type
|
||||
packWriter.WritePackedUInt32(msgType);
|
||||
|
||||
// message type (varint)
|
||||
writer.WritePackedUInt32(msgType);
|
||||
// serialize message into writer
|
||||
msg.Serialize(packWriter);
|
||||
|
||||
// message content (if any)
|
||||
writer.Write(content, 0, content.Length);
|
||||
|
||||
return writer.ToArray();
|
||||
// return byte[]
|
||||
return packWriter.ToArray();
|
||||
}
|
||||
|
||||
// unpack message after receiving
|
||||
|
@ -110,7 +110,7 @@ Start reading our code and you'll get the hang of it. We optimize for readabilit
|
||||
* **KISS / Occam's Razor** - always use the most simple solution.
|
||||
* **No Premature Optimizations**
|
||||
MMOs need to run for weeks without issues or exploits.
|
||||
If you want your code to run 1% faster, spend \$100 on a better CPU.
|
||||
Only do GC optimizations and caching in hot path. Avoid it everywhere else to keep the code simple.
|
||||
* **Curly Braces { }**
|
||||
Always use braces even for one line if's. Unity did this everywhere, and there is value in not accidentally missing a line in an if statement because there were no braces.
|
||||
* **Variable naming**
|
||||
|
Loading…
Reference in New Issue
Block a user