poundbot / rust-plugins

1 stars 0 forks source link

tr lang. poundbot.cs #2

Open GameTeamWar opened 5 years ago

GameTeamWar commented 5 years ago

using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Oxide.Core; using Oxide.Core.Libraries; using Oxide.Core.Libraries.Covalence; using Oxide.Core.Plugins; using System; using System.Linq; using System.Collections.Generic; using System.Text.RegularExpressions;

namespace Oxide.Plugins { [Info("Pound Bot", "MrPoundsign", "2.0.0")] [Description("Connector for the Discord bot PoundBot.")]

class PoundBot : CovalencePlugin { const string EntityDeathURI = "/entity_death"; const string ApiMessageBaseURI = "/messages"; const string ApiRolesURI = "/roles"; const string ApiChatURI = "/chat"; const string ApiRegisteredPlayersURI = "/players/registered"; const string ApiDiscordAuthURI = "/discord_auth"; const string ApiClansURI = "/clans";

private string ApiBaseURI;

enum DebugLevels { TRACE, INFO };

protected string DebugURI = "";
protected int DebugLevel = (int)DebugLevels.INFO;
protected int ApiRetrySeconds = 1;
protected int ApiRetryNotify = 30;

protected string RegisteredUsersGroup;
protected bool ApiInError;
protected bool ApiRetry;
protected uint ApiRetryAttempts;
protected DateTime ApiErrorTime;
protected DateTime LastApiAttempt;
private Dictionary<string, string> RequestHeaders;
protected bool RegisteredUsersInFlight;
private ChannelList KnownChannelList;

class ApiErrorResponse
{
  public string Error;
}

class ApiRequest
{
  public RequestMethod Method;
  public string URI;
  public string Body;
  public Plugin Plugin;
  public string RequestUUID;

  public ApiRequest(RequestMethod method, string uri, string body, Plugin plugin)
  {
    Method = method;
    URI = uri;
    Body = body;
    Plugin = plugin;
    RequestUUID = Guid.NewGuid().ToString();
  }
}

#region PoundBot messages
class Channel
{
  public string ID;
  public string Name;
  public bool CanSend;
  public bool CanStyle;

  public bool IsAvailable()
  {
    return CanSend || CanStyle;
  }
}

class ChannelList
{
  public Channel[] Channels;

  public bool CanSendTo(string channel)
  {
    foreach (Channel chan in Channels)
    {
      if (chan.Name == channel || chan.ID == channel)
      {
        return chan.CanSend;
      }
    }
    return false;
  }

  public bool CanStyleTo(string channel)
  {
    foreach (Channel chan in Channels)
    {
      if (chan.Name == channel || chan.ID == channel)
      {
        return chan.CanStyle;
      }
    }
    return false;
  }
}

class DiscordAuth
{
  public string PlayerID;
  public string DisplayName;
  public string ClanTag;
  public string DiscordName;
  public int Pin;
  public DateTime CreatedAt;

  public DiscordAuth(string displayName, string discordName, string playerid)
  {
    Pin = new System.Random().Next(1, 9999);
    DisplayName = displayName;
    DiscordName = discordName;
    PlayerID = playerid;
    CreatedAt = DateTime.UtcNow;
  }
}

public class GameMessageEmbedStyle
{
  public string Color { get; set; }
}

class GameMessagePart
{
  public string Content { get; set; }
  public bool Escape { get; set; }
}

class GameMessage
{
  public GameMessagePart[] MessageParts { get; set; }
  public int Type { get; set; } // 0 = plain, 1 = embedded
  public GameMessageEmbedStyle EmbedStyle { get; set; }
}

class RoleSyncRequest
{
  public string GuildID;
  public string[] PlayerIDs;
}

class EntityDeath
{
  public string Name;
  public string GridPos;
  public string[] OwnerIDs;
  public DateTime CreatedAt;

