Skip to content

Commit 06063cc

Browse files
update
migrating SinglePlayerTransport into a subfolder of Transports.
1 parent 920f38f commit 06063cc

File tree

5 files changed

+149
-147
lines changed

5 files changed

+149
-147
lines changed

com.unity.netcode.gameobjects/Runtime/Components/Transport/SinglePlayerTransport.cs

Lines changed: 0 additions & 146 deletions
This file was deleted.

com.unity.netcode.gameobjects/Runtime/Components/Transport.meta renamed to com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Unity.Netcode.Transports.SinglePlayer
5+
{
6+
/// <summary>
7+
/// A transport that can be used to run a Netcode for GameObjects session in "single player" mode
8+
/// by assigning this transport to the <see cref="NetworkConfig.NetworkTransport"/> property before
9+
/// starting as a host.
10+
/// </summary>
11+
/// <remarks>
12+
/// You can only start as a host when using this transport.
13+
/// </remarks>
14+
public class SinglePlayerTransport : NetworkTransport
15+
{
16+
/// <inheritdoc/>
17+
public override ulong ServerClientId { get; } = 0;
18+
19+
internal static string NotStartingAsHostErrorMessage = $"When using {nameof(SinglePlayerTransport)}, you must start a hosted session so both client and server are available locally.";
20+
21+
private struct MessageData
22+
{
23+
public ulong FromClientId;
24+
public ArraySegment<byte> Payload;
25+
public NetworkEvent Event;
26+
public float AvailableTime;
27+
}
28+
29+
private static Dictionary<ulong, Queue<MessageData>> s_MessageQueue = new Dictionary<ulong, Queue<MessageData>>();
30+
31+
private bool m_Initialized;
32+
private ulong m_TransportId = 0;
33+
private NetworkManager m_NetworkManager;
34+
35+
36+
/// <inheritdoc/>
37+
public override void Send(ulong clientId, ArraySegment<byte> payload, NetworkDelivery networkDelivery)
38+
{
39+
var copy = new byte[payload.Array.Length];
40+
Array.Copy(payload.Array, copy, payload.Array.Length);
41+
s_MessageQueue[clientId].Enqueue(new MessageData
42+
{
43+
FromClientId = m_TransportId,
44+
Payload = new ArraySegment<byte>(copy, payload.Offset, payload.Count),
45+
Event = NetworkEvent.Data,
46+
AvailableTime = (float)m_NetworkManager.LocalTime.FixedTime,
47+
});
48+
}
49+
50+
/// <inheritdoc/>
51+
public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
52+
{
53+
if (s_MessageQueue[m_TransportId].Count > 0)
54+
{
55+
var data = s_MessageQueue[m_TransportId].Peek();
56+
if (data.AvailableTime > m_NetworkManager.LocalTime.FixedTime)
57+
{
58+
clientId = 0;
59+
payload = new ArraySegment<byte>();
60+
receiveTime = 0;
61+
return NetworkEvent.Nothing;
62+
}
63+
64+
s_MessageQueue[m_TransportId].Dequeue();
65+
clientId = data.FromClientId;
66+
payload = data.Payload;
67+
receiveTime = m_NetworkManager.LocalTime.TimeAsFloat;
68+
if (m_NetworkManager.IsServer && data.Event == NetworkEvent.Connect)
69+
{
70+
s_MessageQueue[data.FromClientId].Enqueue(new MessageData { Event = NetworkEvent.Connect, FromClientId = ServerClientId, Payload = new ArraySegment<byte>() });
71+
}
72+
return data.Event;
73+
}
74+
clientId = 0;
75+
payload = new ArraySegment<byte>();
76+
receiveTime = 0;
77+
return NetworkEvent.Nothing;
78+
}
79+
80+
/// <inheritdoc/>
81+
/// <remarks>
82+
/// This will always return false for <see cref="SinglePlayerTransport"/>.
83+
/// Always use <see cref="StartServer"/>.
84+
/// </remarks>
85+
public override bool StartClient()
86+
{
87+
NetworkLog.LogError(NotStartingAsHostErrorMessage);
88+
return false;
89+
}
90+
91+
/// <inheritdoc/>
92+
/// <remarks>
93+
/// Always use <see cref="NetworkManager.StartHost"/> when hosting a local single player session.
94+
/// </remarks>
95+
public override bool StartServer()
96+
{
97+
s_MessageQueue[ServerClientId] = new Queue<MessageData>();
98+
if (!m_NetworkManager.LocalClient.IsHost && m_NetworkManager.LocalClient.IsServer)
99+
{
100+
NetworkLog.LogError(NotStartingAsHostErrorMessage);
101+
return false;
102+
}
103+
return true;
104+
}
105+
106+
/// <inheritdoc/>
107+
public override void DisconnectRemoteClient(ulong clientId)
108+
{
109+
s_MessageQueue[clientId].Enqueue(new MessageData { Event = NetworkEvent.Disconnect, FromClientId = m_TransportId, Payload = new ArraySegment<byte>() });
110+
}
111+
112+
/// <inheritdoc/>
113+
public override void DisconnectLocalClient()
114+
{
115+
s_MessageQueue[ServerClientId].Enqueue(new MessageData { Event = NetworkEvent.Disconnect, FromClientId = m_TransportId, Payload = new ArraySegment<byte>() });
116+
}
117+
118+
/// <inheritdoc/>
119+
/// <remarks>
120+
/// Will always return 0 since this transport is for a local single player session.
121+
/// </remarks>
122+
public override ulong GetCurrentRtt(ulong clientId)
123+
{
124+
return 0;
125+
}
126+
127+
/// <inheritdoc/>
128+
public override void Shutdown()
129+
{
130+
s_MessageQueue.Clear();
131+
m_TransportId = 0;
132+
}
133+
134+
/// <inheritdoc/>
135+
protected override NetworkTopologyTypes OnCurrentTopology()
136+
{
137+
return m_NetworkManager != null ? m_NetworkManager.NetworkConfig.NetworkTopology : NetworkTopologyTypes.ClientServer;
138+
}
139+
140+
/// <inheritdoc/>
141+
public override void Initialize(NetworkManager networkManager = null)
142+
{
143+
s_MessageQueue.Clear();
144+
m_NetworkManager = networkManager;
145+
}
146+
}
147+
}

com.unity.netcode.gameobjects/Tests/Runtime/Transports/SinglePlayerTransportTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections;
33
using System.Collections.Generic;
44
using NUnit.Framework;
5+
using Unity.Netcode.Transports.SinglePlayer;
56
using Unity.Netcode.TestHelpers.Runtime;
67
using UnityEngine;
78
using UnityEngine.TestTools;

0 commit comments

Comments
 (0)