Skip to content

Commit

Permalink
Merge pull request #42 from GravityWolfNotAmused/dev
Browse files Browse the repository at this point in the history
1.0.9.1 Battle Metrics Update
  • Loading branch information
GravityWolfNotAmused authored Sep 10, 2022
2 parents 3e28bde + 0bbf35a commit 4811d6b
Show file tree
Hide file tree
Showing 35 changed files with 493 additions and 320 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
name: "CodeQL"

on:
push:
branches: [ "dev" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "dev" ]
Expand Down
14 changes: 14 additions & 0 deletions DiscordPlayerCountBot/Attributes/AttributeHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Linq;

namespace DiscordPlayerCountBot.Attributes
{
public static class AttributeHelper
{
public static string GetNameFromAttribute(object obj)
{
var nameAttribute = obj.GetType().GetCustomAttributes(true).Where(attribute => attribute.GetType() == typeof(NameAttribute)).Cast<NameAttribute>().FirstOrDefault();
var label = nameAttribute?.Name ?? obj.GetType().Name;
return label;
}
}
}
2 changes: 1 addition & 1 deletion DiscordPlayerCountBot/Attributes/NameAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace DiscordPlayerCountBot.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
public class NameAttribute : Attribute
{
public string Name { get; set; }
Expand Down
47 changes: 10 additions & 37 deletions DiscordPlayerCountBot/Bot/Bot.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Discord;
using Discord.WebSocket;
using DiscordPlayerCountBot;
using DiscordPlayerCountBot.Enum;
using DiscordPlayerCountBot.Http;
using DiscordPlayerCountBot.Providers;
using DiscordPlayerCountBot.Providers.Base;
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
Expand All @@ -19,16 +19,16 @@ public class Bot
public BotInformation Information { get; set; }
public DiscordSocketClient DiscordClient { get; set; }
public Dictionary<int, IServerInformationProvider> DataProviders { get; set; } = new();
public Dictionary<string, string> ApplicationTokens { get; set; } = new();

private ILog Logger = LogManager.GetLogger(typeof(Bot));

public Bot(BotInformation info)
public Bot(BotInformation info, Dictionary<string, string> applicationTokens)
{
if (info is null)
{
throw new ArgumentNullException(nameof(info));
}
if (info is null) throw new ArgumentNullException(nameof(info));
if (applicationTokens is null) throw new ArgumentException(nameof(applicationTokens));

ApplicationTokens = applicationTokens;
Information = info;

DiscordClient = new DiscordSocketClient(new DiscordSocketConfig()
Expand All @@ -45,23 +45,18 @@ public void InitDataProviders()
DataProviders.Add((int)DataProvider.CFX, new CFXProvider());
DataProviders.Add((int)DataProvider.SCUM, new ScumProvider());
DataProviders.Add((int)DataProvider.MINECRAFT, new MinecraftProvider());
DataProviders.Add((int)DataProvider.BATTLEMETRICS, new BattleMetricsProvider());
}

public async Task StartAsync()
{
if (Information.Address.Contains("hostname") || Information.Address.Contains("localhost"))
{
string[] splitAddr = Information.Address.Split(":");
string address = await GetHostAddress();
string port = splitAddr[1].ToLower();
Information.Address = address + ":" + port;
Information.Address = await AddressHelper.ResolveAddress(Information.Address);
}

Logger.Info($"[Bot] - Loaded {Information.Name} at address and port: {Information.Address}, {Information.ProviderType}");

await DiscordClient.LoginAsync(TokenType.Bot, Information.Token);
await DiscordClient.SetGameAsync($"Starting: {Information.Address}");
await DiscordClient.StartAsync();
await DiscordClient.LoginAndStartAsync(Information.Token, Information.Address);
}

public async Task StopAsync()
Expand All @@ -78,7 +73,7 @@ public async Task UpdateAsync()
}

var dataProvider = DataProviders[dataProviderType];
var serverInformation = await dataProvider.GetServerInformation(Information);
var serverInformation = await dataProvider.GetServerInformation(Information, ApplicationTokens);

if (serverInformation == null)
{
Expand Down Expand Up @@ -123,27 +118,5 @@ public async Task UpdateAsync()
}
}
}

