internal KartMap(serverinfo_pak srv) { unsafe { InternalName = KartUtils.DecodeString(srv.mapname, serverinfo_pak.MAX_MAP_NAME_LENGTH); Title = KartUtils.DecodeString(srv.maptitle, serverinfo_pak.MAX_MAP_TITLE_LENGTH); MD5 = new byte[16]; for (var i = 0; i < 16; i++) { MD5[i] = srv.mapmd5[i]; } } ActNumber = srv.actnum; IsZone = srv.iszone == 0 || srv.iszone == 1 ? srv.iszone == 1 : throw new ArgumentOutOfRangeException(nameof(srv.iszone)); TimeElapsed = TimeSpan.FromSeconds(srv.leveltime / (double)KartUtils.SRB2_TICRATE); }
internal KartServer(serverinfo_pak srv, IEnumerable <plrinfo> players, IEnumerable <(string Filename, byte[] Md5)> neededFiles)
/// <summary> /// Attempts to query an SRB2Kart server for information. /// </summary> /// <param name="endpoint">The endpoint (IP address and port) of the server.</param> /// <returns>A <see cref="KartServer"/> object representing server query information.</returns> public static KartServer QueryServer(IPEndPoint endpoint) { using var client = new UdpClient(endpoint.Port) { Client = { ReceiveTimeout = (int)QueryTimeout } }; client.Connect(endpoint); // ask for server info SendPacket(client, (byte)PT_ASKINFO, new byte[] { 0, 0, 0, 0, 0 }); var remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); var start = 0u; var morePackets = true; var srv = new serverinfo_pak(); var players = new List <plrinfo>(); var neededFiles = new List <(string Filename, byte[] Md5)>(); while (morePackets) { var received = client.Receive(ref remoteEndpoint); var stream = new MemoryStream(received); var header = ReadPacketComponent <doomdata_t>(stream); var type = (packettype_t)header.packettype; var timeout = 0; switch (type) { case PT_SERVERINFO: // 13 srv = ReadPacketComponent <serverinfo_pak>(stream); break; case PT_PLAYERINFO: // 14 for (var i = 0; i < 16; i++) { players.Add(ReadPacketComponent <plrinfo>(stream)); } SendPacket(client, (byte)PT_TELLFILESNEEDED, BitConverter.GetBytes(start)); break; case PT_MOREFILESNEEDED: var filesNeeded = ReadPacketComponent <filesneededconfig_pak>(stream); start += filesNeeded.num; neededFiles.AddRange(GetFilesNeeded(received)); if (filesNeeded.more == 1) { // ask for more files SendPacket(client, (byte)PT_TELLFILESNEEDED, BitConverter.GetBytes(start)); } else { morePackets = false; } break; default: if (++timeout == 5) // 5 invalid packets in a row { throw new Exception("Received 5 invalid response packets in a row."); } break; } } return(new KartServer(srv, players, neededFiles)); }