- Credentials are now loading from creds.yml

- Removed/commented out obsolete credentials code
- Added missing properties to creds.yml
- Updated README.md with some tasks and progress
This commit is contained in:
Kwoth
2021-06-23 18:11:52 +02:00
parent 78d077ce71
commit 16dd398aa0
12 changed files with 254 additions and 290 deletions

View File

@@ -2,6 +2,10 @@
Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
## [3.0.0] - 01.07.2021
WIP
## [2.46.0] - 17.06.2021 ## [2.46.0] - 17.06.2021
### Added ### Added

View File

@@ -1,4 +1,4 @@
# Experimental Branch. Things will break. # :warning: Experimental Branch. Things will break. :warning:
## Migration from 2.x ## Migration from 2.x
@@ -6,6 +6,16 @@
## Changes ## Changes
- Command attributes cleaned up - explain properly: Command attributes cleaned up
- Database migrations cleaned up/squashed - explain properly: Database migrations cleaned up/squashed
- explain properly: coord and coord.yml
- wip: credentials.json moved to `creds.yml`, example is in `creds_example.json`
- todo: from source run location is nadekobot/output
- todo: votes functionality changed
- todo: code cleanup tasks
- todo: remove colors from bot.cs
- todo: creds
- todo:
- todo?: maybe use https://github.com/Humanizr/Humanizer for trimto, time printing, date printing, etc
- todo?: use guild locale more in the code (from guild settings) (for dates, currency, etc?)
- todo?: Write a sourcegen for response strings and use const/static fields (maybe even typed to enforce correct number of arguments)

View File

