Clash of clans completely localizable, fixes, improvements 🆗 💯

This commit is contained in:
Kwoth
2017-02-13 21:29:06 +01:00
parent 53b6a77fc2
commit 023df13121
9 changed files with 419 additions and 64 deletions

View File

@@ -73,7 +73,11 @@ namespace NadekoBot.Modules.ClashOfClans
try
{
SaveWar(war);
await war.Channel.SendErrorAsync($"❗🔰**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false);
await war.Channel.SendErrorAsync(GetTextStatic("claim_expired",
NadekoBot.Localization.GetCultureInfo(war.Channel.GuildId),
typeof(ClashOfClans).Name.ToLowerInvariant(),
Format.Bold(Bases[i].CallUser),
war.ShortPrint()));
}
catch { }
}
@@ -92,7 +96,7 @@ namespace NadekoBot.Modules.ClashOfClans
if (size < 10 || size > 50 || size % 5 != 0)
{
await Context.Channel.SendErrorAsync("🔰 Not a Valid war size").ConfigureAwait(false);
await ReplyErrorLocalized("invalid_size").ConfigureAwait(false);
return;
}
List<ClashWar> wars;
@@ -107,7 +111,7 @@ namespace NadekoBot.Modules.ClashOfClans
var cw = await CreateWar(enemyClan, size, Context.Guild.Id, Context.Channel.Id);
wars.Add(cw);
await Context.Channel.SendConfirmAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false);
await ReplyErrorLocalized("war_created", cw.ShortPrint()).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -120,18 +124,18 @@ namespace NadekoBot.Modules.ClashOfClans
var warsInfo = GetWarInfo(Context.Guild, num);
if (warsInfo == null)
{
await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
var war = warsInfo.Item1[warsInfo.Item2];
try
{
war.Start();
await Context.Channel.SendConfirmAsync($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false);
await ReplyConfirmLocalized("war_started", war.ShortPrint()).ConfigureAwait(false);
}
catch
{
await Context.Channel.SendErrorAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false);
await ReplyErrorLocalized("war_already_started", war.ShortPrint()).ConfigureAwait(false);
}
SaveWar(war);
}
@@ -149,22 +153,20 @@ namespace NadekoBot.Modules.ClashOfClans
ClashWars.TryGetValue(Context.Guild.Id, out wars);
if (wars == null || wars.Count == 0)
{
await Context.Channel.SendErrorAsync("🔰 **No active wars.**").ConfigureAwait(false);
await ReplyErrorLocalized("no_active_wars").ConfigureAwait(false);
return;
}
var sb = new StringBuilder();
sb.AppendLine("🔰 **LIST OF ACTIVE WARS**");
sb.AppendLine("**-------------------------**");
for (var i = 0; i < wars.Count; i++)
{
sb.AppendLine($"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**");
sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**");
sb.AppendLine($"**#{i + 1}.** `{GetText("enemy")}:` **{wars[i].EnemyClan}**");
sb.AppendLine($"\t\t`{GetText("size")}:` **{wars[i].Size} v {wars[i].Size}**");
sb.AppendLine("**-------------------------**");
}
await Context.Channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false);
await Context.Channel.SendConfirmAsync(GetText("list_active_wars"), sb.ToString()).ConfigureAwait(false);
return;
}
var num = 0;
int.TryParse(number, out num);
@@ -172,10 +174,11 @@ namespace NadekoBot.Modules.ClashOfClans
var warsInfo = GetWarInfo(Context.Guild, num);
if (warsInfo == null)
{
await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
await Context.Channel.SendConfirmAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false);
var war = warsInfo.Item1[warsInfo.Item2];
await Context.Channel.SendConfirmAsync(war.Localize("info_about_war", $"`{war.EnemyClan}` ({war.Size} v {war.Size})"), war.ToPrettyString()).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -185,7 +188,7 @@ namespace NadekoBot.Modules.ClashOfClans
var warsInfo = GetWarInfo(Context.Guild, number);
if (warsInfo == null || warsInfo.Item1.Count == 0)
{
await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
var usr =
@@ -197,11 +200,11 @@ namespace NadekoBot.Modules.ClashOfClans
var war = warsInfo.Item1[warsInfo.Item2];
war.Call(usr, baseNumber - 1);
SaveWar(war);
await Context.Channel.SendConfirmAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false);
await ConfirmLocalized("claimed_base", Format.Bold(usr.ToString()), baseNumber, war.ShortPrint()).ConfigureAwait(false);
}
catch (Exception ex)
{
await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false);
await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
}
}
@@ -233,13 +236,13 @@ namespace NadekoBot.Modules.ClashOfClans
var warsInfo = GetWarInfo(Context.Guild, number);
if (warsInfo == null)
{
await Context.Channel.SendErrorAsync("🔰 That war does not exist.").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
var war = warsInfo.Item1[warsInfo.Item2];
war.End();
SaveWar(war);
await Context.Channel.SendConfirmAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false);
await ReplyConfirmLocalized("war_ended", warsInfo.Item1[warsInfo.Item2].ShortPrint()).ConfigureAwait(false);
var size = warsInfo.Item1[warsInfo.Item2].Size;
warsInfo.Item1.RemoveAt(warsInfo.Item2);
@@ -252,7 +255,7 @@ namespace NadekoBot.Modules.ClashOfClans
var warsInfo = GetWarInfo(Context.Guild, number);
if (warsInfo == null || warsInfo.Item1.Count == 0)
{
await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
var usr =
@@ -264,11 +267,11 @@ namespace NadekoBot.Modules.ClashOfClans
var war = warsInfo.Item1[warsInfo.Item2];
var baseNumber = war.Uncall(usr);
SaveWar(war);
await Context.Channel.SendConfirmAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false);
await ReplyConfirmLocalized("base_unclaimed", usr, baseNumber + 1, war.ShortPrint()).ConfigureAwait(false);
}
catch (Exception ex)
{
await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false);
await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
}
}
@@ -277,7 +280,7 @@ namespace NadekoBot.Modules.ClashOfClans
var warInfo = GetWarInfo(Context.Guild, number);
if (warInfo == null || warInfo.Item1.Count == 0)
{
await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
return;
}
var war = warInfo.Item1[warInfo.Item2];
@@ -292,7 +295,7 @@ namespace NadekoBot.Modules.ClashOfClans
{
war.FinishClaim(baseNumber, stars);
}
await Context.Channel.SendConfirmAsync($"❗🔰{Context.User.Mention} **DESTROYED** a base #{baseNumber + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false);
await ReplyConfirmLocalized("base_destroyed", baseNumber +1, war.ShortPrint()).ConfigureAwait(false);
}
catch (Exception ex)
{

View File

@@ -27,13 +27,13 @@ namespace NadekoBot.Modules.ClashOfClans
public static void Call(this ClashWar cw, string u, int baseNumber)
{
if (baseNumber < 0 || baseNumber >= cw.Bases.Count)
throw new ArgumentException("Invalid base number");
throw new ArgumentException(cw.Localize("invalid_base_number"));
if (cw.Bases[baseNumber].CallUser != null && cw.Bases[baseNumber].Stars == 3)
throw new ArgumentException("That base is already destroyed.");
throw new ArgumentException(cw.Localize("base_already_claimed"));
for (var i = 0; i < cw.Bases.Count; i++)
{
if (cw.Bases[i]?.BaseDestroyed == false && cw.Bases[i]?.CallUser == u)
throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one.");
throw new ArgumentException(cw.Localize("claimed_other", u, i + 1));
}
var cc = cw.Bases[baseNumber];
@@ -45,7 +45,7 @@ namespace NadekoBot.Modules.ClashOfClans
public static void Start(this ClashWar cw)
{
if (cw.WarState == StateOfWar.Started)
throw new InvalidOperationException("War already started");
throw new InvalidOperationException("war_already_started");
//if (Started)
// throw new InvalidOperationException();
//Started = true;
@@ -66,7 +66,7 @@ namespace NadekoBot.Modules.ClashOfClans
cw.Bases[i].CallUser = null;
return i;
}
throw new InvalidOperationException("You are not participating in that war.");
throw new InvalidOperationException(cw.Localize("not_partic"));
}
public static string ShortPrint(this ClashWar cw) =>
@@ -75,8 +75,7 @@ namespace NadekoBot.Modules.ClashOfClans
public static string ToPrettyString(this ClashWar cw)
{
var sb = new StringBuilder();
sb.AppendLine($"🔰**WAR AGAINST `{cw.EnemyClan}` ({cw.Size} v {cw.Size}) INFO:**");
if (cw.WarState == StateOfWar.Created)
sb.AppendLine("`not started`");
var twoHours = new TimeSpan(2, 0, 0);
@@ -84,7 +83,7 @@ namespace NadekoBot.Modules.ClashOfClans
{
if (cw.Bases[i].CallUser == null)
{
sb.AppendLine($"`{i + 1}.` ❌*unclaimed*");
sb.AppendLine($"`{i + 1}.` ❌*{cw.Localize("not_claimed")}*");
}
else
{
@@ -120,7 +119,7 @@ namespace NadekoBot.Modules.ClashOfClans
cw.Bases[i].Stars = stars;
return i;
}
throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base.");
throw new InvalidOperationException(cw.Localize("not_partic_or_destroyed", user));
}
public static void FinishClaim(this ClashWar cw, int index, int stars = 3)
@@ -128,10 +127,22 @@ namespace NadekoBot.Modules.ClashOfClans
if (index < 0 || index > cw.Bases.Count)
throw new ArgumentOutOfRangeException(nameof(index));
var toFinish = cw.Bases[index];
if (toFinish.BaseDestroyed != false) throw new InvalidOperationException("That base is already destroyed.");
if (toFinish.CallUser == null) throw new InvalidOperationException("That base is unclaimed.");
if (toFinish.BaseDestroyed != false) throw new InvalidOperationException(cw.Localize("base_already_destroyed"));
if (toFinish.CallUser == null) throw new InvalidOperationException(cw.Localize("base_already_unclaimed"));
toFinish.BaseDestroyed = true;
toFinish.Stars = stars;
}
public static string Localize(this ClashWar cw, string key)
{
return NadekoModule.GetTextStatic(key,
NadekoBot.Localization.GetCultureInfo(cw.Channel?.GuildId),
typeof(ClashOfClans).Name.ToLowerInvariant());
}
public static string Localize(this ClashWar cw, string key, params object[] replacements)
{
return string.Format(cw.Localize(key), replacements);
}
}
}

