From 9976545276017c0a53d7132c9b393a02b0ac70a8 Mon Sep 17 00:00:00 2001 From: "Michael J. Barton" Date: Mon, 19 Aug 2024 22:32:34 -0700 Subject: [PATCH] Added FTP source type to admin lists. (#379) * Added FTP support to admin lists. * Removed debug messages. Added info to readme template. * Ran yarn build-all * Ran yarn lint --------- Co-authored-by: Marek --- README.md | 604 +++++++++--------- config.json | 200 +++--- squad-server/factory.js | 16 +- squad-server/package.json | 1 + squad-server/plugins/discord-base-plugin.js | 4 +- squad-server/plugins/discord-server-status.js | 39 +- squad-server/templates/readme-template.md | 4 + squad-server/utils/admin-lists.js | 25 + squad-server/utils/writable-buffer.js | 22 + 9 files changed, 489 insertions(+), 426 deletions(-) create mode 100644 squad-server/utils/writable-buffer.js diff --git a/README.md b/README.md index 4913f4d9..ce6873c3 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ The following section of the configuration contains information about your Squad { "type": "remote", "source": "http://yourWebsite.com/Server1/Admins.cfg", + }, + { + "type": "ftp", + "source": "ftp://:@:/", } ] }, @@ -207,15 +211,26 @@ The following is a list of plugins built into SquadJS, you can click their title Interested in creating your own plugin? [See more here](./squad-server/plugins/readme.md)
- TeamRandomizer -

TeamRandomizer

-

The TeamRandomizer can be used to randomize teams. It's great for destroying clan stacks or for social events. It can be run by typing, by default, !randomize into in-game admin chat

+ DiscordAdminCamLogs +

DiscordAdminCamLogs

+

The DiscordAdminCamLogs plugin will log in game admin camera usage to a Discord channel.

Options

-
  • command

    +
    • discordClient (Required)

      Description
      -

      The command used to randomize the teams.

      +

      Discord connector name.

      Default
      -
      randomize
    +
    discord
  • +
  • channelID (Required)

    +
    Description
    +

    The ID of the channel to log admin camera usage to.

    +
    Default
    +
  • Example
    +
    667741905228136459
    +
  • color

    +
    Description
    +

    The color of the embed.

    +
    Default
    +
    16761867
@@ -242,9 +257,9 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
- DiscordFOBHABExplosionDamage -

DiscordFOBHABExplosionDamage

-

The DiscordFOBHABExplosionDamage plugin logs damage done to FOBs and HABs by explosions to help identify engineers blowing up friendly FOBs and HABs.

+ DiscordRcon +

DiscordRcon

+

The DiscordRcon plugin allows a specified Discord channel to be used as a RCON console to run RCON commands.

Options

  • discordClient (Required)

    Description
    @@ -253,15 +268,27 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
    discord
  • channelID (Required)

    Description
    -

    The ID of the channel to log FOB/HAB explosion damage to.

    +

    ID of channel to turn into RCON console.

    Default
  • Example
    667741905228136459
    -
  • color

    +
  • permissions

    Description
    -

    The color of the embeds.

    +

    Default
    -
    16761867
+
{}
Example
+
{
+  "123456789123456789": [
+    "AdminBroadcast",
+    "AdminForceTeamChange",
+    "AdminDemoteCommander"
+  ]
+}
+
  • prependAdminNameInBroadcast

    +
    Description
    +

    Prepend admin names when making announcements.

    +
    Default
    +
    false
  • @@ -288,9 +315,9 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
    - DiscordChat -

    DiscordChat

    -

    The DiscordChat plugin will log in-game chat to a Discord channel.

    + DiscordKillFeed +

    DiscordKillFeed

    +

    The DiscordKillFeed plugin logs all wounds and related information to a Discord channel for admins to review.

    Options

    • discordClient (Required)

      Description
      @@ -299,30 +326,89 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
      discord
    • channelID (Required)

      Description
      -

      The ID of the channel to log admin broadcasts to.

      +

      The ID of the channel to log teamkills to.

      Default
    • Example
      667741905228136459
      -
    • chatColors

      -
      Description
      -

      The color of the embed for each chat.

      -
      Default
      -
      {}
    • Example
      -
      {
      -  "ChatAll": 16761867
      -}
    • color

      Description
      -

      The color of the embed.

      +

      The color of the embeds.

      Default
      16761867
    • -
    • ignoreChats

      +
    • disableCBL

      Description
      -

      A list of chat names to ignore.

      +

      Disable Community Ban List information.

      Default
      -
      [
      -  "ChatSquad"
      -]
    +
    false
    +
    + +
    + DiscordPlaceholder +

    DiscordPlaceholder

    +

    The DiscordPlaceholder plugin allows you to make your bot create placeholder messages that can be used when configuring other plugins.

    +

    Options

    +
    • discordClient (Required)

      +
      Description
      +

      Discord connector name.

      +
      Default
      +
      discord
    • +
    • command

      +
      Description
      +

      Command to create Discord placeholder.

      +
      Default
      +
      !placeholder
    • +
    • channelID (Required)

      +
      Description
      +

      The bot will only answer with a placeholder on this channel

      +
      Default
      +
    +
    + +
    + DBLog +

    DBLog

    +

    The mysql-log plugin will log various server statistics and events to a database. This is great for server performance monitoring and/or player stat tracking. + +Grafana: +

    • Grafana is a cool way of viewing server statistics stored in the database.
    • +
    • Install Grafana.
    • +
    • Add your database as a datasource named SquadJS.
    • +
    • Import the SquadJS Dashboard to get a preconfigured MySQL only Grafana dashboard.
    • +
    • Install any missing Grafana plugins.

    +

    Options

    +
    • database (Required)

      +
      Description
      +

      The Sequelize connector to log server information to.

      +
      Default
      +
      mysql
    • +
    • overrideServerID

      +
      Description
      +

      A overridden server ID.

      +
      Default
      +
      null
    +
    + +
    + CBLInfo +

    CBLInfo

    +

    The CBLInfo plugin alerts admins when a harmful player is detected joining their server based on data from the Community Ban List.

    +

    Options

    +
    • discordClient (Required)

      +
      Description
      +

      Discord connector name.

      +
      Default
      +
      discord
    • +
    • channelID (Required)

      +
      Description
      +

      The ID of the channel to alert admins through.

      +
      Default
      +
    • Example
      +
      667741905228136459
      +
    • threshold

      +
      Description
      +

      Admins will be alerted when a player has this or more reputation points. For more information on reputation points, see the Community Ban List's FAQ

      +
      Default
      +
      6
    @@ -349,32 +435,77 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
    - DiscordAdminCamLogs -

    DiscordAdminCamLogs

    -

    The DiscordAdminCamLogs plugin will log in game admin camera usage to a Discord channel.

    + ChatCommands +

    ChatCommands

    +

    The ChatCommands plugin can be configured to make chat commands that broadcast or warn the caller with present messages.

    +

    Options

    +
    • commands

      +
      Description
      +

      An array of objects containing the following properties:

      • command - The command that initiates the message.
      • type - Either warn or broadcast.
      • response - The message to respond with.
      • ignoreChats - A list of chats to ignore the commands in. Use this to limit it to admins.

      +
      Default
      +
      [
      +  {
      +    "command": "squadjs",
      +    "type": "warn",
      +    "response": "This server is powered by SquadJS.",
      +    "ignoreChats": []
      +  }
      +]
    +
    + +
    + DiscordServerStatus +

    DiscordServerStatus

    +

    The DiscordServerStatus plugin can be used to get the server status in Discord.

    Options

    • discordClient (Required)

      Description

      Discord connector name.

      Default
      discord
    • -
    • channelID (Required)

      +
    • messageStore (Required)

      Description
      -

      The ID of the channel to log admin camera usage to.

      +

      Sequelize connector name.

      Default
      -
    • Example
      -
      667741905228136459
      -
    • color

      +
      sqlite
    • +
    • command

      Description
      -

      The color of the embed.

      +

      Command name to get message.

      Default
      -
      16761867
    +
    !status
    +
  • disableSubscriptions

    +
    Description
    +

    Whether to allow messages to be subscribed to automatic updates.

    +
    Default
    +
    false
  • +
  • updateInterval

    +
    Description
    +

    How frequently to update the time in Discord.

    +
    Default
    +
    60000
  • +
  • setBotStatus

    +
    Description
    +

    Whether to update the bot's status with server information.

    +
    Default
    +
    true
  • - DiscordRcon -

    DiscordRcon

    -

    The DiscordRcon plugin allows a specified Discord channel to be used as a RCON console to run RCON commands.

    + TeamRandomizer +

    TeamRandomizer

    +

    The TeamRandomizer can be used to randomize teams. It's great for destroying clan stacks or for social events. It can be run by typing, by default, !randomize into in-game admin chat

    +

    Options

    +
    • command

      +
      Description
      +

      The command used to randomize the teams.

      +
      Default
      +
      randomize
    +
    + +
    + DiscordChat +

    DiscordChat

    +

    The DiscordChat plugin will log in-game chat to a Discord channel.

    Options

    • discordClient (Required)

      Description
      @@ -383,27 +514,30 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
      discord
    • channelID (Required)

      Description
      -

      ID of channel to turn into RCON console.

      +

      The ID of the channel to log admin broadcasts to.

      Default
    • Example
      667741905228136459
      -
    • permissions

      +
    • chatColors

      Description
      -

      +

      The color of the embed for each chat.

      Default
      {}
    • Example
      {
      -  "123456789123456789": [
      -    "AdminBroadcast",
      -    "AdminForceTeamChange",
      -    "AdminDemoteCommander"
      -  ]
      +  "ChatAll": 16761867
       }
      -
    • prependAdminNameInBroadcast

      +
    • color

      Description
      -

      Prepend admin names when making announcements.

      +

      The color of the embed.

      Default
      -
      false
    +
    16761867
    +
  • ignoreChats

    +
    Description
    +

    A list of chat names to ignore.

    +
    Default
    +
    [
    +  "ChatSquad"
    +]
  • @@ -454,56 +588,53 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
    - AutoKickUnassigned -

    AutoKickUnassigned

    -

    The AutoKickUnassigned plugin will automatically kick players that are not in a squad after a specified ammount of time.

    + DiscordDebug +

    DiscordDebug

    +

    The DiscordDebug plugin can be used to help debug SquadJS by dumping SquadJS events to a Discord channel.

    Options

    -
    • warningMessage

      +
      • discordClient (Required)

        Description
        -

        Message SquadJS will send to players warning them they will be kicked

        +

        Discord connector name.

        Default
        -
        Join a squad, you are unassigned and will be kicked
      • -
      • kickMessage

        +
        discord
      • +
      • channelID (Required)

        Description
        -

        Message to send to players when they are kicked

        -
        Default
        -
        Unassigned - automatically removed
      • -
      • frequencyOfWarnings

        -
        Description
        -

        How often in Seconds should we warn the player about being unassigned?

        -
        Default
        -
        30
      • -
      • unassignedTimer

        -
        Description
        -

        How long in Seconds to wait before a unassigned player is kicked

        -
        Default
        -
        360
      • -
      • playerThreshold

        -
        Description
        -

        Player count required for AutoKick to start kicking players, set to -1 to disable

        +

        The ID of the channel to log events to.

        Default
        -
        93
      • -
      • roundStartDelay

        +
      • Example
        +
        667741905228136459
        +
      • events (Required)

        Description
        -

        Time delay in Seconds from start of the round before AutoKick starts kicking again

        +

        A list of events to dump.

        Default
        -
        900
      • -
      • ignoreAdmins

        +
        []
      • Example
        +
        [
        +  "PLAYER_DIED"
        +]
      +
    + +
    + DiscordSubsystemRestarter +

    DiscordSubsystemRestarter

    +

    The DiscordSubSystemRestarter plugin allows you to manually restart SquadJS subsystems in case an issues arises with them.

    • !squadjs restartsubsystem rcon
    • !squadjs restartsubsystem logparser

    +

    Options

    +
    • discordClient (Required)

      Description
      -

      • true: Admins will NOT be kicked
      • false: Admins WILL be kicked

      +

      Discord connector name.

      Default
      -
      false
    • -
    • ignoreWhitelist

      +
      discord
    • +
    • role (Required)

      Description
      -

      • true: Reserve slot players will NOT be kicked
      • false: Reserve slot players WILL be kicked

      +

      ID of role required to run the sub system restart commands.

      Default
      -
      false
    +
    Example
    +
    667741905228136459
    - DiscordDebug -

    DiscordDebug

    -

    The DiscordDebug plugin can be used to help debug SquadJS by dumping SquadJS events to a Discord channel.

    + DiscordSquadCreated +

    DiscordSquadCreated

    +

    The SquadCreated plugin will log Squad Creation events to a Discord channel.

    Options

    • discordClient (Required)

      Description
      @@ -512,41 +643,57 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
      discord
    • channelID (Required)

      Description
      -

      The ID of the channel to log events to.

      +

      The ID of the channel to log Squad Creation events to.

      Default
    • Example
      667741905228136459
      -
    • events (Required)

      +
    • color

      Description
      -

      A list of events to dump.

      +

      The color of the embed.

      Default
      -
      []
    • Example
      -
      [
      -  "PLAYER_DIED"
      -]
    +
    16761867
    +
  • useEmbed

    +
    Description
    +

    Send message as Embed

    +
    Default
    +
    true
  • - CBLInfo -

    CBLInfo

    -

    The CBLInfo plugin alerts admins when a harmful player is detected joining their server based on data from the Community Ban List.

    + FogOfWar +

    FogOfWar

    +

    The FogOfWar plugin can be used to automate setting fog of war mode.

    Options

    -
    • discordClient (Required)

      +
      • mode

        Description
        -

        Discord connector name.

        +

        Fog of war mode to set.

        Default
        -
        discord
      • -
      • channelID (Required)

        +
        1
      • +
      • delay

        Description
        -

        The ID of the channel to alert admins through.

        +

        Delay before setting fog of war mode.

        Default
        -
      • Example
        -
        667741905228136459
        -
      • threshold

        +
        10000
      +
    + +
    + IntervalledBroadcasts +

    IntervalledBroadcasts

    +

    The IntervalledBroadcasts plugin allows you to set broadcasts, which will be broadcasted at preset intervals

    +

    Options

    +
    • broadcasts

      Description
      -

      Admins will be alerted when a player has this or more reputation points. For more information on reputation points, see the Community Ban List's FAQ

      +

      Messages to broadcast.

      Default
      -
      6
    +
    []
    Example
    +
    [
    +  "This server is powered by SquadJS."
    +]
    +
  • interval

    +
    Description
    +

    Frequency of the broadcasts in milliseconds.

    +
    Default
    +
    300000
  • @@ -575,74 +722,67 @@ Interested in creating your own plugin? [See more here](./squad-server/plugins/r
    - DBLog -

    DBLog

    -

    The mysql-log plugin will log various server statistics and events to a database. This is great for server performance monitoring and/or player stat tracking. - -Grafana: -

    • Grafana is a cool way of viewing server statistics stored in the database.
    • -
    • Install Grafana.
    • -
    • Add your database as a datasource named SquadJS.
    • -
    • Import the SquadJS Dashboard to get a preconfigured MySQL only Grafana dashboard.
    • -
    • Install any missing Grafana plugins.

    + AutoTKWarn +

    AutoTKWarn

    +

    The AutoTkWarn plugin will automatically warn players with a message when they teamkill.

    Options

    -
    • database (Required)

      +
      • attackerMessage

        Description
        -

        The Sequelize connector to log server information to.

        +

        The message to warn attacking players with.

        Default
        -
        mysql
      • -
      • overrideServerID

        +
        Please apologise for ALL TKs in ALL chat!
      • +
      • victimMessage

        Description
        -

        A overridden server ID.

        +

        The message that will be sent to the victim.

        Default
        null
    - DiscordSquadCreated -

    DiscordSquadCreated

    -

    The SquadCreated plugin will log Squad Creation events to a Discord channel.

    + AutoKickUnassigned +

    AutoKickUnassigned

    +

    The AutoKickUnassigned plugin will automatically kick players that are not in a squad after a specified ammount of time.

    Options

    -
    • discordClient (Required)

      +
      • warningMessage

        Description
        -

        Discord connector name.

        +

        Message SquadJS will send to players warning them they will be kicked

        Default
        -
        discord
      • -
      • channelID (Required)

        +
        Join a squad, you are unassigned and will be kicked
      • +
      • kickMessage

        Description
        -

        The ID of the channel to log Squad Creation events to.

        +

        Message to send to players when they are kicked

        Default
        -
      • Example
        -
        667741905228136459
        -
      • color

        +
        Unassigned - automatically removed
      • +
      • frequencyOfWarnings

        Description
        -

        The color of the embed.

        +

        How often in Seconds should we warn the player about being unassigned?

        Default
        -
        16761867
      • -
      • useEmbed

        +
        30
      • +
      • unassignedTimer

        Description
        -

        Send message as Embed

        +

        How long in Seconds to wait before a unassigned player is kicked

        Default
        -
        true
      -
    - -
    - ChatCommands -

    ChatCommands

    -

    The ChatCommands plugin can be configured to make chat commands that broadcast or warn the caller with present messages.

    -

    Options

    -
    • commands

      +
      360
    • +
    • playerThreshold

      Description
      -

      An array of objects containing the following properties:

      • command - The command that initiates the message.
      • type - Either warn or broadcast.
      • response - The message to respond with.
      • ignoreChats - A list of chats to ignore the commands in. Use this to limit it to admins.

      +

      Player count required for AutoKick to start kicking players, set to -1 to disable

      Default
      -
      [
      -  {
      -    "command": "squadjs",
      -    "type": "warn",
      -    "response": "This server is powered by SquadJS.",
      -    "ignoreChats": []
      -  }
      -]
    +
    93
    +
  • roundStartDelay

    +
    Description
    +

    Time delay in Seconds from start of the round before AutoKick starts kicking again

    +
    Default
    +
    900
  • +
  • ignoreAdmins

    +
    Description
    +

    • true: Admins will NOT be kicked
    • false: Admins WILL be kicked

    +
    Default
    +
    false
  • +
  • ignoreWhitelist

    +
    Description
    +

    • true: Reserve slot players will NOT be kicked
    • false: Reserve slot players WILL be kicked

    +
    Default
    +
    false
  • @@ -673,63 +813,6 @@ Grafana:
    false
    -
    - IntervalledBroadcasts -

    IntervalledBroadcasts

    -

    The IntervalledBroadcasts plugin allows you to set broadcasts, which will be broadcasted at preset intervals

    -

    Options

    -
    • broadcasts

      -
      Description
      -

      Messages to broadcast.

      -
      Default
      -
      []
    • Example
      -
      [
      -  "This server is powered by SquadJS."
      -]
      -
    • interval

      -
      Description
      -

      Frequency of the broadcasts in milliseconds.

      -
      Default
      -
      300000
    -
    - -
    - DiscordServerStatus -

    DiscordServerStatus

    -

    The DiscordServerStatus plugin can be used to get the server status in Discord.

    -

    Options

    -
    • discordClient (Required)

      -
      Description
      -

      Discord connector name.

      -
      Default
      -
      discord
    • -
    • messageStore (Required)

      -
      Description
      -

      Sequelize connector name.

      -
      Default
      -
      sqlite
    • -
    • command

      -
      Description
      -

      Command name to get message.

      -
      Default
      -
      !status
    • -
    • disableSubscriptions

      -
      Description
      -

      Whether to allow messages to be subscribed to automatic updates.

      -
      Default
      -
      false
    • -
    • updateInterval

      -
      Description
      -

      How frequently to update the time in Discord.

      -
      Default
      -
      60000
    • -
    • setBotStatus

      -
      Description
      -

      Whether to update the bot's status with server information.

      -
      Default
      -
      true
    -
    -
    DiscordAdminRequest

    DiscordAdminRequest

    @@ -803,9 +886,9 @@ Grafana:
    - DiscordKillFeed -

    DiscordKillFeed

    -

    The DiscordKillFeed plugin logs all wounds and related information to a Discord channel for admins to review.

    + DiscordFOBHABExplosionDamage +

    DiscordFOBHABExplosionDamage

    +

    The DiscordFOBHABExplosionDamage plugin logs damage done to FOBs and HABs by explosions to help identify engineers blowing up friendly FOBs and HABs.

    Options

    • discordClient (Required)

      Description
      @@ -814,7 +897,7 @@ Grafana:
      discord
    • channelID (Required)

      Description
      -

      The ID of the channel to log teamkills to.

      +

      The ID of the channel to log FOB/HAB explosion damage to.

      Default
    • Example
      667741905228136459
      @@ -822,86 +905,7 @@ Grafana:
      Description

      The color of the embeds.

      Default
      -
      16761867
      -
    • disableCBL

      -
      Description
      -

      Disable Community Ban List information.

      -
      Default
      -
      false
    -
    - -
    - AutoTKWarn -

    AutoTKWarn

    -

    The AutoTkWarn plugin will automatically warn players with a message when they teamkill.

    -

    Options

    -
    • attackerMessage

      -
      Description
      -

      The message to warn attacking players with.

      -
      Default
      -
      Please apologise for ALL TKs in ALL chat!
    • -
    • victimMessage

      -
      Description
      -

      The message that will be sent to the victim.

      -
      Default
      -
      null
    -
    - -
    - DiscordPlaceholder -

    DiscordPlaceholder

    -

    The DiscordPlaceholder plugin allows you to make your bot create placeholder messages that can be used when configuring other plugins.

    -

    Options

    -
    • discordClient (Required)

      -
      Description
      -

      Discord connector name.

      -
      Default
      -
      discord
    • -
    • command

      -
      Description
      -

      Command to create Discord placeholder.

      -
      Default
      -
      !placeholder
    • -
    • channelID (Required)

      -
      Description
      -

      The bot will only answer with a placeholder on this channel

      -
      Default
      -
    -
    - -
    - FogOfWar -

    FogOfWar

    -

    The FogOfWar plugin can be used to automate setting fog of war mode.

    -

    Options

    -
    • mode

      -
      Description
      -

      Fog of war mode to set.

      -
      Default
      -
      1
    • -
    • delay

      -
      Description
      -

      Delay before setting fog of war mode.

      -
      Default
      -
      10000
    -
    - -
    - DiscordSubsystemRestarter -

    DiscordSubsystemRestarter

    -

    The DiscordSubSystemRestarter plugin allows you to manually restart SquadJS subsystems in case an issues arises with them.

    • !squadjs restartsubsystem rcon
    • !squadjs restartsubsystem logparser

    -

    Options

    -
    • discordClient (Required)

      -
      Description
      -

      Discord connector name.

      -
      Default
      -
      discord
    • -
    • role (Required)

      -
      Description
      -

      ID of role required to run the sub system restart commands.

      -
      Default
      -
    • Example
      -
      667741905228136459
    +
    16761867

    diff --git a/config.json b/config.json index 9928ba52..dbc65944 100644 --- a/config.json +++ b/config.json @@ -46,9 +46,11 @@ }, "plugins": [ { - "plugin": "TeamRandomizer", - "enabled": true, - "command": "randomize" + "plugin": "DiscordAdminCamLogs", + "enabled": false, + "discordClient": "discord", + "channelID": "", + "color": 16761867 }, { "plugin": "DiscordAdminBroadcast", @@ -58,11 +60,12 @@ "color": 16761867 }, { - "plugin": "DiscordFOBHABExplosionDamage", - "enabled": true, + "plugin": "DiscordRcon", + "enabled": false, "discordClient": "discord", "channelID": "", - "color": 16761867 + "permissions": {}, + "prependAdminNameInBroadcast": false }, { "plugin": "DiscordRoundWinner", @@ -72,37 +75,77 @@ "color": 16761867 }, { - "plugin": "DiscordChat", - "enabled": true, + "plugin": "DiscordKillFeed", + "enabled": false, "discordClient": "discord", "channelID": "", - "chatColors": {}, "color": 16761867, - "ignoreChats": [ - "ChatSquad" - ] + "disableCBL": false }, { - "plugin": "DiscordRoundEnded", + "plugin": "DiscordPlaceholder", "enabled": true, "discordClient": "discord", - "channelID": "", - "color": 16761867 + "command": "!placeholder", + "channelID": "" }, { - "plugin": "DiscordAdminCamLogs", + "plugin": "DBLog", "enabled": false, + "database": "mysql", + "overrideServerID": null + }, + { + "plugin": "CBLInfo", + "enabled": true, + "discordClient": "discord", + "channelID": "", + "threshold": 6 + }, + { + "plugin": "DiscordRoundEnded", + "enabled": true, "discordClient": "discord", "channelID": "", "color": 16761867 }, { - "plugin": "DiscordRcon", - "enabled": false, + "plugin": "ChatCommands", + "enabled": true, + "commands": [ + { + "command": "squadjs", + "type": "warn", + "response": "This server is powered by SquadJS.", + "ignoreChats": [] + } + ] + }, + { + "plugin": "DiscordServerStatus", + "enabled": true, + "discordClient": "discord", + "messageStore": "sqlite", + "command": "!status", + "disableSubscriptions": false, + "updateInterval": 60000, + "setBotStatus": true + }, + { + "plugin": "TeamRandomizer", + "enabled": true, + "command": "randomize" + }, + { + "plugin": "DiscordChat", + "enabled": true, "discordClient": "discord", "channelID": "", - "permissions": {}, - "prependAdminNameInBroadcast": false + "chatColors": {}, + "color": 16761867, + "ignoreChats": [ + "ChatSquad" + ] }, { "plugin": "SeedingMode", @@ -116,18 +159,6 @@ "waitOnNewGames": true, "waitTimeOnNewGame": 30 }, - { - "plugin": "AutoKickUnassigned", - "enabled": true, - "warningMessage": "Join a squad, you are unassigned and will be kicked", - "kickMessage": "Unassigned - automatically removed", - "frequencyOfWarnings": 30, - "unassignedTimer": 360, - "playerThreshold": 93, - "roundStartDelay": 900, - "ignoreAdmins": false, - "ignoreWhitelist": false - }, { "plugin": "DiscordDebug", "enabled": false, @@ -136,43 +167,54 @@ "events": [] }, { - "plugin": "CBLInfo", - "enabled": true, + "plugin": "DiscordSubsystemRestarter", + "enabled": false, + "discordClient": "discord", + "role": "" + }, + { + "plugin": "DiscordSquadCreated", + "enabled": false, "discordClient": "discord", "channelID": "", - "threshold": 6 + "color": 16761867, + "useEmbed": true }, { - "plugin": "SocketIOAPI", + "plugin": "FogOfWar", "enabled": false, - "websocketPort": "", - "securityToken": "" + "mode": 1, + "delay": 10000 }, { - "plugin": "DBLog", + "plugin": "IntervalledBroadcasts", "enabled": false, - "database": "mysql", - "overrideServerID": null + "broadcasts": [], + "interval": 300000 }, { - "plugin": "DiscordSquadCreated", + "plugin": "SocketIOAPI", "enabled": false, - "discordClient": "discord", - "channelID": "", - "color": 16761867, - "useEmbed": true + "websocketPort": "", + "securityToken": "" }, { - "plugin": "ChatCommands", + "plugin": "AutoTKWarn", "enabled": true, - "commands": [ - { - "command": "squadjs", - "type": "warn", - "response": "This server is powered by SquadJS.", - "ignoreChats": [] - } - ] + "attackerMessage": "Please apologise for ALL TKs in ALL chat!", + "victimMessage": null + }, + { + "plugin": "AutoKickUnassigned", + "enabled": true, + "warningMessage": "Join a squad, you are unassigned and will be kicked", + "kickMessage": "Unassigned - automatically removed", + "frequencyOfWarnings": 30, + "unassignedTimer": 360, + "playerThreshold": 93, + "roundStartDelay": 900, + "ignoreAdmins": false, + "ignoreWhitelist": false }, { "plugin": "DiscordTeamkill", @@ -182,22 +224,6 @@ "color": 16761867, "disableCBL": false }, - { - "plugin": "IntervalledBroadcasts", - "enabled": false, - "broadcasts": [], - "interval": 300000 - }, - { - "plugin": "DiscordServerStatus", - "enabled": true, - "discordClient": "discord", - "messageStore": "sqlite", - "command": "!status", - "disableSubscriptions": false, - "updateInterval": 60000, - "setBotStatus": true - }, { "plugin": "DiscordAdminRequest", "enabled": true, @@ -214,37 +240,11 @@ "showInGameAdmins": true }, { - "plugin": "DiscordKillFeed", - "enabled": false, - "discordClient": "discord", - "channelID": "", - "color": 16761867, - "disableCBL": false - }, - { - "plugin": "AutoTKWarn", - "enabled": true, - "attackerMessage": "Please apologise for ALL TKs in ALL chat!", - "victimMessage": null - }, - { - "plugin": "DiscordPlaceholder", + "plugin": "DiscordFOBHABExplosionDamage", "enabled": true, "discordClient": "discord", - "command": "!placeholder", - "channelID": "" - }, - { - "plugin": "FogOfWar", - "enabled": false, - "mode": 1, - "delay": 10000 - }, - { - "plugin": "DiscordSubsystemRestarter", - "enabled": false, - "discordClient": "discord", - "role": "" + "channelID": "", + "color": 16761867 } ], "logger": { diff --git a/squad-server/factory.js b/squad-server/factory.js index 7bda552e..93f03831 100644 --- a/squad-server/factory.js +++ b/squad-server/factory.js @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; -import {Client, Events, GatewayIntentBits} from 'discord.js'; +import { Client, Events, GatewayIntentBits } from 'discord.js'; import sequelize from 'sequelize'; import AwnAPI from './utils/awn-api.js'; @@ -103,16 +103,20 @@ export default class SquadServerFactory { Logger.verbose('SquadServerFactory', 1, `Starting ${type} connector ${connectorName}...`); if (type === 'discord') { - const connector = new Client({intents:[ + const connector = new Client({ + intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, - GatewayIntentBits.GuildMembers, - ]}); - connector.once(Events.ClientReady, readyClient => {console.log(`Ready! Logged in as ${readyClient.user.tag}`);}); + GatewayIntentBits.GuildMembers + ] + }); + connector.once(Events.ClientReady, (readyClient) => { + console.log(`Ready! Logged in as ${readyClient.user.tag}`); + }); await connector.login(connectorConfig); // setup compatability with older plugins for message create event. - connector.on('messageCreate', message=>{ + connector.on('messageCreate', (message) => { connector.emit('message', message); }); return connector; diff --git a/squad-server/package.json b/squad-server/package.json index cbe06f00..035bd4d7 100644 --- a/squad-server/package.json +++ b/squad-server/package.json @@ -4,6 +4,7 @@ "type": "module", "dependencies": { "axios": "^0.21.1", + "basic-ftp": "^4.6.6", "core": "1.0.0", "didyoumean": "^1.2.1", "discord.js": "^14.14.1", diff --git a/squad-server/plugins/discord-base-plugin.js b/squad-server/plugins/discord-base-plugin.js index 1f1fffd0..5b339826 100644 --- a/squad-server/plugins/discord-base-plugin.js +++ b/squad-server/plugins/discord-base-plugin.js @@ -36,8 +36,8 @@ export default class DiscordBasePlugin extends BasePlugin { if (typeof message === 'object' && 'embed' in message) { message.embed.footer = message.embed.footer || { text: COPYRIGHT_MESSAGE }; if (typeof message.embed.color === 'string') - message.embed.color = parseInt(message.embed.color,16); - message = {...message, embeds:[message.embed]}; + message.embed.color = parseInt(message.embed.color, 16); + message = { ...message, embeds: [message.embed] }; } await this.channel.send(message); diff --git a/squad-server/plugins/discord-server-status.js b/squad-server/plugins/discord-server-status.js index e7d610c1..c187fced 100644 --- a/squad-server/plugins/discord-server-status.js +++ b/squad-server/plugins/discord-server-status.js @@ -54,7 +54,6 @@ export default class DiscordServerStatus extends DiscordBaseMessageUpdater { } async generateMessage() { - // Set player embed field. let players = ''; @@ -65,24 +64,25 @@ export default class DiscordServerStatus extends DiscordBaseMessageUpdater { players += ` / ${this.server.publicSlots}`; if (this.server.reserveSlots > 0) players += ` (+${this.server.reserveSlots})`; - const layerName = this.server.currentLayer ? this.server.currentLayer.name : (await this.server.rcon.getCurrentMap()).layer; + const layerName = this.server.currentLayer + ? this.server.currentLayer.name + : (await this.server.rcon.getCurrentMap()).layer; // Clamp the ratio between 0 and 1 to avoid tinygradient errors. const ratio = this.server.a2sPlayerCount / (this.server.publicSlots + this.server.reserveSlots); const clampedRatio = Math.min(1, Math.max(0, ratio)); // Set gradient embed color. - const color = - parseInt( - tinygradient([ - { color: '#ff0000', pos: 0 }, - { color: '#ffff00', pos: 0.5 }, - { color: '#00ff00', pos: 1 } - ]) - .rgbAt(clampedRatio) - .toHex(), - 16 - ); + const color = parseInt( + tinygradient([ + { color: '#ff0000', pos: 0 }, + { color: '#ffff00', pos: 0.5 }, + { color: '#00ff00', pos: 1 } + ]) + .rgbAt(clampedRatio) + .toHex(), + 16 + ); const embedobj = { title: this.server.serverName, @@ -99,18 +99,21 @@ export default class DiscordServerStatus extends DiscordBaseMessageUpdater { { name: 'Next Layer', value: `\`\`\`${ - this.server.nextLayer?.name || (this.server.nextLayerToBeVoted ? 'To be voted' : 'Unknown') + this.server.nextLayer?.name || + (this.server.nextLayerToBeVoted ? 'To be voted' : 'Unknown') }\`\`\``, inline: true } ], color: color, - footer: {text:COPYRIGHT_MESSAGE}, + footer: { text: COPYRIGHT_MESSAGE }, timestamp: new Date(), image: { - url: (this.server.currentLayer ? `https://squad-data.nyc3.cdn.digitaloceanspaces.com/main/${this.server.currentLayer.layerid}.jpg` : undefined) - }, - } + url: this.server.currentLayer + ? `https://squad-data.nyc3.cdn.digitaloceanspaces.com/main/${this.server.currentLayer.layerid}.jpg` + : undefined + } + }; return { embeds: [embedobj] }; } diff --git a/squad-server/templates/readme-template.md b/squad-server/templates/readme-template.md index 381aa644..940a9d48 100644 --- a/squad-server/templates/readme-template.md +++ b/squad-server/templates/readme-template.md @@ -84,6 +84,10 @@ The following section of the configuration contains information about your Squad { "type": "remote", "source": "http://yourWebsite.com/Server1/Admins.cfg", + }, + { + "type": "ftp", + "source": "ftp://:@:/", } ] }, diff --git a/squad-server/utils/admin-lists.js b/squad-server/utils/admin-lists.js index 1bebb9a1..9ece8266 100644 --- a/squad-server/utils/admin-lists.js +++ b/squad-server/utils/admin-lists.js @@ -1,6 +1,8 @@ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; +import { Client as FTPClient } from 'basic-ftp'; +import WritableBuffer from './writable-buffer.js'; import axios from 'axios'; import Logger from 'core/logger'; @@ -31,6 +33,29 @@ export default async function fetchAdminLists(adminLists) { data = fs.readFileSync(listPath, 'utf8'); break; } + case 'ftp': { + // ex url: ftp//:@:/ + if (!list.source.startsWith('ftp://')) { + throw new Error( + `Invalid FTP URI format of ${list.source}. The source must be a FTP URI starting with the protocol. Ex: ftp://username:password@host:21/some/file.txt` + ); + } + const [loginString, hostPathString] = list.source.substring('ftp://'.length).split('@'); + const [user, password] = loginString.split(':').map((v) => decodeURI(v)); + const pathStartIndex = hostPathString.indexOf('/'); + const remoteFilePath = + pathStartIndex === -1 ? '/' : hostPathString.substring(pathStartIndex); + const [host, port = 21] = hostPathString + .substring(0, pathStartIndex === -1 ? hostPathString.length : pathStartIndex) + .split(':'); + + const buffer = new WritableBuffer(); + const ftpClient = new FTPClient(); + await ftpClient.access({ host, port, user, password }); + await ftpClient.downloadTo(buffer, remoteFilePath); + data = buffer.toString('utf8'); + break; + } default: throw new Error(`Unsupported AdminList type:${list.type}`); } diff --git a/squad-server/utils/writable-buffer.js b/squad-server/utils/writable-buffer.js new file mode 100644 index 00000000..8df6ccf9 --- /dev/null +++ b/squad-server/utils/writable-buffer.js @@ -0,0 +1,22 @@ +import { Writable } from 'stream'; + +export class WritableBuffer extends Writable { + constructor(options) { + super(options); + this.data = []; + } + + _write(chunk, encoding, callback) { + this.data.push(chunk); + callback(); + } + + getBuffer() { + return Buffer.concat(this.data); + } + + toString(encoding = 'utf8') { + return this.getBuffer().toString(encoding); + } +} +export default WritableBuffer;