public async Task<string> GetHostAddress()
{
string publicIPAddress = string.Empty;
var httpClient = new HttpExecuter(new HttpClient());


try
{
var ipAddress = await httpClient.GET<object, string>("http://ifconfig.me");

if (string.IsNullOrEmpty(ipAddress))
throw new ApplicationException("IP Address cannot be null. Host failed to resolve address.");

return ipAddress;
}
catch (WebException ex)
{
Logger.Error($"[Bot] - Error Reaching ifconfig.me: {ex.Status}", ex);
throw ex;
}
}
}
}
8 changes: 5 additions & 3 deletions DiscordPlayerCountBot/Bot/BotConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ public class BotConfig
public int UpdateTime { get; set; }

[JsonProperty]
public string SteamAPIKey { get; set; }
public List<BotInformation> ServerInformation { get; set; } = new();

[JsonProperty]
public List<BotInformation> ServerInformation { get; set; } = new();
public Dictionary<string, string> ApplicationTokens { get; set; } = new();

public void CreateDefaults()
{
Expand All @@ -26,7 +26,9 @@ public void CreateDefaults()
UseNameAsLabel = false
});
UpdateTime = 30;
SteamAPIKey = "SteamAPIKeyHere";

ApplicationTokens.Add("SteamAPIKey", "Here");
ApplicationTokens.Add("BattleMetricsKey", "Here");
}
}
}
8 changes: 4 additions & 4 deletions DiscordPlayerCountBot/Bot/BotInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class BotInformation
public string Address { get; set; }

[JsonProperty]
public string? Token { get; set; }
public string Token { get; set; }

[JsonProperty]
public int Status { get; set; }
Expand All @@ -28,14 +28,14 @@ public class BotInformation
[JsonProperty]
public ulong? ChannelID { get; set; }

[JsonIgnore]
public string SteamAPIToken { get; set; }

public Tuple<string, ushort> GetAddressAndPort()
{
string[] splitData = Address.Split(":");
try
{
if (splitData.Length == 1)
return new Tuple<string, ushort>(splitData[0], 0);

ushort port = ushort.Parse(splitData[1]);
return new Tuple<string, ushort>(splitData[0], port);
}
Expand Down
22 changes: 17 additions & 5 deletions DiscordPlayerCountBot/Configuration/DockerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,19 @@ public async Task<Tuple<Dictionary<string, Bot>, int>> Configure()
var botTokens = Environment.GetEnvironmentVariable("BOT_DISCORD_TOKENS")?.Split(";");
var botStatuses = Environment.GetEnvironmentVariable("BOT_STATUSES")?.Split(";");
var botTags = Environment.GetEnvironmentVariable("BOT_USENAMETAGS")?.Split(";");
var providerTypes = Environment.GetEnvironmentVariable("BOT_PROVIDERTYPES")?.Split(";");
var providerTypes = Environment.GetEnvironmentVariable("BOT_PROVIDERTYPES")!.Split(";");

var applicationTokensPairs = Environment.GetEnvironmentVariable("BOT_APPLICATION_VARIABLES")!.Split(";").ToList();
var applicationTokens = new Dictionary<string, string>();

foreach (var token in applicationTokensPairs)
{
var keyValueSplit = token.Split(',');
var key = keyValueSplit[0];
var value = keyValueSplit[1];

applicationTokens.Add(key, value);
}

var channelIDs = new List<ulong?>();

Expand Down Expand Up @@ -76,18 +88,18 @@ public async Task<Tuple<Dictionary<string, Bot>, int>> Configure()
{
Name = botNames[i],
Address = botAddresses?[i] + ":" + botPorts?[i],
Token = botTokens?[i],
Token = botTokens?[i] ?? throw new ApplicationException("Missing bot token."),
Status = activity,
UseNameAsLabel = useNameAsLabel,
ChannelID = channelID ?? null,
ProviderType = (int)EnumHelper.GetDataProvider(int.Parse(providerTypes?[i] ?? "0")),
SteamAPIToken = Environment.GetEnvironmentVariable("STEAM_API_KEY") ?? "",
ProviderType = EnumHelper.GetDataProvider(int.Parse(providerTypes[i]))
};

var bot = new Bot(info);
var bot = new Bot(info, applicationTokens);
await bot.StartAsync();
bots.Add(bot.Information.Address, bot);
}

return new Tuple<Dictionary<string, Bot>, int>(bots, int.Parse(Environment.GetEnvironmentVariable("BOT_UPDATE_TIME") ?? "30"));
}
}
Expand Down
3 changes: 1 addition & 2 deletions DiscordPlayerCountBot/Configuration/StandardConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public async Task<Tuple<Dictionary<string, Bot>, int>> Configure()