View File

@@ -222,17 +222,6 @@ namespace NadekoBot.Modules.Games
return images[rng.Next(0, images.Length)];
}
int GetRandomNumber()
{
using (var rg = RandomNumberGenerator.Create())
{
byte[] rno = new byte[4];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
return randomvalue;
}
}
}
}
}

View File

@@ -13,7 +13,7 @@ namespace NadekoBot.Modules
{
protected readonly Logger _log;
protected CultureInfo _cultureInfo { get; private set; }
public readonly string _prefix;
public readonly string Prefix;
public readonly string ModuleTypeName;
public readonly string LowerModuleTypeName;
@@ -23,16 +23,14 @@ namespace NadekoBot.Modules
ModuleTypeName = isTopLevelModule ? this.GetType().Name : this.GetType().DeclaringType.Name;
LowerModuleTypeName = ModuleTypeName.ToLowerInvariant();
if (!NadekoBot.ModulePrefixes.TryGetValue(ModuleTypeName, out _prefix))
_prefix = "?err?";
if (!NadekoBot.ModulePrefixes.TryGetValue(ModuleTypeName, out Prefix))
Prefix = "?err?";
_log = LogManager.GetCurrentClassLogger();
}
protected override void BeforeExecute()
{
_cultureInfo = (Context.Guild == null
? NadekoBot.Localization.DefaultCultureInfo
: NadekoBot.Localization.GetCultureInfo(Context.Guild));
_cultureInfo = NadekoBot.Localization.GetCultureInfo(Context.Guild?.Id);
_log.Warn("Culture info is {0}", _cultureInfo);
}
@@ -60,24 +58,31 @@ namespace NadekoBot.Modules
/// <summary>
/// Used as failsafe in case response key doesn't exist in the selected or default language.
/// </summary>
private readonly CultureInfo usCultureInfo = new CultureInfo("en-US");
protected string GetText(string key)
private static readonly CultureInfo usCultureInfo = new CultureInfo("en-US");
public static string GetTextStatic(string key, CultureInfo _cultureInfo, string lowerModuleTypeName)
{
var text = NadekoBot.ResponsesResourceManager.GetString(LowerModuleTypeName + "_" + key, _cultureInfo);
var text = NadekoBot.ResponsesResourceManager.GetString(lowerModuleTypeName + "_" + key, _cultureInfo);
if (string.IsNullOrWhiteSpace(text))
{
_log.Warn(LowerModuleTypeName + "_" + key + " key is missing from " + _cultureInfo + " response strings. PLEASE REPORT THIS.");
return NadekoBot.ResponsesResourceManager.GetString(LowerModuleTypeName + "_" + key, usCultureInfo);
LogManager.GetCurrentClassLogger().Warn(lowerModuleTypeName + "_" + key + " key is missing from " + _cultureInfo + " response strings. PLEASE REPORT THIS.");
return NadekoBot.ResponsesResourceManager.GetString(lowerModuleTypeName + "_" + key, usCultureInfo) ?? $"Error: dkey {lowerModuleTypeName + "_" + key} found!";
}
return text;
return text ?? $"Error: key {lowerModuleTypeName + "_" + key} not found.";
}
protected string GetText(string key, params object[] replacements)
public static string GetTextStatic(string key, CultureInfo _cultureInfo, string lowerModuleTypeName, params object[] replacements)
{
return string.Format(GetText(key), replacements);
return string.Format(GetTextStatic(key, _cultureInfo, lowerModuleTypeName), replacements);
}
protected string GetText(string key) =>
GetTextStatic(key, _cultureInfo, LowerModuleTypeName);
protected string GetText(string key, params object[] replacements) =>
GetText(key, _cultureInfo, LowerModuleTypeName, replacements);
public Task<IUserMessage> ErrorLocalized(string textKey, params object[] replacements)
{
var text = GetText(textKey);

View File

@@ -153,7 +153,7 @@ namespace NadekoBot.Modules.Pokemon
var enabledMoves = userType.Moves;
if (!enabledMoves.Contains(move.ToLowerInvariant()))
{
await ReplyErrorLocalized("invalid_move", Format.Bold(move), _prefix).ConfigureAwait(false);
await ReplyErrorLocalized("invalid_move", Format.Bold(move), Prefix).ConfigureAwait(false);
return;
}