forked from bthomas2622/facepunch-steamworks-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SteamSocketsStuff.cs
198 lines (179 loc) · 6.45 KB
/
SteamSocketsStuff.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Code for SteamNetworkingSockets which replaced SteamNetworking P2P code SteamManager
// SOCKET CLASS that creates socket server, only host of each match utilizes this
public class SteamSocketManager : SocketManager
{
public override void OnConnecting(Connection connection, ConnectionInfo data)
{
base.OnConnecting(connection, data);//The base class will accept the connection
Debug.Log("SocketManager OnConnecting");
}
public override void OnConnected(Connection connection, ConnectionInfo data)
{
base.OnConnected(connection, data);
Debug.Log("New player connecting");
}
public override void OnDisconnected(Connection connection, ConnectionInfo data)
{
base.OnDisconnected(connection, data);
Debug.Log("Player disconnected");
}
public override void OnMessage(Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel)
{
// Socket server received message, forward on message to all members of socket server
SteamManager.Instance.RelaySocketMessageReceived(data, size, connection.Id);
Debug.Log("Socket message received");
}
}
// CONNECTION MANAGER that enables all players to connect to Socket Server
public class SteamConnectionManager : ConnectionManager
{
public override void OnConnected(ConnectionInfo info)
{
base.OnConnected(info);
Debug.Log("ConnectionOnConnected");
}
public override void OnConnecting(ConnectionInfo info)
{
base.OnConnecting(info);
Debug.Log("ConnectionOnConnecting");
}
public override void OnDisconnected(ConnectionInfo info)
{
base.OnDisconnected(info);
Debug.Log("ConnectionOnDisconnected");
}
public override void OnMessage(IntPtr data, int size, long messageNum, long recvTime, int channel)
{
// Message received from socket server, delegate to method for processing
SteamManager.Instance.ProcessMessageFromSocketServer(data, size);
Debug.Log("Connection Got A Message");
}
}
// SteamManager.cs code/ methods that facilitate sending and receiving messages to and from Socket server
public void Awake()
{
// Helpful to reduce time to use SteamNetworkingSockets later
SteamNetworkingUtils.InitRelayNetworkAccess();
}
void Update()
{
SteamClient.RunCallbacks();
try
{
if (activeSteamSocketServer)
{
steamSocketManager.Receive();
}
if (activeSteamSocketConnection)
{
steamConnectionManager.Receive();
}
}
catch
{
Debug.Log("Error receiving data on socket/connection");
}
}
private void CreateSteamSocketServer()
{
steamSocketManager = SteamNetworkingSockets.CreateRelaySocket<SteamSocketManager>(0);
// Host needs to connect to own socket server with a ConnectionManager to send/receive messages
// Relay Socket servers are created/connected to through SteamIds rather than "Normal" Socket Servers which take IP addresses
steamConnectionManager = SteamNetworkingSockets.ConnectRelay<SteamConnectionManager>(PlayerSteamId);
activeSteamSocketServer = true;
activeSteamSocketConnection = true;
}
private void JoinSteamSocketServer()
{
if (NOT_HOST)
{
Debug.Log("joining socket server");
steamConnectionManager = SteamNetworkingSockets.ConnectRelay<SteamConnectionManager>(OpponentSteamId, 0);
activeSteamSocketServer = false;
activeSteamSocketConnection = true;
}
}
private void LeaveSteamSocketServer()
{
activeSteamSocketServer = false;
activeSteamSocketConnection = false;
try
{
// Shutdown connections/sockets. I put this in try block because if player 2 is leaving they don't have a socketManager to close, only connection
steamConnectionManager.Close();
steamSocketManager.Close();
}
catch
{
Debug.Log("Error closing socket server / connection manager");
}
}
public void RelaySocketMessageReceived(IntPtr message, int size, uint connectionSendingMessageId)
{
try
{
// Loop to only send messages to socket server members who are not the one that sent the message
for (int i = 0; i < steamSocketManager.Connected.Count; i++)
{
if (steamSocketManager.Connected[i].Id != connectionSendingMessageId)
{
Result success = steamSocketManager.Connected[i].SendMessage(message, size);
if (success != Result.OK)
{
Result retry = steamSocketManager.Connected[i].SendMessage(message, size);
}
}
}
}
catch
{
Debug.Log("Unable to relay socket server message");
}
}
public bool SendMessageToSocketServer(byte[] messageToSend)
{
try
{
// Convert string/byte[] message into IntPtr data type for efficient message send / garbage management
int sizeOfMessage = messageToSend.Length;
IntPtr intPtrMessage = System.Runtime.InteropServices.Marshal.AllocHGlobal(sizeOfMessage);
System.Runtime.InteropServices.Marshal.Copy(messageToSend, 0, intPtrMessage, sizeOfMessage);
Result success = steamConnectionManager.Connection.SendMessage(intPtrMessage, sizeOfMessage, SendType.Reliable);
if (success == Result.OK)
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(intPtrMessage); // Free up memory at pointer
return true;
}
else
{
// RETRY
Result retry = steamConnectionManager.Connection.SendMessage(intPtrMessage, sizeOfMessage, SendType.Reliable);
System.Runtime.InteropServices.Marshal.FreeHGlobal(intPtrMessage); // Free up memory at pointer
if (retry == Result.OK)
{
return true;
}
return false;
}
}
catch (Exception e)
{
Debug.Log(e.Message);
Debug.Log("Unable to send message to socket server");
return false;
}
}
public void ProcessMessageFromSocketServer(IntPtr messageIntPtr, int dataBlockSize)
{
try
{
byte[] message = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(messageIntPtr, message, 0, dataBlockSize);
string messageString = System.Text.Encoding.UTF8.GetString(message);
// Do something with received message
}
catch
{
Debug.Log("Unable to process message from socket server");
}
}