@@ -18,7 +18,6 @@ using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Net; using Discord.Net;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Common.Configs; using NadekoBot.Common.Configs;
using NadekoBot.Db; using NadekoBot.Db;
@@ -32,14 +31,14 @@ namespace NadekoBot
{ {
public class Bot public class Bot
{ {
public BotCredentials Credentials { get; } private readonly IBotCredentials _creds;
public DiscordSocketClient Client { get; } public DiscordSocketClient Client { get; }
public CommandService CommandService { get; } public CommandService CommandService { get; }
private readonly DbService _db; private readonly DbService _db;
public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; } public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; }
/* Will have to be removed soon, it's been way too long */ // todo remove colors from here
public static Color OkColor { get; set; } public static Color OkColor { get; set; }
public static Color ErrorColor { get; set; } public static Color ErrorColor { get; set; }
public static Color PendingColor { get; set; } public static Color PendingColor { get; set; }
@@ -60,10 +59,12 @@ namespace NadekoBot
TerribleElevatedPermissionCheck(); TerribleElevatedPermissionCheck();
Credentials = new BotCredentials(); _creds = BotCredentialsProvider.CreateBotCredentials();
Cache = new RedisCache(Credentials, shardId);
LinqToDBForEFTools.Initialize(); // todo no need for cache prop
_db = new DbService(Credentials); Cache = new RedisCache(_creds, shardId);
_db = new DbService(_creds);
if (shardId == 0) if (shardId == 0)
{ {
@@ -75,7 +76,7 @@ namespace NadekoBot
MessageCacheSize = 50, MessageCacheSize = 50,
LogLevel = LogSeverity.Warning, LogLevel = LogSeverity.Warning,
ConnectionTimeout = int.MaxValue, ConnectionTimeout = int.MaxValue,
TotalShards = Credentials.TotalShards, TotalShards = _creds.TotalShards,
ShardId = shardId, ShardId = shardId,
AlwaysDownloadUsers = false, AlwaysDownloadUsers = false,
ExclusiveBulkDelete = true, ExclusiveBulkDelete = true,
@@ -116,7 +117,7 @@ namespace NadekoBot
} }
var svcs = new ServiceCollection() var svcs = new ServiceCollection()
.AddSingleton<IBotCredentials>(Credentials) .AddSingleton<IBotCredentials>(_creds)
.AddSingleton(_db) .AddSingleton(_db)
.AddSingleton(Client) .AddSingleton(Client)
.AddSingleton(CommandService) .AddSingleton(CommandService)
@@ -300,7 +301,7 @@ namespace NadekoBot
{ {
var sw = Stopwatch.StartNew(); var sw = Stopwatch.StartNew();
await LoginAsync(Credentials.Token).ConfigureAwait(false); await LoginAsync(_creds.Token).ConfigureAwait(false);
Mention = Client.CurrentUser.Mention; Mention = Client.CurrentUser.Mention;
Log.Information("Shard {ShardId} loading services...", Client.ShardId); Log.Information("Shard {ShardId} loading services...", Client.ShardId);

View File

@@ -1,86 +1,120 @@
using System.Collections.Generic; using System.Collections.Generic;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
using NadekoBot.Services;
using YamlDotNet.Serialization;
namespace Nadeko.Common namespace Nadeko.Common
{ {
public sealed record Creds public sealed class Creds : IBotCredentials
{ {
public Creds() public Creds()
{ {
Token = string.Empty; Token = string.Empty;
OwnerIds = new() OwnerIds = new();
{
105635576866156544
};
TotalShards = 1; TotalShards = 1;
GoogleApiKey = string.Empty; GoogleApiKey = string.Empty;
Votes = new(string.Empty, string.Empty); Votes = new(string.Empty, string.Empty);
Patreon = new(string.Empty, string.Empty, string.Empty, string.Empty); Patreon = new(string.Empty, string.Empty, string.Empty, string.Empty);
BotListToken = string.Empty; BotListToken = string.Empty;
CleverbotApiKey = string.Empty; CleverbotApiKey = string.Empty;
RedisOptions = "redis:6379,syncTimeout=30000,responseTimeout=30000,allowAdmin=true,password="; RedisOptions = "localhost:6379,syncTimeout=30000,responseTimeout=30000,allowAdmin=true,password=";
Db = new DbOptions(); Db = new()
{
Type = "sqlite",
ConnectionString = "Data Source=data/NadekoBot.db"
};
Version = 1; Version = 1;
} }
[Comment(@"Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/")] [Comment(@"Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/")]
public string Token { get; } public string Token { get; set; }
[Comment(@"List of Ids of the users who have bot owner permissions [Comment(@"List of Ids of the users who have bot owner permissions
**DO NOT ADD PEOPLE YOU DON'T TRUST**")] **DO NOT ADD PEOPLE YOU DON'T TRUST**")]
public HashSet<ulong> OwnerIds { get; } public List<ulong> OwnerIds { get; set; }
// todo update total shards on startup
[Comment(@"The number of shards that the bot will running on. [Comment(@"The number of shards that the bot will running on.
Leave at 1 if you don't know what you're doing.")] Leave at 1 if you don't know what you're doing.")]
public int TotalShards { get; } public int TotalShards { get; set; }
[Comment(@"Login to https://console.cloud.google.com, create a new project, go to APIs & Services -> Library -> YouTube Data API and enable it. [Comment(@"Login to https://console.cloud.google.com, create a new project, go to APIs & Services -> Library -> YouTube Data API and enable it.
Then, go to APIs and Services -> Credentials and click Create credentials -> API key. Then, go to APIs and Services -> Credentials and click Create credentials -> API key.
Used only for Youtube Data Api (at the moment).")] Used only for Youtube Data Api (at the moment).")]
public string GoogleApiKey { get; } public string GoogleApiKey { get; set; }
[Comment(@"Settings for voting system for discordbots. Meant for use on global Nadeko.")] [Comment(@"Settings for voting system for discordbots. Meant for use on global Nadeko.")]
public VotesSettings Votes { get; } public VotesSettings Votes { get; set; }
[Comment(@"Patreon auto reward system settings. [Comment(@"Patreon auto reward system settings.
go to https://www.patreon.com/portal -> my clients -> create client")] go to https://www.patreon.com/portal -> my clients -> create client")]
public PatreonSettings Patreon { get; } public PatreonSettings Patreon { get; set; }
[Comment(@"Api key for sending stats to DiscordBotList.")] [Comment(@"Api key for sending stats to DiscordBotList.")]
public string BotListToken { get; } public string BotListToken { get; set; }
[Comment(@"Official cleverbot api key.")] [Comment(@"Official cleverbot api key.")]
public string CleverbotApiKey { get; } public string CleverbotApiKey { get; set; }
[Comment(@"Redis connection string. Don't change if you don't know what you're doing.")] [Comment(@"Redis connection string. Don't change if you don't know what you're doing.")]
public string RedisOptions { get; } public string RedisOptions { get; set; }
[Comment(@"Database options. Don't change if you don't know what you're doing. Leave null for default values")] [Comment(@"Database options. Don't change if you don't know what you're doing. Leave null for default values")]
public DbOptions Db { get; } public DbOptions Db { get; set; }
[Comment(@"DO NOT CHANGE")] [Comment(@"DO NOT CHANGE")]
public int Version { get; } public int Version { get; set; }
public RestartConfig RestartCommand { get; set; }
[YamlIgnore]
public string PatreonCampaignId => Patreon?.CampaignId;
[YamlIgnore]
public string PatreonAccessToken => Patreon?.AccessToken;
public string VotesUrl { get; set; }
public string VotesToken { get; set; }
[Comment(@"Api key obtained on https://rapidapi.com (go to MyApps -> Add New App -> Enter Name -> Application key)")]
public string RapidApiKey { get; set; }
[Comment(@"https://locationiq.com api key (register and you will receive the token in the email).
Used only for .time command.")]
public string LocationIqApiKey { get; set; }
[Comment(@"https://timezonedb.com api key (register and you will receive the token in the email).
Used only for .time command")]
public string TimezoneDbApiKey { get; set; }
[Comment(@"https://pro.coinmarketcap.com/account/ api key. There is a free plan for personal use.
Used for cryptocurrency related commands.")]
public string CoinmarketcapApiKey { get; set; }
[Comment(@"Api key used for Osu related commands. Obtain this key at https://osu.ppy.sh/p/api")]
public string OsuApiKey { get; set; }
public class DbOptions public class DbOptions
{ {
[Comment(@"Database type. Only sqlite supported atm")] [Comment(@"Database type. Only sqlite supported atm")]
public string Type { get; } = ""; public string Type { get; set; }
[Comment(@"Connection string. Will default to ""Data Source=data/NadekoBot.db""")] [Comment(@"Connection string. Will default to ""Data Source=data/NadekoBot.db""")]
public string ConnectionString { get; } = string.Empty; public string ConnectionString { get; set; }
} }
// todo fixup patreon
public sealed record PatreonSettings public sealed record PatreonSettings
{ {
[Comment(@"")] [Comment(@"Access token. You have to manually update this 1st of each month by refreshing the token on https://patreon.com/portal")]
public string AccessToken { get; } public string AccessToken { get; set; }
[Comment(@"")] [Comment(@"Unused atm")]
public string RefreshToken { get; } public string RefreshToken { get; set; }
[Comment(@"")] [Comment(@"Unused atm")]
public string ClientSecret { get; } public string ClientSecret { get; set; }
[Comment(@"Campaign ID of your patreon page. Go to your patreon page (make sure you're logged in) and type ""prompt('Campaign ID', window.patreon.bootstrap.creator.data.id);"" in the console. (ctrl + shift + i)")] [Comment(@"Campaign ID of your patreon page. Go to your patreon page (make sure you're logged in) and type ""prompt('Campaign ID', window.patreon.bootstrap.creator.data.id);"" in the console. (ctrl + shift + i)")]
public string CampaignId { get; } public string CampaignId { get; set; }
public PatreonSettings(string accessToken, string refreshToken, string clientSecret, string campaignId) public PatreonSettings(string accessToken, string refreshToken, string clientSecret, string campaignId)
{ {
@@ -94,9 +128,9 @@ go to https://www.patreon.com/portal -> my clients -> create client")]
public sealed record VotesSettings public sealed record VotesSettings
{ {
[Comment(@"")] [Comment(@"")]
public string Url { get; } public string Url { get; set; }
[Comment(@"")] [Comment(@"")]
public string Key { get; } public string Key { get; set; }
public VotesSettings(string url, string key) public VotesSettings(string url, string key)
{ {
@@ -107,31 +141,31 @@ go to https://www.patreon.com/portal -> my clients -> create client")]
public class Old public class Old
{ {
public string Token { get; } = string.Empty; public string Token { get; set; } = string.Empty;
public ulong[] OwnerIds { get; } = new ulong[1]; public ulong[] OwnerIds { get; set; } = new ulong[1];
public string LoLApiKey { get; } = string.Empty; public string LoLApiKey { get; set; } = string.Empty;
public string GoogleApiKey { get; } = string.Empty; public string GoogleApiKey { get; set; } = string.Empty;
public string MashapeKey { get; } = string.Empty; public string MashapeKey { get; set; } = string.Empty;
public string OsuApiKey { get; } = string.Empty; public string OsuApiKey { get; set; } = string.Empty;
public string SoundCloudClientId { get; } = string.Empty; public string SoundCloudClientId { get; set; } = string.Empty;
public string CleverbotApiKey { get; } = string.Empty; public string CleverbotApiKey { get; set; } = string.Empty;
public string CarbonKey { get; } = string.Empty; public string CarbonKey { get; set; } = string.Empty;
public int TotalShards { get; } = 1; public int TotalShards { get; set; } = 1;
public string PatreonAccessToken { get; } = string.Empty; public string PatreonAccessToken { get; set; } = string.Empty;
public string PatreonCampaignId { get; } = "334038"; public string PatreonCampaignId { get; set; } = "334038";
public RestartConfig? RestartCommand { get; } = null; public RestartConfig? RestartCommand { get; set; } = null;
public string ShardRunCommand { get; } = string.Empty; public string ShardRunCommand { get; set; } = string.Empty;
public string ShardRunArguments { get; } = string.Empty; public string ShardRunArguments { get; set; } = string.Empty;
public int? ShardRunPort { get; } = null; public int? ShardRunPort { get; set; } = null;
public string MiningProxyUrl { get; } = string.Empty; public string MiningProxyUrl { get; set; } = string.Empty;
public string MiningProxyCreds { get; } = string.Empty; public string MiningProxyCreds { get; set; } = string.Empty;
public string BotListToken { get; } = string.Empty; public string BotListToken { get; set; } = string.Empty;
public string TwitchClientId { get; } = string.Empty; public string TwitchClientId { get; set; } = string.Empty;
public string VotesToken { get; } = string.Empty; public string VotesToken { get; set; } = string.Empty;
public string VotesUrl { get; } = string.Empty; public string VotesUrl { get; set; } = string.Empty;
public string RedisOptions { get; } = string.Empty; public string RedisOptions { get; set; } = string.Empty;
public class RestartConfig public class RestartConfig
{ {
@@ -141,8 +175,8 @@ go to https://www.patreon.com/portal -> my clients -> create client")]
this.Args = args; this.Args = args;
} }
public string Cmd { get; } public string Cmd { get; set; }
public string Args { get; } public string Args { get; set; }
} }
} }
} }

View File

@@ -6,6 +6,7 @@ using NadekoBot.Services;
using System; using System;
using System.IO; using System.IO;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Nadeko.Common;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
namespace NadekoBot.Services.Database namespace NadekoBot.Services.Database
@@ -16,7 +17,7 @@ namespace NadekoBot.Services.Database
{ {
LogSetup.SetupLogger(-2); LogSetup.SetupLogger(-2);
var optionsBuilder = new DbContextOptionsBuilder<NadekoContext>(); var optionsBuilder = new DbContextOptionsBuilder<NadekoContext>();
IBotCredentials creds = new BotCredentials(); IBotCredentials creds = BotCredentialsProvider.CreateBotCredentials();
var builder = new SqliteConnectionStringBuilder(creds.Db.ConnectionString); var builder = new SqliteConnectionStringBuilder(creds.Db.ConnectionString);
builder.DataSource = Path.Combine(AppContext.BaseDirectory, builder.DataSource); builder.DataSource = Path.Combine(AppContext.BaseDirectory, builder.DataSource);
optionsBuilder.UseSqlite(builder.ToString()); optionsBuilder.UseSqlite(builder.ToString());

View File

@@ -218,7 +218,7 @@ namespace NadekoBot.Modules.Administration.Services
Log.Warning( Log.Warning(
"No owner channels created! Make sure you've specified the correct OwnerId in the credentials.json file and invited the bot to a Discord server."); "No owner channels created! Make sure you've specified the correct OwnerId in the credentials.json file and invited the bot to a Discord server.");
else else
Log.Information($"Created {ownerChannels.Count} out of {_creds.OwnerIds.Length} owner message channels."); Log.Information($"Created {ownerChannels.Count} out of {_creds.OwnerIds.Count} owner message channels.");
} }
public Task LeaveGuild(string guildStr) public Task LeaveGuild(string guildStr)

View File

@@ -430,7 +430,7 @@ namespace NadekoBot.Modules.Searches
if (!await ValidateQuery(ctx.Channel, name).ConfigureAwait(false)) if (!await ValidateQuery(ctx.Channel, name).ConfigureAwait(false))
return; return;
if (string.IsNullOrWhiteSpace(_creds.MashapeKey)) if (string.IsNullOrWhiteSpace(_creds.RapidApiKey))
{ {
await ReplyErrorLocalizedAsync("mashape_api_missing").ConfigureAwait(false); await ReplyErrorLocalizedAsync("mashape_api_missing").ConfigureAwait(false);
return; return;

View File

@@ -575,7 +575,7 @@ namespace NadekoBot.Modules.Searches.Services
using (var http = _httpFactory.CreateClient()) using (var http = _httpFactory.CreateClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.MashapeKey); http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.RapidApiKey);
try try
{ {
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" + var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" +

View File

@@ -34,6 +34,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
@@ -56,8 +57,13 @@
<ProjectReference Include="..\ayu\Ayu.Discord.Voice\Ayu.Discord.Voice.csproj" /> <ProjectReference Include="..\ayu\Ayu.Discord.Voice\Ayu.Discord.Voice.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<None Update="creds.yml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="credentials.json" />
<Protobuf Include="..\NadekoBot.Coordinator\Protos\coordinator.proto" GrpcServices="Client"> <Protobuf Include="..\NadekoBot.Coordinator\Protos\coordinator.proto" GrpcServices="Client">
<Link>Protos\coordinator.proto</Link> <Link>Protos\coordinator.proto</Link>
</Protobuf> </Protobuf>
@@ -73,7 +79,7 @@
<None Update="data\xp_template_backup.json"> <None Update="data\xp_template_backup.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="credentials_example.json"> <None Update="creds_example.yml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>

View File

@@ -4,7 +4,7 @@ using NadekoBot.Services.Database;
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using NadekoBot.Db; using LinqToDB.EntityFrameworkCore;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
@@ -15,6 +15,8 @@ namespace NadekoBot.Services
public DbService(IBotCredentials creds) public DbService(IBotCredentials creds)
{ {
LinqToDBForEFTools.Initialize();
var builder = new SqliteConnectionStringBuilder(creds.Db.ConnectionString); var builder = new SqliteConnectionStringBuilder(creds.Db.ConnectionString);
builder.DataSource = Path.Combine(AppContext.BaseDirectory, builder.DataSource); builder.DataSource = Path.Combine(AppContext.BaseDirectory, builder.DataSource);

View File

@@ -1,5 +1,8 @@
using Discord; using System.Collections.Generic;
using Discord;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using Nadeko.Common;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
@@ -7,31 +10,32 @@ namespace NadekoBot.Services
{ {
string Token { get; } string Token { get; }
string GoogleApiKey { get; } string GoogleApiKey { get; }
ImmutableArray<ulong> OwnerIds { get; } List<ulong> OwnerIds { get; }
string MashapeKey { get; } string RapidApiKey { get; }
string PatreonAccessToken { get; } string PatreonAccessToken { get; }
string CarbonKey { get; }
DBConfig Db { get; } Creds.DbOptions Db { get; }
string OsuApiKey { get; } string OsuApiKey { get; }
bool IsOwner(IUser u);
int TotalShards { get; } int TotalShards { get; }
string ShardRunCommand { get; }
string ShardRunArguments { get; }
string PatreonCampaignId { get; } string PatreonCampaignId { get; }
string CleverbotApiKey { get; } string CleverbotApiKey { get; }
RestartConfig RestartCommand { get; } RestartConfig RestartCommand { get; }
string VotesUrl { get; } string VotesUrl { get; }
string VotesToken { get; } string VotesToken { get; }
string BotListToken { get; } string BotListToken { get; }
string TwitchClientId { get; }
string RedisOptions { get; } string RedisOptions { get; }
string LocationIqApiKey { get; } string LocationIqApiKey { get; }
string TimezoneDbApiKey { get; } string TimezoneDbApiKey { get; }
string CoinmarketcapApiKey { get; } string CoinmarketcapApiKey { get; }
} }
// todo move somewhere else
public static class IBotCredentialsExtensions
{
public static bool IsOwner(this IBotCredentials creds, IUser user)
=> creds.OwnerIds.Contains(user.Id);
}
public class RestartConfig public class RestartConfig
{ {
public RestartConfig(string cmd, string args) public RestartConfig(string cmd, string args)
@@ -43,15 +47,4 @@ namespace NadekoBot.Services
public string Cmd { get; } public string Cmd { get; }
public string Args { get; } public string Args { get; }
} }
public class DBConfig
{
public DBConfig(string type, string connectionString)
{
this.Type = type;
this.ConnectionString = connectionString;
}
public string Type { get; }
public string ConnectionString { get; }
}
} }

View File

@@ -1,206 +1,119 @@
using Discord; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration;
using NadekoBot.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using Nadeko.Common;
using Serilog; using Serilog;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
public class BotCredentials : IBotCredentials public static class BotCredentialsProvider
{ {
public string GoogleApiKey { get; } private const string _credsFileName = "creds.yml";
public string MashapeKey { get; } private static string _oldCredsJsonFilename = Path.Combine(Directory.GetCurrentDirectory(), "credentials.json");
public string Token { get; }
public ImmutableArray<ulong> OwnerIds { get; } public static Creds CreateBotCredentials()
public string OsuApiKey { get; }
public string CleverbotApiKey { get; }
public RestartConfig RestartCommand { get; }
public DBConfig Db { get; }
public int TotalShards { get; }
public string CarbonKey { get; }
private readonly string _credsFileName = Path.Combine(Directory.GetCurrentDirectory(), "credentials.json");
public string PatreonAccessToken { get; }
public string ShardRunCommand { get; }
public string ShardRunArguments { get; }
public int ShardRunPort { get; }
public string PatreonCampaignId { get; }
public string TwitchClientId { get; }
public string VotesUrl { get; }
public string VotesToken { get; }
public string BotListToken { get; }
public string RedisOptions { get; }
public string LocationIqApiKey { get; }
public string TimezoneDbApiKey { get; }
public string CoinmarketcapApiKey { get; }
public BotCredentials()
{ {
try
{
File.WriteAllText("./credentials_example.json",
JsonConvert.SerializeObject(new CredentialsModel(), Formatting.Indented));
}
catch
{
}
if (!File.Exists(_credsFileName)) if (!File.Exists(_credsFileName))
Log.Warning( Log.Warning($"{_credsFileName} is missing. " +
$"credentials.json is missing. Attempting to load creds from environment variables prefixed with 'NadekoBot_'. Example is in {Path.GetFullPath("./credentials_example.json")}"); $"Attempting to load creds from environment variables prefixed with 'NadekoBot_'. " +
try $"Example is in {Path.GetFullPath("./creds-example.yml")}");
{
var configBuilder = new ConfigurationBuilder();
configBuilder.AddJsonFile(_credsFileName, true)
.AddEnvironmentVariables("NadekoBot_");
var data = configBuilder.Build();
Token = data[nameof(Token)]; IConfigurationBuilder configBuilder = new ConfigurationBuilder();
if (string.IsNullOrWhiteSpace(Token)) var creds = configBuilder
{ .AddYamlFile(_credsFileName, false, true)
Log.Error( .AddEnvironmentVariables("NadekoBot_")
"Token is missing from credentials.json or Environment variables. Add it and restart the program."); .Build()
Helpers.ReadErrorAndExit(5); .Get<Creds>();
}
OwnerIds = data.GetSection("OwnerIds").GetChildren().Select(c => ulong.Parse(c.Value)) // if(string.IsNullOrWhiteSpace(creds.RedisOptions))
.ToImmutableArray(); // creds.RedisOptions = ""
GoogleApiKey = data[nameof(GoogleApiKey)];
MashapeKey = data[nameof(MashapeKey)];
OsuApiKey = data[nameof(OsuApiKey)];
PatreonAccessToken = data[nameof(PatreonAccessToken)];
PatreonCampaignId = data[nameof(PatreonCampaignId)] ?? "334038";
ShardRunCommand = data[nameof(ShardRunCommand)];
ShardRunArguments = data[nameof(ShardRunArguments)];
CleverbotApiKey = data[nameof(CleverbotApiKey)];
LocationIqApiKey = data[nameof(LocationIqApiKey)];
TimezoneDbApiKey = data[nameof(TimezoneDbApiKey)];
CoinmarketcapApiKey = data[nameof(CoinmarketcapApiKey)];
if (string.IsNullOrWhiteSpace(CoinmarketcapApiKey))
{
CoinmarketcapApiKey = "e79ec505-0913-439d-ae07-069e296a6079";
}
if (!string.IsNullOrWhiteSpace(data[nameof(RedisOptions)])) return creds;
RedisOptions = data[nameof(RedisOptions)];
else
RedisOptions = "127.0.0.1,syncTimeout=3000";
VotesToken = data[nameof(VotesToken)]; // try
VotesUrl = data[nameof(VotesUrl)]; // {
BotListToken = data[nameof(BotListToken)]; //
//
var restartSection = data.GetSection(nameof(RestartCommand)); // var data = configBuilder.Build();
var cmd = restartSection["cmd"]; //
var args = restartSection["args"]; // Token = data[nameof(Token)];
if (!string.IsNullOrWhiteSpace(cmd)) // if (string.IsNullOrWhiteSpace(Token))
RestartCommand = new RestartConfig(cmd, args); // {
// Log.Error("Token is missing from credentials.json or Environment variables. Add it and restart the program.");
if (Environment.OSVersion.Platform == PlatformID.Unix) // Helpers.ReadErrorAndExit(5);
{ // }
if (string.IsNullOrWhiteSpace(ShardRunCommand)) //
ShardRunCommand = "dotnet"; // OwnerIds = data.GetSection("OwnerIds").GetChildren().Select(c => ulong.Parse(c.Value))
if (string.IsNullOrWhiteSpace(ShardRunArguments)) // .ToImmutableArray();
ShardRunArguments = "run -c Release --no-build -- {0} {1}"; // GoogleApiKey = data[nameof(GoogleApiKey)];
} // MashapeKey = data[nameof(MashapeKey)];
else //windows // OsuApiKey = data[nameof(OsuApiKey)];
{ // PatreonAccessToken = data[nameof(PatreonAccessToken)];
if (string.IsNullOrWhiteSpace(ShardRunCommand)) // PatreonCampaignId = data[nameof(PatreonCampaignId)] ?? "334038";
ShardRunCommand = "NadekoBot.exe"; // ShardRunCommand = data[nameof(ShardRunCommand)];
if (string.IsNullOrWhiteSpace(ShardRunArguments)) // ShardRunArguments = data[nameof(ShardRunArguments)];
ShardRunArguments = "{0} {1}"; // CleverbotApiKey = data[nameof(CleverbotApiKey)];
} // LocationIqApiKey = data[nameof(LocationIqApiKey)];
// TimezoneDbApiKey = data[nameof(TimezoneDbApiKey)];
var portStr = data[nameof(ShardRunPort)]; // CoinmarketcapApiKey = data[nameof(CoinmarketcapApiKey)];
if (string.IsNullOrWhiteSpace(portStr)) // if (string.IsNullOrWhiteSpace(CoinmarketcapApiKey))
ShardRunPort = new NadekoRandom().Next(5000, 6000); // {
else // CoinmarketcapApiKey = "e79ec505-0913-439d-ae07-069e296a6079";
ShardRunPort = int.Parse(portStr); // }
//
if (!int.TryParse(data[nameof(TotalShards)], out var ts)) // if (!string.IsNullOrWhiteSpace(data[nameof(RedisOptions)]))
ts = 0; // RedisOptions = data[nameof(RedisOptions)];
TotalShards = ts < 1 ? 1 : ts; // else
// RedisOptions = "127.0.0.1,syncTimeout=3000";
CarbonKey = data[nameof(CarbonKey)]; //
var dbSection = data.GetSection("db"); // VotesToken = data[nameof(VotesToken)];
Db = new DBConfig(string.IsNullOrWhiteSpace(dbSection["Type"]) // VotesUrl = data[nameof(VotesUrl)];
? "sqlite" // BotListToken = data[nameof(BotListToken)];
: dbSection["Type"], //
string.IsNullOrWhiteSpace(dbSection["ConnectionString"]) // var restartSection = data.GetSection(nameof(RestartCommand));
? "Data Source=data/NadekoBot.db" // var cmd = restartSection["cmd"];
: dbSection["ConnectionString"]); // var args = restartSection["args"];
// if (!string.IsNullOrWhiteSpace(cmd))
TwitchClientId = data[nameof(TwitchClientId)]; // RestartCommand = new RestartConfig(cmd, args);
if (string.IsNullOrWhiteSpace(TwitchClientId)) //
{ // if (Environment.OSVersion.Platform == PlatformID.Unix)
TwitchClientId = "67w6z9i09xv2uoojdm9l0wsyph4hxo6"; // {
// if (string.IsNullOrWhiteSpace(ShardRunCommand))
// ShardRunCommand = "dotnet";
// if (string.IsNullOrWhiteSpace(ShardRunArguments))
// ShardRunArguments = "run -c Release --no-build -- {0} {1}";
// }
// else //windows
// {
// if (string.IsNullOrWhiteSpace(ShardRunCommand))
// ShardRunCommand = "NadekoBot.exe";
// if (string.IsNullOrWhiteSpace(ShardRunArguments))
// ShardRunArguments = "{0} {1}";
// }
//
// if (!int.TryParse(data[nameof(TotalShards)], out var ts))
// ts = 0;
// TotalShards = ts < 1 ? 1 : ts;
//
// CarbonKey = data[nameof(CarbonKey)];
// var dbSection = data.GetSection("db");
// Db = new DBConfig(@"sqlite",
// string.IsNullOrWhiteSpace(dbSection["ConnectionString"])
// ? "Data Source=data/NadekoBot.db"
// : dbSection["ConnectionString"]);
//
// TwitchClientId = data[nameof(TwitchClientId)];
// if (string.IsNullOrWhiteSpace(TwitchClientId))
// {
// TwitchClientId = "67w6z9i09xv2uoojdm9l0wsyph4hxo6";
// }
// }
// catch (Exception ex)
// {
// Log.Error("JSON serialization has failed. Fix your credentials file and restart the bot.");
// Log.Fatal(ex.ToString());
// Helpers.ReadErrorAndExit(6);
// }
} }
} }
catch (Exception ex)
{
Log.Error("JSON serialization has failed. Fix your credentials file and restart the bot.");
Log.Fatal(ex.ToString());
Helpers.ReadErrorAndExit(6);
}
}
/// <summary>
/// No idea why this thing exists
/// </summary>
private class CredentialsModel : IBotCredentials
{
public string Token { get; set; } = "";
public ulong[] OwnerIds { get; set; } = new ulong[]
{
105635576866156544
};
public string GoogleApiKey { get; set; } = "";
public string MashapeKey { get; set; } = "";
public string OsuApiKey { get; set; } = "";
public string SoundCloudClientId { get; set; } = "";
public string CleverbotApiKey { get; } = "";
public string CarbonKey { get; set; } = "";
public DBConfig Db { get; set; } = new DBConfig("sqlite", "Data Source=data/NadekoBot.db");
public int TotalShards { get; set; } = 1;
public string PatreonAccessToken { get; set; } = "";
public string PatreonCampaignId { get; set; } = "334038";
public string RestartCommand { get; set; } = null;
public string ShardRunCommand { get; set; } = "";
public string ShardRunArguments { get; set; } = "";
public int? ShardRunPort { get; set; } = null;
public string BotListToken { get; set; }
public string TwitchClientId { get; set; }
public string VotesToken { get; set; }
public string VotesUrl { get; set; }
public string RedisOptions { get; set; }
public string LocationIqApiKey { get; set; }
public string TimezoneDbApiKey { get; set; }
public string CoinmarketcapApiKey { get; set; }
[JsonIgnore] ImmutableArray<ulong> IBotCredentials.OwnerIds => throw new NotImplementedException();
[JsonIgnore] RestartConfig IBotCredentials.RestartCommand => throw new NotImplementedException();
public bool IsOwner(IUser u)
{
throw new NotImplementedException();
}
}
public bool IsOwner(IUser u) => OwnerIds.Contains(u.Id);
}
} }