{
  "name": "VotingSystem",
  "author": "r20",
  "supportedGames": [
    "all"
  ],
  "takaroVersion": "main",
  "versions": [
    {
      "tag": "latest",
      "description": "# R20_VotingSystem: Server Voting & Reward Platform\n\nThe **R20_VotingSystem** module provides a complete voting and rewards integration for your gaming server. This comprehensive Takaro module connects with popular voting platforms to incentivize players to vote for your server, increasing visibility and rankings.\n\n## Key Benefits:\n- **Voting Site Integration**: Seamless connection with popular server listing platforms\n- **Flexible Reward Configuration**: Multiple reward types for complete customization\n- **Random Reward System**: Element of surprise with randomized item distribution\n- **API Communication**: Automatic verification of player votes\n- **Anti-Abuse Protection**: Prevents duplicate reward claims\n\n## Features:\n* Support for major voting platforms including 7daystodie-servers.com and rust-servers.net\n* Configurable currency rewards integrated with server economy\n* Random item rewards with customizable probability\n* Fixed item rewards for guaranteed player benefits\n* Custom notification messages for successful votes\n* Public announcements to encourage community participation\n* Detailed player feedback during reward distribution\n* SteamID and username authentication support.",
      "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"required\":[\"votingsite\",\"votekey\",\"novote\",\"alreadyclaimed\"],\"additionalProperties\":false,\"properties\":{\"votingsite\":{\"title\":\"votingsite\",\"description\":\"Site where players vote. Example: \\nhttps://7daystodie-servers.com for 7 Days to Die;\\nhttps://rust-servers.net for RUST\\n\\n\",\"default\":\"https://7daystodie-servers.com\",\"type\":\"string\"},\"votekey\":{\"title\":\"votekey\",\"description\":\"Vote key provided by the voting site\",\"type\":\"string\"},\"novote\":{\"title\":\"novote\",\"description\":\"Message to send to the player when voting site reports no vote was cast. \",\"default\":\"You haven't voted yet. Please vote at https://7daystodie-servers.com first.\",\"type\":\"string\"},\"alreadyclaimed\":{\"title\":\"alreadyclaimed\",\"description\":\"Message to send to the player when the voting site reports the vote reward was already claimed.\",\"default\":\"You have already claimed your last vote.\",\"type\":\"string\"},\"privatemessage\":{\"title\":\"privatemessage\",\"description\":\"Optional message to send to the player when the voting site reports a vote with no reward claimed yet. \\nExample: Thanks for voting.\\nLeave it blank if you want nothing to be sent instead.\",\"default\":\"\",\"type\":\"string\"},\"publicmessage\":{\"title\":\"publicmessage\",\"description\":\"Optional message to broadcast to all players online when vote is successful. Use {name} in the message to refer to the player name.\\nExample: [00FF00]{name}[-] voted at 7daystodie-servers.com and was rewarded Takaro Coins!\\nLeave it blank if you want nothing to be sent instead.\\n\",\"default\":\"\",\"type\":\"string\"},\"currency\":{\"title\":\"currency\",\"description\":\"How much currency to add to the player in Takaro, if any.\\nMake sure to enable economy for this server.\",\"default\":0,\"type\":\"number\"},\"randomitemnumber\":{\"title\":\"randomitemnumber\",\"description\":\"Defines how many random items will be rewarded to the player, picked from randomitemlist config field.\\nThe quantities for each item picked is defined on the mentioned config field.\",\"default\":0,\"type\":\"number\"},\"randomitemlist\":{\"title\":\"Items\",\"description\":\"List of items that will be used to select a random reward for the vote, as many times as defined at randomitemnumber.\",\"x-component\":\"item\",\"type\":\"array\",\"uniqueItems\":true,\"items\":{\"type\":\"object\",\"title\":\"Item\",\"properties\":{\"item\":{\"type\":\"string\",\"title\":\"Item\"},\"amount\":{\"type\":\"number\",\"title\":\"Amount\"},\"quality\":{\"type\":\"string\",\"title\":\"Quality\"}}}},\"fixedrewards\":{\"title\":\"Items\",\"description\":\"All the items in this list will be given as a reward for the vote.\",\"x-component\":\"item\",\"type\":\"array\",\"uniqueItems\":true,\"items\":{\"type\":\"object\",\"title\":\"Item\",\"properties\":{\"item\":{\"type\":\"string\",\"title\":\"Item\"},\"amount\":{\"type\":\"number\",\"title\":\"Amount\"},\"quality\":{\"type\":\"string\",\"title\":\"Quality\"}}}}}}",
      "uiSchema": "{}",
      "commands": [
        {
          "name": "vote",
          "trigger": "vote",
          "helpText": "Claim rewards for voting for the server",
          "function": "\nimport { takaro, data, axios } from '@takaro/helpers';\nasync function main() {\n  const { } = data;\n\n  const { votingsite, votekey, novote, alreadyclaimed, privatemessage, publicmessage, currency, randomitemnumber, randomitemlist, fixedrewards } = data.module.userConfig;\n  const { steamId } = data.player;\n\n  let actualrandomitemnumber;\n  if (randomitemnumber === 0) {\n    actualrandomitemnumber = 0;\n  } else {\n    actualrandomitemnumber = randomitemnumber > randomitemlist.length ? randomitemlist.length : randomitemnumber;\n  }\n\n  let voteId = `steamid=${steamId}`;\n  if (!steamId)\n    voteId = `username=${data.player.name}`;\n\n  const votingSiteResponse = (await axios.get(`${votingsite}/api/?object=votes&element=claim&key=${votekey}&${voteId}`)).data;\n  // if you wish to test the command without actually voting, comment the line above and uncomment the line bellow, and to the same with lines 27 and 28.\n  // const votingSiteResponse = 1;\n  if (votingSiteResponse == 'Error: server key not found') { await data.player.pm(`The server vote key is invalid, please notify the admins.`); }\n  if (votingSiteResponse == 0) { await data.player.pm(novote); }\n  if (votingSiteResponse == 2) { await data.player.pm(alreadyclaimed); }\n  if (votingSiteResponse == 1) {\n\n    const claimresponse = (await axios.post(`${votingsite}/api/?action=post&object=votes&element=claim&key=${votekey}&${voteId}`)).data;\n    //  const claimresponse = 1\n    if (claimresponse == 1) {\n      if (privatemessage) { await data.player.pm(privatemessage); }\n      if (publicmessage) { await takaro.gameserver.gameServerControllerSendMessage(data.gameServerId, { message: publicmessage.replace('{name}', data.player.name), }); }\n\n      if (actualrandomitemnumber > 0) {\n        for (let i = 0; i < actualrandomitemnumber; i++) {\n          const randomIndex = Math.floor(Math.random() * randomitemlist.length);\n          const randomOption = randomitemlist.splice(randomIndex, 1)[0];\n          if (typeof randomOption === 'string') {\n            console.log(`Giving random item ${i + 1}/${actualrandomitemnumber}:`, randomOption);\n            await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n              name: randomOption,\n              amount: 1,\n              quality: '0',\n            });\n            await data.player.pm(`You received ${randomOption}! (item ${i + 1}/${actualrandomitemnumber + fixedrewards.length})`);\n          }\n          else {\n            const item = (await takaro.item.itemControllerFindOne(randomOption.item)).data.data;\n            console.log(`Giving random item ${i + 1}/${actualrandomitemnumber}:`, item.name);\n            try {\n              await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n                name: item.code,\n                amount: randomOption.amount ?? '1',\n                quality: randomOption.quality ?? '',\n              });\n            } catch (error) {\n              await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n                name: item.code,\n                amount: randomOption.amount ?? '1',\n                quality: '',\n              });\n            }\n\n            await data.player.pm(`You received ${randomOption.amount}x ${item.name}! (item ${i + 1}/${actualrandomitemnumber + fixedrewards.length})`);\n          }\n        }\n      }\n\n      if (fixedrewards.length > 0) {\n        let index = 1;\n        for (const each of fixedrewards) {\n          if (typeof each === 'string') {\n            await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n              name: each,\n              amount: 1,\n              quality: '0',\n            });\n            await data.player.pm(`You received ${each}! (item ${index + actualrandomitemnumber}/${actualrandomitemnumber + fixedrewards.length})`);\n          }\n          else {\n            const item = (await takaro.item.itemControllerFindOne(each.item)).data.data;\n            try {\n              await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n                name: item.code,\n                amount: each.amount ?? 1,\n                quality: each.quality ?? '',\n              });\n            } catch (error) {\n              await takaro.gameserver.gameServerControllerGiveItem(data.gameServerId, data.player.id, {\n                name: item.code,\n                amount: each.amount ?? 1,\n                quality: '',\n              });\n            }\n\n\n            await data.player.pm(`You received ${each.amount}x ${item.name}! (item ${index + actualrandomitemnumber}/${actualrandomitemnumber + fixedrewards.length})`);\n          }\n          index++;\n        }\n      }\n\n      if (currency > 0) {\n        const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', data.gameServerId)).data.data;\n        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(data.gameServerId, data.player.id, { currency: currency, });\n        await data.player.pm(`You received ${currency} ${currencyName.value}.`);\n      }\n\n    } else {\n      await data.player.pm(`Something went wrong while claiming your vote reward.`);\n      console.log(votingSiteResponse);\n    }\n  }\n\n\n}\n\nawait main();\n",
          "arguments": []
        }
      ],
      "hooks": [],
      "cronJobs": [],
      "functions": [],
      "permissions": []
    }
  ]
}