protected override async Task <bool> PostServerInfoAsync(GameServer discordGameServer) { if (discordGameServer == null) { return(false); } MineQuery query = null; try { query = new MineQuery(discordGameServer.ServerIP.Address, discordGameServer.ServerIP.Port, logger); MineQueryResult serverInfo = await query.GetServerInfoAsync().ConfigureAwait(false); if (serverInfo == null) { return(false); } SocketGuild guild = discordClient?.GetGuild(discordGameServer.GuildID); SocketTextChannel channel = guild?.GetTextChannel(discordGameServer.ChannelID); if (guild == null || channel == null) { return(false); } EmbedBuilder builder = new EmbedBuilder() .WithColor(new Color(21, 26, 35)) .WithTitle($"Minecraft Server ({discordGameServer.ServerIP.Address}:{discordGameServer.ServerIP.Port})") .WithDescription($"Motd: {serverInfo.Description.Motd}"); _ = serverInfo.Players.Sample != null && serverInfo.Players.Sample.Count > 0 ? builder.AddField($"Online Players ({serverInfo.Players.Online}/{serverInfo.Players.Max})", string.Join(", ", serverInfo.Players.Sample.Select(x => x.Name))) : builder.AddField("Online Players", $"{serverInfo.Players.Online}/{serverInfo.Players.Max}"); if (discordGameServer.GameVersion.IsEmpty()) { discordGameServer.GameVersion = serverInfo.Version.Name; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } else { if (serverInfo.Version.Name != discordGameServer.GameVersion) { discordGameServer.GameVersion = serverInfo.Version.Name; discordGameServer.LastVersionUpdate = DateTime.Now; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } } string lastServerUpdate = ""; if (discordGameServer.LastVersionUpdate.HasValue) { lastServerUpdate = $" (Last update: {discordGameServer.LastVersionUpdate.Value})"; } _ = builder.WithFooter($"Server version: {serverInfo.Version.Name}{lastServerUpdate} || Last check: {DateTime.Now}"); // Generate chart every full 10 minutes if (DateTime.Now.Minute % 10 == 0) { string chart = await GenerateHistoryChartAsync(discordGameServer, serverInfo.Players.Online, serverInfo.Players.Max).ConfigureAwait(false); if (!chart.IsEmptyOrWhiteSpace()) { _ = builder.AddField("Player Count History", chart); } } if (discordGameServer.MessageID.HasValue) { if (await channel.GetMessageAsync(discordGameServer.MessageID.Value).ConfigureAwait(false) is IUserMessage existingMessage && existingMessage != null) { await existingMessage.ModifyAsync(x => x.Embed = builder.Build()).ConfigureAwait(false); } else { logger.LogWarning($"Error getting updates for server {discordGameServer.ServerIP}. Original message was removed."); await RemoveServerAsync(discordGameServer.ServerIP, discordGameServer.GuildID).ConfigureAwait(false); _ = await channel.SendMessageAsync($"Error getting updates for server {discordGameServer.ServerIP}. Original message was removed. Please use the proper remove command to remove the gameserver").ConfigureAwait(false); return(false); } } else { IUserMessage message = await(channel?.SendMessageAsync("", false, builder.Build())).ConfigureAwait(false); discordGameServer.MessageID = message.Id; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } }
public async Task <MineQueryResult> GetServerInfoAsync() { await client.ConnectAsync(Address, Port).ConfigureAwait(false); if (!client.Connected) { return(null); } writeBuffer = new List <byte>(); NetworkStream stream = client.GetStream(); //Send a "Handshake" packet http://wiki.vg/Server_List_Ping#Ping_Process WriteVarInt(47); WriteString(Address.ToString()); WriteShort(25565); WriteVarInt(1); Flush(stream, 0); // Send a "Status Request" packet http://wiki.vg/Server_List_Ping#Ping_Process Flush(stream, 0); byte[] readBuffer = new byte[1024]; var completeBuffer = new List <byte>(); int numberOfBytesRead; do { numberOfBytesRead = await stream.ReadAsync(readBuffer).ConfigureAwait(false); completeBuffer.AddRange(readBuffer.Take(numberOfBytesRead)); }while (numberOfBytesRead > 0); try { byte[] b = completeBuffer.ToArray(); int length = ReadVarInt(b); int packet = ReadVarInt(b); int jsonLength = ReadVarInt(b); if (jsonLength > completeBuffer.Count - offset) { //TODO: log receive error return(null); } string json = ReadString(b, jsonLength); MineQueryResult result = JsonSerializer.Deserialize <MineQueryResult>(json); return(result); } catch (IOException ex) { logger.LogError(ex, $"Couldn't get MineCraft server info for {Address}:{Port}"); return(null); } finally { client.Close(); stream.Dispose(); } }