private static void ClientRun(object o) { var id = (int)o; var managedClient = _clients[id]; // keep track of client state so we can notify application of state changes var prevState = managedClient.client.State; while (managedClient.shouldRun) { managedClient.client.Update(managedClient.time); if (managedClient.client.State != prevState) { prevState = managedClient.client.State; PostStateChange(id); } if (managedClient.client.State == ClientState.Connected) { byte[] packetData; while (managedClient.pendingPackets.TryDequeue(out packetData)) { managedClient.client.SendPacket(packetData); } } while (true) { var packet = managedClient.client.ReceivePacket(); if (packet == null) { break; } WriteMessage(new JArray { JValue.FromObject(TypeReceivePacket), JValue.FromObject(id), JValue.FromObject(Convert.ToBase64String(packet)), }); } var deltaTime = 1.0 / (double)managedClient.tickRate; NetcodeLibrary.Sleep(deltaTime); managedClient.time += deltaTime; } WriteMessage(new JArray { JValue.FromObject(TypeClientDestroyed), JValue.FromObject(id), }); _clients.Remove(id); managedClient.client.Dispose(); }
public static Tuple <int, byte[]> SendResponse(HttpListenerRequest request, HttpListenerResponse response) { if (request.Url.AbsolutePath == "/") { response.ContentType = "text/html"; var asmPath = Assembly.GetExecutingAssembly().Location; var indexPath = Path.Combine(new FileInfo(asmPath).DirectoryName, "index.htm"); using (var reader = new StreamReader(indexPath)) { return(new Tuple <int, byte[]>(200, Encoding.UTF8.GetBytes(reader.ReadToEnd().Replace("__PROTOCOL__", isServerIpv4 ? "ipv4" : "ipv6")))); } } if (request.Url.AbsolutePath == "/basic") { response.ContentType = "text/html"; var asmPath = Assembly.GetExecutingAssembly().Location; var indexPath = Path.Combine(new FileInfo(asmPath).DirectoryName, "basic.htm"); using (var reader = new StreamReader(indexPath)) { return(new Tuple <int, byte[]>(200, Encoding.UTF8.GetBytes(reader.ReadToEnd().Replace("__PROTOCOL__", isServerIpv4 ? "ipv4" : "ipv6")))); } } if (request.Url.AbsolutePath == "/token") { response.ContentType = "text/plain"; var clientId = NetcodeLibrary.GetRandomUInt64(); var token = NetcodeLibrary.GenerateConnectTokenFromPrivateKey( new[] { serverAddress + ":" + serverPort }, 30, clientId, 0x1122334455667788L, 0, _privateKey); return(new Tuple <int, byte[]>(200, Encoding.UTF8.GetBytes(Convert.ToBase64String(token)))); } if (request.Url.AbsolutePath == "/netcode-support.xpi") { response.ContentType = "application/x-xpinstall"; var asmPath = Assembly.GetExecutingAssembly().Location; var xpiPath = Path.Combine(new FileInfo(asmPath).DirectoryName, "netcodeio_support_self_dist-0.1.5-fx.xpi"); using (var reader = new FileStream(xpiPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var b = new byte[reader.Length]; reader.Read(b, 0, b.Length); return(new Tuple <int, byte[]>(200, b)); } } return(new Tuple <int, byte[]>(404, Encoding.UTF8.GetBytes("404 not found"))); }
private static void NetcodeServer() { NetcodeLibrary.SetLogLevel(NetcodeLogLevel.Info); double time = 0f; double deltaTime = 1.0 / 60.0; var server = new Server( serverAddress + ":" + serverPort, 0x1122334455667788L, _privateKey, 0); server.Start(NetcodeLibrary.GetMaxClients()); lastPacketMessage = new byte[NetcodeLibrary.GetMaxClients()][]; while (running) { server.Update(time); for (var clientIndex = 0; clientIndex < NetcodeLibrary.GetMaxClients(); clientIndex++) { if (server.ClientConnected(clientIndex) && lastPacketMessage[clientIndex] != null) { server.SendPacket(clientIndex, lastPacketMessage[clientIndex]); lastPacketMessage[clientIndex] = null; } } for (var clientIndex = 0; clientIndex < NetcodeLibrary.GetMaxClients(); clientIndex++) { while (true) { var packet = server.ReceivePacket(clientIndex); if (packet == null) { break; } lastPacketMessage[clientIndex] = packet; } } NetcodeLibrary.Sleep(deltaTime); time += deltaTime; } server.Dispose(); }
public static string SendResponse(HttpListenerRequest request, HttpListenerResponse response) { if (request.Url.AbsolutePath == "/") { response.ContentType = "text/html"; var asmPath = Assembly.GetExecutingAssembly().Location; var indexPath = Path.Combine(new FileInfo(asmPath).DirectoryName, "index.htm"); using (var reader = new StreamReader(indexPath)) { return(reader.ReadToEnd().Replace("__PROTOCOL__", isServerIpv4 ? "ipv4" : "ipv6")); } } if (request.Url.AbsolutePath == "/basic") { response.ContentType = "text/html"; var asmPath = Assembly.GetExecutingAssembly().Location; var indexPath = Path.Combine(new FileInfo(asmPath).DirectoryName, "basic.htm"); using (var reader = new StreamReader(indexPath)) { return(reader.ReadToEnd().Replace("__PROTOCOL__", isServerIpv4 ? "ipv4" : "ipv6")); } } if (request.Url.AbsolutePath == "/token") { response.ContentType = "text/plain"; var clientId = NetcodeLibrary.GetRandomUInt64(); var token = NetcodeLibrary.GenerateConnectTokenFromPrivateKey( new[] { serverAddress + ":" + serverPort }, 30, clientId, 0x1122334455667788L, 0, _privateKey); return(Convert.ToBase64String(token)); } return("404 not found"); }
public static void Main(string[] args) { const UInt64 testProtocolId = 0x1122334455667788L; double time = 0f; double deltaTime = 1.0 / 60.0; bool quit = false; Console.CancelKeyPress += (sender, a) => { quit = true; }; NetcodeLibrary.SetLogLevel(NetcodeLogLevel.Info); var server = new Server( "127.0.0.1:40000", testProtocolId, privateKey, time); var maxPacketSize = NetcodeLibrary.GetMaxPacketSize(); var packetData = new byte[maxPacketSize]; for (var i = 0; i < maxPacketSize; i++) { packetData[i] = (byte)i; } server.Start(NetcodeLibrary.GetMaxClients()); while (!quit) { server.Update(time); if (server.ClientConnected(0)) { server.SendPacket(0, packetData); } for (var clientIndex = 0; clientIndex < NetcodeLibrary.GetMaxClients(); ++clientIndex) { while (true) { var packet = server.ReceivePacket(clientIndex); if (packet == null) { break; } if (packet.Length != packetData.Length) { Console.Error.WriteLine("Packet doesn't have expected length!"); } else { for (var i = 0; i < maxPacketSize; i++) { if (packet[i] != packetData[i]) { Console.Error.WriteLine($"Packet differs at index {i}!"); } } } } } NetcodeLibrary.Sleep(deltaTime); time += deltaTime; } if (quit) { Console.WriteLine("Shutting down"); } server.Dispose(); }
public static void Main(string[] args) { const int testConnectTokenExpiry = 30; const UInt64 testProtocolId = 0x1122334455667788L; double time = 0f; double deltaTime = 1.0 / 60.0; bool validatedServer = false; bool validatedClient = false; DateTime startTime = DateTime.UtcNow; NetcodeLibrary.SetLogLevel(NetcodeLogLevel.Info); var server = new Server( "127.0.0.1:40000", testProtocolId, privateKey, time); server.Start(NetcodeLibrary.GetMaxClients()); var client = new Client( "127.0.0.1", time); var clientId = NetcodeLibrary.GetRandomUInt64(); Console.WriteLine($"client id is {clientId:X}"); var serverAddress = "127.0.0.1:40000"; byte[] connectToken = NetcodeLibrary.GenerateConnectTokenFromPrivateKey( new[] { serverAddress }, testConnectTokenExpiry, clientId, testProtocolId, 0, privateKey); client.Connect(connectToken); var maxPacketSize = NetcodeLibrary.GetMaxPacketSize(); var serverPacketData = new byte[maxPacketSize]; var clientPacketData = new byte[maxPacketSize]; for (var i = 0; i < maxPacketSize; i++) { serverPacketData[i] = (byte)i; clientPacketData[i] = (byte)i; } while ((!validatedServer || !validatedClient) && (DateTime.UtcNow - startTime).TotalSeconds < 30) { server.Update(time); if (server.ClientConnected(0)) { server.SendPacket(0, serverPacketData); } for (var clientIndex = 0; clientIndex < NetcodeLibrary.GetMaxClients(); ++clientIndex) { while (true) { var packet = server.ReceivePacket(clientIndex); if (packet == null) { break; } var matches = true; if (packet.Length != clientPacketData.Length) { Console.Error.WriteLine("Packet doesn't have expected length!"); matches = false; } else { for (var i = 0; i < maxPacketSize; i++) { if (packet[i] != clientPacketData[i]) { Console.Error.WriteLine($"Packet differs at index {i}!"); matches = false; } } } if (matches) { validatedServer = true; } } } client.Update(time); if (client.State == ClientState.Connected) { client.SendPacket(clientPacketData); } while (true) { var packet = client.ReceivePacket(); if (packet == null) { break; } var matches = true; if (packet.Length != serverPacketData.Length) { Console.Error.WriteLine("Packet doesn't have expected length!"); matches = false; } else { for (var i = 0; i < maxPacketSize; i++) { if (packet[i] != serverPacketData[i]) { Console.Error.WriteLine($"Packet differs at index {i}!"); matches = false; } } } if (matches) { validatedClient = true; } } if (client.State <= ClientState.Disconnected) { break; } NetcodeLibrary.Sleep(deltaTime); time += deltaTime; } if ((DateTime.UtcNow - startTime).TotalSeconds > 30) { Console.Error.WriteLine("Timed out after 30 seconds."); Environment.Exit(1); } if (!validatedClient || !validatedServer) { Console.Error.WriteLine("Not in a valid state when exiting loop."); Environment.Exit(1); } client.Dispose(); server.Dispose(); Console.WriteLine("Test passed."); Environment.Exit(0); }
static void Main(string[] args) { _clients = new Dictionary <int, ManagedClient>(); _random = new Random(); _outWriter = new BinaryWriter(Console.OpenStandardOutput()); _writerLock = new object(); bool quit = false; Console.CancelKeyPress += (sender, a) => { quit = true; }; NetcodeLibrary.SetLogLevel(NetcodeLogLevel.None); using (var reader = new BinaryReader(Console.OpenStandardInput())) { while (!quit) { try { var size = reader.ReadInt32(); var bytes = reader.ReadBytes(size); var json = Encoding.UTF8.GetString(bytes); var messageArray = JsonConvert.DeserializeObject <JArray>(json); var messageType = messageArray[0].Value <int>(); var messageId = messageArray[1].Value <int>(); try { switch (messageType) { case TypeCheckPresence: { WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), JValue.FromObject(HelperVersion), }); break; } case TypeCreateClient: { var id = _random.Next(); while (_clients.ContainsKey(id)) { id = _random.Next(); } var isIpV6 = false; if (messageArray.Count >= 3) { isIpV6 = messageArray[2].Value <bool>(); } _clients[id] = new ManagedClient { client = new Client(isIpV6 ? "::" : "0.0.0.0", 0), tickRate = 60, shouldRun = true, time = 0, pendingPackets = new ConcurrentQueue <byte[]>(), }; _clients[id].thread = new Thread(ClientRun); _clients[id].thread.IsBackground = true; _clients[id].thread.Start(id); WriteMessage(new JArray { JValue.FromObject(ResultClientCreated), JValue.FromObject(messageId), JValue.FromObject(id), }); break; } case TypeSetClientTickRate: { var id = messageArray[2].Value <int>(); var tickRate = messageArray[3].Value <int>(); _clients[id].tickRate = tickRate; WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), }); break; } case TypeConnectClient: { var id = messageArray[2].Value <int>(); var connectTokenBase64 = messageArray[3].Value <string>(); _clients[id].client.Connect(Convert.FromBase64String(connectTokenBase64)); WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), }); break; } case TypeSendPacket: { var id = messageArray[2].Value <int>(); var packetData = messageArray[3].Value <string>(); _clients[id].pendingPackets.Enqueue(Convert.FromBase64String(packetData)); WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), }); break; } case TypeGetClientState: { var id = messageArray[2].Value <int>(); string state; switch (_clients[id].client.State) { case ClientState.Connected: state = "connected"; break; case ClientState.ConnectionDenied: state = "connectionDenied"; break; case ClientState.ConnectionRequestTimeout: state = "connectionRequestTimeout"; break; case ClientState.ConnectionResponseTimeout: state = "connectionResponseTimeout"; break; case ClientState.ConnectionTimedOut: state = "connectionTimedOut"; break; case ClientState.ConnectTokenExpired: state = "connectTokenExpired"; break; case ClientState.Disconnected: state = "disconnected"; break; case ClientState.InvalidConnectToken: state = "invalidConnectToken"; break; case ClientState.SendingConnectionRequest: state = "sendingConnectionRequest"; break; case ClientState.SendingConnectionResponse: state = "sendingConnectionResponse"; break; default: state = "unknown"; break; } WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), JValue.FromObject(state), }); break; } case TypeDestroyClient: { var id = messageArray[2].Value <int>(); _clients[id].shouldRun = false; WriteMessage(new JArray { JValue.FromObject(ResultSuccess), JValue.FromObject(messageId), }); break; } } } catch (Exception ex) { WriteMessage(new JArray { JValue.FromObject(ResultErrorInternal), JValue.FromObject(messageId), JValue.FromObject(ex.ToString()), }); } } catch (EndOfStreamException) { // Requested to close by browser process. return; } } } }
public static void Main(string[] args) { const int testConnectTokenExpiry = 30; const UInt64 testProtocolId = 0x1122334455667788L; double time = 0f; double deltaTime = 1.0 / 60.0; bool quit = false; Console.CancelKeyPress += (sender, a) => { quit = true; }; NetcodeLibrary.SetLogLevel(NetcodeLogLevel.Info); Console.WriteLine("[client]"); var client = new Client( "0.0.0.0", time); var clientId = NetcodeLibrary.GetRandomUInt64(); Console.WriteLine($"client id is {clientId:X}"); var serverAddress = "127.0.0.1:40000"; byte[] connectToken = NetcodeLibrary.GenerateConnectTokenFromPrivateKey( new[] { serverAddress }, testConnectTokenExpiry, clientId, testProtocolId, 0, privateKey); client.Connect(connectToken); var maxPacketSize = NetcodeLibrary.GetMaxPacketSize(); var packetData = new byte[maxPacketSize]; for (var i = 0; i < maxPacketSize; i++) { packetData[i] = (byte)i; } while (!quit) { client.Update(time); if (client.State == ClientState.Connected) { client.SendPacket(packetData); } while (true) { var packet = client.ReceivePacket(); if (packet == null) { break; } if (packet.Length != packetData.Length) { Console.Error.WriteLine("Packet doesn't have expected length!"); } else { for (var i = 0; i < maxPacketSize; i++) { if (packet[i] != packetData[i]) { Console.Error.WriteLine($"Packet differs at index {i}!"); } } } } if (client.State <= ClientState.Disconnected) { break; } NetcodeLibrary.Sleep(deltaTime); time += deltaTime; } if (quit) { Console.WriteLine("Shutting down"); } client.Dispose(); }