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;
}

View File

@ -59,6 +59,213 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to That base is already claimed or destroyed..
/// </summary>
public static string clashofclans_base_already_claimed {
get {
return ResourceManager.GetString("clashofclans_base_already_claimed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to That base is already destroyed..
/// </summary>
public static string clashofclans_base_already_destroyed {
get {
return ResourceManager.GetString("clashofclans_base_already_destroyed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to That base is not claimed..
/// </summary>
public static string clashofclans_base_already_unclaimed {
get {
return ResourceManager.GetString("clashofclans_base_already_unclaimed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to **DESTROYED** base #{0} in a war against {1}.
/// </summary>
public static string clashofclans_base_destroyed {
get {
return ResourceManager.GetString("clashofclans_base_destroyed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} has **UNCLAIMED** base #{1} in a war against {2}.
/// </summary>
public static string clashofclans_base_unclaimed {
get {
return ResourceManager.GetString("clashofclans_base_unclaimed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Claim from @{0} for a war against {1} has expired..
/// </summary>
public static string clashofclans_claim_expired {
get {
return ResourceManager.GetString("clashofclans_claim_expired", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} claimed a base #{1} in a war against {2}.
/// </summary>
public static string clashofclans_claimed_base {
get {
return ResourceManager.GetString("clashofclans_claimed_base", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to @{0} You already claimed base #{1}. You can&apos;t claim a new one..
/// </summary>
public static string clashofclans_claimed_other {
get {
return ResourceManager.GetString("clashofclans_claimed_other", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enemy.
/// </summary>
public static string clashofclans_enemy {
get {
return ResourceManager.GetString("clashofclans_enemy", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Info about war against {0}.
/// </summary>
public static string clashofclans_info_about_war {
get {
return ResourceManager.GetString("clashofclans_info_about_war", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid base number..
/// </summary>
public static string clashofclans_invalid_base_number {
get {
return ResourceManager.GetString("clashofclans_invalid_base_number", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Not a Valid war size..
/// </summary>
public static string clashofclans_invalid_size {
get {
return ResourceManager.GetString("clashofclans_invalid_size", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to List Of Active Wars.
/// </summary>
public static string clashofclans_list_active_wars {
get {
return ResourceManager.GetString("clashofclans_list_active_wars", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No active wars..
/// </summary>
public static string clashofclans_no_active_wars {
get {
return ResourceManager.GetString("clashofclans_no_active_wars", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to not claimed.
/// </summary>
public static string clashofclans_not_claimed {
get {
return ResourceManager.GetString("clashofclans_not_claimed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You are not participating in that war..
/// </summary>
public static string clashofclans_not_partic {
get {
return ResourceManager.GetString("clashofclans_not_partic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to @{0} You are either not participating in that war, or that base is already destroyed..
/// </summary>
public static string clashofclans_not_partic_or_destroyed {
get {
return ResourceManager.GetString("clashofclans_not_partic_or_destroyed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Size.
/// </summary>
public static string clashofclans_size {
get {
return ResourceManager.GetString("clashofclans_size", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to War against {0} has already started..
/// </summary>
public static string clashofclans_war_already_started {
get {
return ResourceManager.GetString("clashofclans_war_already_started", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to War against {0} created..
/// </summary>
public static string clashofclans_war_created {
get {
return ResourceManager.GetString("clashofclans_war_created", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to War against {0} ended..
/// </summary>
public static string clashofclans_war_ended {
get {
return ResourceManager.GetString("clashofclans_war_ended", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to That war does not exist..
/// </summary>
public static string clashofclans_war_not_exist {
get {
return ResourceManager.GetString("clashofclans_war_not_exist", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to War against {0} started!.
/// </summary>
public static string clashofclans_war_started {
get {
return ResourceManager.GetString("clashofclans_war_started", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} has already fainted..
/// </summary>

View File

@ -117,6 +117,75 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="clashofclans_base_already_claimed" xml:space="preserve">
<value>That base is already claimed or destroyed.</value>
</data>
<data name="clashofclans_base_already_destroyed" xml:space="preserve">
<value>That base is already destroyed.</value>
</data>
<data name="clashofclans_base_already_unclaimed" xml:space="preserve">
<value>That base is not claimed.</value>
</data>
<data name="clashofclans_base_destroyed" xml:space="preserve">
<value>**DESTROYED** base #{0} in a war against {1}</value>
</data>
<data name="clashofclans_base_unclaimed" xml:space="preserve">
<value>{0} has **UNCLAIMED** base #{1} in a war against {2}</value>
</data>
<data name="clashofclans_claimed_base" xml:space="preserve">
<value>{0} claimed a base #{1} in a war against {2}</value>
</data>
<data name="clashofclans_claimed_other" xml:space="preserve">
<value>@{0} You already claimed base #{1}. You can't claim a new one.</value>
</data>
<data name="clashofclans_claim_expired" xml:space="preserve">
<value>Claim from @{0} for a war against {1} has expired.</value>
</data>
<data name="clashofclans_enemy" xml:space="preserve">
<value>Enemy</value>
</data>
<data name="clashofclans_info_about_war" xml:space="preserve">
<value>Info about war against {0}</value>
</data>
<data name="clashofclans_invalid_base_number" xml:space="preserve">
<value>Invalid base number.</value>
</data>
<data name="clashofclans_invalid_size" xml:space="preserve">
<value>Not a Valid war size.</value>
</data>
<data name="clashofclans_list_active_wars" xml:space="preserve">
<value>List Of Active Wars</value>
</data>
<data name="clashofclans_not_claimed" xml:space="preserve">
<value>not claimed</value>
</data>
<data name="clashofclans_not_partic" xml:space="preserve">
<value>You are not participating in that war.</value>
</data>
<data name="clashofclans_not_partic_or_destroyed" xml:space="preserve">
<value>@{0} You are either not participating in that war, or you have already destroyed a base.</value>
</data>
<data name="clashofclans_no_active_wars" xml:space="preserve">
<value>No active wars.</value>
</data>
<data name="clashofclans_size" xml:space="preserve">
<value>Size</value>
</data>
<data name="clashofclans_war_already_started" xml:space="preserve">
<value>War against {0} is already started.</value>
</data>
<data name="clashofclans_war_created" xml:space="preserve">
<value>War against {0} created.</value>
</data>
<data name="clashofclans_war_ended" xml:space="preserve">
<value>War against {0} ended.</value>
</data>
<data name="clashofclans_war_not_exist" xml:space="preserve">
<value>That war does not exist.</value>
</data>
<data name="clashofclans_war_started" xml:space="preserve">
<value>War against {0} started!</value>
</data>
<data name="pokemon_already_fainted" xml:space="preserve">
<value>{0} has already fainted.</value>
</data>

View File

@ -184,4 +184,73 @@
<data name="pokemon_you_fainted" xml:space="preserve">
<value>Онесвешћен си, не можеш да се крећеш.</value>
</data>
<data name="clashofclans_base_already_claimed" xml:space="preserve">
<value>Та база је већ под захетвом или је уништена.</value>
</data>
<data name="clashofclans_base_already_destroyed" xml:space="preserve">
<value>Та база је већ под захтевом.</value>
</data>
<data name="clashofclans_base_already_unclaimed" xml:space="preserve">
<value>Та база није под захтевом.</value>
</data>
<data name="clashofclans_base_unclaimed" xml:space="preserve">
<value>{0} је **ПОНИШТИО ЗАХТЕВ** за базу #{1} у рату против {2}</value>
</data>
<data name="clashofclans_claimed_base" xml:space="preserve">
<value>{0} захтева базу #{1} у рату против {2}</value>
</data>
<data name="clashofclans_claimed_other" xml:space="preserve">
<value>@{0} Ти већ захтеваш базу #{1}. Не можеш захтевати још једну.</value>
</data>
<data name="clashofclans_claim_expired" xml:space="preserve">
<value>Захтев од @{0} за рат против {1} је истекао.</value>
</data>
<data name="clashofclans_enemy" xml:space="preserve">
<value>Противник</value>
</data>
<data name="clashofclans_info_about_war" xml:space="preserve">
<value>Подаци о рату против {0}</value>
</data>
<data name="clashofclans_invalid_base_number" xml:space="preserve">
<value>Број базе није валидан.</value>
</data>
<data name="clashofclans_invalid_size" xml:space="preserve">
<value>Величина рата није валидна.</value>
</data>
<data name="clashofclans_list_active_wars" xml:space="preserve">
<value>Листа Ратова У Току</value>
</data>
<data name="clashofclans_not_claimed" xml:space="preserve">
<value>нема захтева</value>
</data>
<data name="clashofclans_not_partic" xml:space="preserve">
<value>Ти не учествујеш у том рату.</value>
</data>
<data name="clashofclans_not_partic_or_destroyed" xml:space="preserve">
<value>@{0} Ти или не учествујеш у рату или је та база већ уништена.</value>
</data>
<data name="clashofclans_no_active_wars" xml:space="preserve">
<value>Нема ратова у току.</value>
</data>
<data name="clashofclans_size" xml:space="preserve">
<value>Величина</value>
</data>
<data name="clashofclans_war_already_started" xml:space="preserve">
<value>Рат против {0} је већ почео.</value>
</data>
<data name="clashofclans_war_created" xml:space="preserve">
<value>Рат против {0} је направљен.</value>
</data>
<data name="clashofclans_war_ended" xml:space="preserve">
<value>Рат против {0} је завршен.</value>
</data>
<data name="clashofclans_war_not_exist" xml:space="preserve">
<value>Тај рат не постоји.</value>
</data>
<data name="clashofclans_war_started" xml:space="preserve">
<value>Рат против {0} је започет!</value>
</data>
<data name="clasofclans_base_destroyed" xml:space="preserve">
<value>је **УНИШТИО** базу #{0} у рату против {1}</value>
</data>
</root>

View File

@ -102,12 +102,14 @@ namespace NadekoBot.Services
SetDefaultCulture(CultureInfo.CurrentCulture);
public CultureInfo GetCultureInfo(IGuild guild) =>
GetCultureInfo(guild.Id);
GetCultureInfo(guild?.Id);
public CultureInfo GetCultureInfo(ulong guildId)
public CultureInfo GetCultureInfo(ulong? guildId)
{
if (guildId == null)
return DefaultCultureInfo;
CultureInfo info = null;
GuildCultureInfos.TryGetValue(guildId, out info);
GuildCultureInfos.TryGetValue(guildId.Value, out info);
return info ?? DefaultCultureInfo;
}