  public EntityDeath(string name, string gridpos, string[] ownerIDs)
  {
    Name = name;
    GridPos = gridpos;
    OwnerIDs = ownerIDs;
    CreatedAt = DateTime.UtcNow;
  }
}
#endregion

#region Configuration
protected override void LoadDefaultConfig()
{
  Config["api.url"] = "https://api.poundbot.com/";
  Config["api.key"] = "API Anahtarı Buraya Gelecek";
  Config["config.version"] = 2;
  Config["players.registered.group"] = "default";
}

void UpgradeConfig()
{
  string configVersion = "config.version";
  bool dirty = false;

  if (Config[configVersion] == null)
  {
    Config[configVersion] = 1;
  }
  else
  {
    try
    {
      var foo = (string)Config[configVersion];
      Config[configVersion] = 2;
      dirty = true;
    }
    catch (InvalidCastException) { } // testing if it can be converted to a string or not. No need to change it because it's not a string.
  }

  if ((int)Config[configVersion] < 2)
  {
    LogWarning(string.Format(lang.GetMessage("config.upgrading", this), "1.1.2"));

    // Update the API endpoint
    string api_url = (string)Config["api_url"];
    if (api_url == "http://poundbot.mrpoundsign.com/" || api_url == "http://api.poundbot.com/")
    {
      Config["api.url"] = "https://api.poundbot.com/";
    }
    else
    {
      Config["api.url"] = (string)Config["api_url"];
    }
    Config["api.key"] = (string)Config["api_key"];
    Config.Remove("api_url");
    Config.Remove("api_key");
    Config["players.registered.group"] = "poundbot.registered";
    Config[configVersion] = 2;
    dirty = true;
  }

  if (dirty)
  {
    SaveConfig();
  }
}
#endregion

#region Language
protected override void LoadDefaultMessages()
{
  lang.RegisterMessages(new Dictionary<string, string>
  {
    ["config.upgrading"] = "Config Dosyasını v{0} Yükseltme",
    ["config.api_key_updated"] = "API anahtarınız güncellendi. Config / PoundBot.json dosyasını kontrol edin.",
    ["command.poundbot_register"] = "pbkayıt",
    ["connector.reconnected"] = "PoundBot Tekrar Bağlanıldı",
    ["connector.time_in_error"] = "Toplamda Hatalı Bağlanma Süresi: {0}",
    ["connector.error"] = "PoundBot İle Bağlantı Kurulurken Hata Oluştu: {0}:{1}",
    ["connector.error_with_rid"] = "PoundBot İle Bağlantı Kesildi Ve Hata oluştu: [{0}] {1}:{2}",
    ["connector.user_error"] = "PoundBot’a Şu Anda Bağlanılamıyor. Lütfen Yöneticileri Uyarın.",
    ["discord.pin"] = "Bu Kodu Discord Üzerinde Bot'a Gönderiniz: {0}.",
    ["discord.connected"] = "Kayıt İşlemi Tamamlandı!",
    ["discord.already_connected"] = "Önceden Kayıt İşlemi Yapmış Görünüyorsun!",
    ["discord.not_connected"] = "Kayıt Bulunamadı.",
    ["discord.channels_updated"] = "Mevcut Kanal Güncelendi!",
    ["discord.channel_cannot_send"] = "Discord {0} Kanalına Bildirim Gönderilemiyor. Lütfen Botun Bu Kanala Bağlantısını Kontrol Edin. Önbelleği Güncellemek İçin Discord Değişiklikleri Yaptıktan Sonra \tpb.kanalgüncelle Komutunu Kanalda Çalıştırın.",
    ["discord.channel_cannot_style"] = "Discord {0} Kanalına Bildirim Gönderilemiyor. Lütfen Kanal İd'sini Yerleştirdiğinizi Ve Botun Bu Kanala Bağlantısını Kontrol edin. Önbelleği Güncellemek İçin Değişiklikleri Yaptıktan Sonra ! pb.kanalgüncelle Komutunu Kanalda Çalıştırın.",
    ["usage.pbreg"] = "Usage: /pbkayıt \"<discord ismi>\"\n Örnek: /discord \"Fantezi Adamı#8080\"",
    ["usage.set_api_key"] = "Kullanımı:\n\tpb.api_ayar <api key>",
    ["discord.console.registration_attempt"] = "{0} ({1}) oyuncusu {2} olarak kaydolmaya çalışıyor",
  }, this);
}

#endregion

#region Oxide API
void Init()
{
  UpgradeConfig();
  ApiBaseURI = $"{Config["api.url"]}api";
  ApplyConfig();

  RegisteredUsersGroup = (string)Config["players.registered.group"];
  permission.RegisterPermission(RegisteredUsersGroup, this);
  if (!permission.GroupExists(RegisteredUsersGroup))
  {
    permission.CreateGroup(RegisteredUsersGroup, "PoundBot Registered Users", 0);
  }

  AddLocalizedCommand("command.poundbot_register", "CommandPoundBotRegister");

  Connected();

  timer.Every(5f, () =>
  {
    if (RegisteredUsersInFlight) return;
    RegisteredUsersInFlight = true;
    Request(new ApiRequest(RequestMethod.GET, ApiRegisteredPlayersURI, null, this),
    (code, response) =>
    {
      RegisteredUsersInFlight = false;
      if (code == 200)
      {
        string[] groupPlayerIDs = permission.GetUsersInGroup(RegisteredUsersGroup);
        string[] playerIDs = JsonConvert.DeserializeObject<string[]>(response);

        for (int i = 0; i < groupPlayerIDs.Length; i++)
        {
          groupPlayerIDs[i] = groupPlayerIDs[i].Substring(0, groupPlayerIDs[i].IndexOf(' '));
        }

        // hot group diff action
        string[] playersToRemove = groupPlayerIDs.Except(playerIDs).ToArray();
        string[] playersToAdd = playerIDs.Except(groupPlayerIDs).ToArray();

        if (playersToAdd.Length + playersToRemove.Length == 0)
        {
          return true;
        }

        foreach (string id in playersToRemove)
        {
          Puts($"Removing user {id} from {RegisteredUsersGroup}");
          permission.RemoveUserGroup(id, RegisteredUsersGroup);
        }

        foreach (string id in playersToAdd)
        {
          Puts($"Adding user {id} to {RegisteredUsersGroup}");
          permission.AddUserGroup(id, RegisteredUsersGroup);
        }
        return true;
      }

      Puts("Unuccessful registered players get");
      Puts(response);
      return false;
    });
  });
}
#endregion

private void ApplyConfig()
{
  RequestHeaders = new Dictionary<string, string>
  {
    ["Content-type"] = "application/json",
    ["Authorization"] = $"Token {Config["api.key"]}",
    ["X-PoundBotConnector-Version"] = Version.ToString(),
    ["User-Agent"] = $"PoundBotConnector/{Version.ToString()}",
    ["X-PoundBot-Game"] = covalence.Game.ToLower()
  };
}

#region API

// private Dictionary<string, string> Headers() => RequestHeaders;

private string API_RegisteredUsersGroup() => RegisteredUsersGroup;

private string ApiBase() => ApiBaseURI;

private bool ApiRequestOk()
{
  if (ApiInError && !ApiRetry && (LastApiAttempt.AddSeconds(ApiRetrySeconds) < DateTime.Now))
  {
    ApiRetryAttempts++;
    if (ApiRetryAttempts == 1 || ApiRetryAttempts % ApiRetryNotify == 0)
    {
      Puts(string.Format(lang.GetMessage("connector.time_in_error", this), DateTime.Now.Subtract(ApiErrorTime)));
    }
    ApiRetry = true;
  }
  return (!ApiInError || ApiRetry);
}

private void ApiError(int code, string response, string requestID = null)
{
  string error;
  if (ApiInError)
  {
    if (ApiRetry)
    {
      LastApiAttempt = DateTime.Now;
      ApiRetry = false;
    }

    if (ApiRetryAttempts % ApiRetryNotify != 0) return;
  }
  else
  {
    ApiErrorTime = DateTime.Now;
    LastApiAttempt = DateTime.Now;
    ApiInError = true;
    ApiRetry = false;
  }

  if (code == 0)
  {
    error = "Bağlantı hatası!";
  }
  else
  {
    try
    {
      var air = JsonConvert.DeserializeObject<ApiErrorResponse>(response);
      error = air.Error;
    }
    catch
    {
      error = response;
    }
  }
  if (code == 0)
  {
    Puts(string.Format(lang.GetMessage("connector.error", this), code, error));
    return;
  }
  Puts(string.Format(lang.GetMessage("connector.error_with_rid", this), requestID, code, error));

}

private bool ApiSuccess(bool success)
{
  // Reset retry variables if we're successful
  if (ApiInError && success)
  {
    Puts(lang.GetMessage("connector.reconnected", this));
    Puts(string.Format(lang.GetMessage("connector.time_in_error", this), DateTime.Now.Subtract(ApiErrorTime)));
    ApiRetryAttempts = 0;
    ApiInError = false;
    ApiRetry = true;
    Connected();
  }
  return success;
}

#region Requests

private bool Request(ApiRequest api_request, Func<int, string, bool> callback)
{
  if (!ApiRequestOk()) return false;

  if (DebugURI != "" && api_request.URI.StartsWith(DebugURI))
  {
    Puts($"Request from {api_request.Plugin.Name} to {api_request.URI} with RequestUUID {api_request.RequestUUID}");
  }

  if (api_request.Plugin == null)
  {
    api_request.Plugin = this;
  }

  Dictionary<string, string> rHeaders = new Dictionary<string, string>(RequestHeaders);
  rHeaders["X-Request-ID"] = api_request.RequestUUID;

  webrequest.Enqueue($"{ApiBaseURI}{api_request.URI}", api_request.Body,
  (code, response) =>
  {
    if (!ApiSuccess(callback(code, response)))
    {
      ApiError(code, response, rHeaders["X-Request-ID"]);
    }
  },
  api_request.Plugin, api_request.Method, rHeaders, 12000f);

  return true;
}
// Returns true if request was sent, false otherwise.
private bool API_Request(string uri, string body, Func<int, string, bool> callback, Plugin owner, RequestMethod method = RequestMethod.GET, Dictionary<string, string> headers = null)
{
  return Request(new ApiRequest(method, uri, body, this), callback);
}
#endregion

#region Messages API
private bool API_SendChannelMessage(Plugin owner, string channel, KeyValuePair<string, bool>[] message_parts, string embed_color = null, Func<int, string, bool> callback = null, Dictionary<string, string> headers = null, string type = "plain")
{
  List<GameMessagePart> parts = new List<GameMessagePart>();

  foreach (KeyValuePair<string, bool> part in message_parts)
  {
    parts.Add(
      new GameMessagePart
      {
        Content = part.Key,
        Escape = part.Value
      }
    );
  }

  GameMessage sm = new GameMessage
  {
    MessageParts = parts.ToArray()
  };

  if (embed_color != null)
  {
    if (!KnownChannelList.CanStyleTo(channel))
    {
      Puts(string.Format(lang.GetMessage("discord.channel_cannot_style", this), channel));
      return false;
    }
    sm.Type = 1;
    sm.EmbedStyle = new GameMessageEmbedStyle
    {
      Color = embed_color
    };
  }
  else
  {
    if (!KnownChannelList.CanSendTo(channel))
    {
      Puts(string.Format(lang.GetMessage("discord.channel_cannot_send", this), channel));
      return false;
    }
  }

  if (channel[0] == '#')
  {
    channel = channel.Substring(1);
  }

  if (callback == null)
  {
    callback = (int code, string response) => (code == 200);
  }

  string body = JsonConvert.SerializeObject(sm);
  return Request(new ApiRequest(RequestMethod.POST, $"{ApiMessageBaseURI}/{channel}", body, owner), callback);
}

private bool API_GetChannelMessage(Plugin owner, string channel, Func<int, string, bool> callback = null)
{
  return Request(new ApiRequest(RequestMethod.GET, ApiChatURI, null, owner), callback);
}
#endregion

#region Roles API
private bool API_SendRole(Plugin owner, string[] groupPlayerIDs, string role, Func<int, string, bool> callback)
{
  RoleSyncRequest rsr = new RoleSyncRequest
  {
    PlayerIDs = groupPlayerIDs,
  };

  return Request(new ApiRequest(RequestMethod.POST, $"{ApiRolesURI}/{role}", JsonConvert.SerializeObject(rsr), owner), callback);
}
#endregion

private bool API_SendEntityDeath(Plugin owner, string name, string gridPos, string[] owners, Func<int, string, bool> callback)
{
  EntityDeath di = new EntityDeath(name, gridPos, owners);

  return Request(new ApiRequest(RequestMethod.PUT, EntityDeathURI, JsonConvert.SerializeObject(di), owner), callback);
}

private bool API_SendClans(Plugin owner, List<JObject> clans, Func<int, string, bool> callback)
{
  return Request(new ApiRequest(RequestMethod.PUT, ApiClansURI, JsonConvert.SerializeObject(clans), owner), callback);
}

private bool API_SendClan(Plugin owner, string tag, JObject clan, Func<int, string, bool> callback)
{
  return Request(new ApiRequest(RequestMethod.PUT, $"{ApiClansURI}/{tag}", JsonConvert.SerializeObject(clan), owner), callback);
}

private bool API_DeleteClan(Plugin owner, string tag, Func<int, string, bool> callback)
{
  return Request(new ApiRequest(RequestMethod.DELETE, $"{ApiClansURI}/{tag}", null, owner), callback);
}

private void Connected()
{
  UpdateChannels();
  Interface.Call("OnPoundBotConnected");
}
#endregion

private void UpdateChannels()
{
  Request(new ApiRequest(RequestMethod.GET, ApiMessageBaseURI, null, this),
      (code, response) =>
      {
        if (code == 200)
        {
          KnownChannelList = JsonConvert.DeserializeObject<ChannelList>(response);
          Puts(lang.GetMessage("discord.channels_updated", this));
          return true;
        }

        return false;
      });
}

public void PrintChannels(bool all = false)
{
  foreach (Channel c in KnownChannelList.Channels)
  {
    if (all || c.IsAvailable())
    {
      Puts($"ID: {c.ID}, Name: {c.Name}, CanSend: {c.CanSend}, CanStyle: {c.CanStyle}");
    }
  }
}

#region Helpers
private void AddLocalizedCommand(string key, string command)
{
  foreach (var language in lang.GetLanguages(this))
  {
    var messages = lang.GetMessages(language, this);
    foreach (var message in messages.Where(m => m.Key.Equals(key)))
      if (!string.IsNullOrEmpty(message.Value)) AddCovalenceCommand(message.Value, command);
  }
}
#endregion

#region Commands
private void CommandPoundBotRegister(IPlayer player, string command, string[] args)
{
  if (args.Length != 1)
  {
    player.Message(lang.GetMessage("usage.pbreg", this, player.Id));
    return;
  }

  if (args[0] == "check")
  {
    Request(new ApiRequest(RequestMethod.GET, $"{ApiDiscordAuthURI}/check/{player.Id}", null, this),
    (code, response) =>
    {
      if (code == 200)
      {
        player.Message(lang.GetMessage("discord.connected", this, player.Id));
        return true;
      }

      if (code == 404) // Method not allowed means we're already connected
      {
        player.Message(lang.GetMessage("discord.not_connected", this, player.Id));
        return true;
      }

      return false;
    });

    return;
  }

  Regex r = new Regex(@"^[^#]+#[0-9]+$");
  if (!r.Match(args[0]).Success)
  {
    player.Message(lang.GetMessage("usage.pbreg", this, player.Id));
    return;
  }

  string.Format(lang.GetMessage("discord.console.registration_attempt", this), player.Name, player.Id, args[0]);

  var da = new DiscordAuth(player.Name, args[0], player.Id);

  Request(new ApiRequest(RequestMethod.PUT, ApiDiscordAuthURI, JsonConvert.SerializeObject(da), this),
    (code, response) =>
    {
      if (code == 200)
      {
        player.Message(string.Format(lang.GetMessage("discord.pin", this, player.Id), da.Pin.ToString("D4")));
        return true;
      }

      if (code == 409) // Conflict means we're already connected
      {
        player.Message(lang.GetMessage("discord.already_connected", this, player.Id));
        return true;
      }

      return false;
    });
}

[Command("pb.kanal_güncelle")]
private void ConsoleCommandUpdateChannels(IPlayer player, string command, string[] args)
{
  UpdateChannels();
}

[Command("pb.kanal")]
private void ConsoleCommandChannels(IPlayer player, string command, string[] args)
{
  PrintChannels((args.Length != 0));
}

[Command("pb.api_ayar")]
private void ConsoleCommandSetAPIKey(IPlayer player, string command, string[] args)
{
  if (args.Count() != 1)
  {
    Puts(lang.GetMessage("usage.set_api_key", this));
    return;
  }

  Puts(lang.GetMessage("config.api_key_updated", this));
  Config["api.key"] = args[0];
  SaveConfig();
  ApplyConfig();
}

[Command("pb.hata_ayıkla")]
private void ConsoleCommandSetDebugURI(IPlayer player, string command, string[] args)
{
  if (args.Count() != 1)
  {
    Puts(lang.GetMessage("usage.set_debug_uri", this));
    return;
  }

  DebugURI = args[0];
}
#endregion

} }

mrpoundsign commented 5 years ago

Thanks, @GameTeamWar, but at this time, it's not possible to translate the commands. I will do some research and see if I can get it into the lang files.