foreach (var info in config.ServerInformation)
{
info.SteamAPIToken = config.SteamAPIKey;
var bot = new Bot(info);
var bot = new Bot(info, config.ApplicationTokens);
await bot.StartAsync();
bots.Add(bot.Information.Address, bot);
}
Expand Down
77 changes: 77 additions & 0 deletions DiscordPlayerCountBot/Data/BattleMetrics/ServerListResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;

namespace DiscordPlayerCountBot.Data
{
#nullable enable
public class BattleMetricsServerDetails
{
public List<string> modIds { get; set; } = new List<string>();
public List<string> modHashes { get; set; } = new List<string>();
public string? map { get; set; }
public string? time { get; set; }
public string? time_i { get; set; }
public bool? official { get; set; }
public string? gamemode { get; set; }
public List<string>? modNames { get; set; }
public bool? pve { get; set; }
public bool? modded { get; set; }
public bool? crossplay { get; set; }
public string? session_flags { get; set; }
public string? serverSteamId { get; set; }
}

public class BattleMetricsServerAttributes
{
public string? id { get; set; }
public string? name { get; set; }
public string? address { get; set; }
public string? ip { get; set; }
public int? port { get; set; }
public int? players { get; set; }
public int? maxPlayers { get; set; }
public int? rank { get; set; }
public List<double> location { get; set; } = new List<double>();
public string? status { get; set; }
public BattleMetricsServerDetails? details { get; set; }
public bool? @private { get; set; }
public DateTime? createdAt { get; set; }
public DateTime? updatedAt { get; set; }
public int? portQuery { get; set; }
public string? country { get; set; }
public string? queryStatus { get; set; }
}

public class BattleMetricsServerData
{
public string? type { get; set; }
public string? id { get; set; }
public BattleMetricsServerAttributes? attributes { get; set; }
public BattleMetricsServerRelationships? relationships { get; set; }
}

public class BattleMetricsServerGame
{
public BattleMetricsServerData? data { get; set; }
}

public class BattleMetricsServerRelationships
{
public BattleMetricsServerGame? game { get; set; }
}

public class Links
{
public string? prev { get; set; }
public string? next { get; set; }
}

public class BattleMetricsServerRoot
{
public List<BattleMetricsServerData>? data { get; set; }
public Links? links { get; set; }
public List<object>? included { get; set; }
}

#nullable disable
}
2 changes: 1 addition & 1 deletion DiscordPlayerCountBot/Data/Minecraft/MinecraftServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class MinecraftServer
public MinecraftMotd Motd { get; set; }

[JsonProperty("players")]
public MinecraftPlayerInfo Players { get; set; }
public MinecraftPlayerInfo? Players { get; set; }

[JsonProperty("version")]
public string? Version { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public SteamServerListResponse()
response = new SteamServerListSubClass();
}

public SteamApiResponseData? GetServerDataByPort(string port)
public SteamApiResponseData? GetServerDataByPort(int port)
{
return response.GetAddressDataByPort(port);
}
Expand Down
4 changes: 2 additions & 2 deletions DiscordPlayerCountBot/Data/Steam/SteamServerListSubClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ public SteamServerListSubClass()
servers = new List<SteamApiResponseData>();
}

public SteamApiResponseData? GetAddressDataByPort(string port)
public SteamApiResponseData? GetAddressDataByPort(int port)
{
foreach (SteamApiResponseData data in servers)
{
if (data.addr.Split(":")[1] == port)
if (int.Parse(data.addr.Split(":")[1]) == port)
{
return data;
}
Expand Down
16 changes: 16 additions & 0 deletions DiscordPlayerCountBot/DiscordClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Discord;
using Discord.WebSocket;
using System.Threading.Tasks;

namespace DiscordPlayerCountBot
{
public static class DiscordClient
{
public static async Task LoginAndStartAsync(this DiscordSocketClient client, string token, string address)
{
await client.LoginAsync(TokenType.Bot, token);
await client.SetGameAsync($"Starting: {address}");
await client.StartAsync();
}
}
}
3 changes: 2 additions & 1 deletion DiscordPlayerCountBot/Enum/DataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum DataProvider
STEAM,
CFX,
SCUM,
MINECRAFT
MINECRAFT,
BATTLEMETRICS
}
}
Loading

0 comments on commit 4811d6b

Please sign in to comment.