Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- "use strict";
- ///<reference path="node_modules/sinusbot/typings/global.d.ts" />
- registerPlugin({
- name: "Vote Reward",
- engine: ">= 1.0.0",
- version: "1.0.0",
- description: "Group Vote Rewards for TeamSpeakServers.org",
- author: "Multivitamin <david.kartnaller@gmail.com",
- requiredModules: ["http"],
- vars: [{
- name: "key",
- title: "TeamSpeak-Servers API Key",
- type: "string",
- default: ""
- }, {
- name: "sid",
- title: "TeamSpeak-Servers Server ID",
- type: "string",
- default: ""
- }, {
- name: "removeTime",
- title: "remove vote when older than x days (default: 30, -1 to disable removal)",
- type: "number",
- default: 30
- }, {
- name: "rewards",
- title: "Group per vote",
- type: "array",
- vars: [{
- name: "amount",
- title: "Amount of Votes in this month",
- type: "number",
- default: 0
- }, {
- name: "group",
- title: "Group Reward",
- type: "number",
- default: 0
- }]
- }]
- }, (_, config) => {
- const { key, sid, removeTime, rewards } = config;
- let initialized = false;
- const rewardSorted = rewards.sort((g1, g2) => g1.amount - g2.amount).reverse();
- const availableGroups = rewards.map(g => g.group);
- const removeAfter = removeTime > 0 ? removeTime * 24 * 60 * 60 : -1;
- const engine = require("engine");
- const event = require("event");
- const store = require("store");
- const http = require("http");
- const backend = require("backend");
- const helpers = require("helpers");
- const CHECK_INTERVAL = 60 * 1000;
- class Vote {
- /** initializes store */
- init() {
- if (!Array.isArray(this.getVotes()))
- this.setVotes([]);
- }
- /** current store namespace */
- ns(name) {
- return `${this.namespace}${name}`;
- }
- /** retrieves the namespace for vote items */
- get nsVotes() {
- return this.ns("votes");
- }
- /** retrieves all votes from store */
- getVotes() {
- return store.getInstance(this.nsVotes);
- }
- /** saves all vote items back to store */
- setVotes(items) {
- store.setInstance(this.nsVotes, items);
- }
- /** retrieves all votes */
- saveItem(item) {
- this.setVotes(this.getVotes().map(i => i.hash === item.hash ? item : i));
- return this;
- }
- addItem(item) {
- this.setVotes([...this.getVotes(), item]);
- return this;
- }
- /** requests to add an item to the store */
- requestAdd(item) {
- const hash = this.getHash(item);
- if (this.findHash(hash))
- return false;
- if (this.isOld(item))
- return false;
- const newItem = this.createVoteItem(item);
- this.addItem(newItem);
- this.tryMakeClaim(newItem);
- return true;
- }
- /** checks if the item is too old to get added or still be hold in store */
- isOld(item) {
- if (removeAfter === -1)
- return false;
- return item.timestamp < Math.floor(Date.now() / 1000) - removeAfter;
- }
- /** retrieves the hash value of an item */
- getHash(item) {
- return helpers.MD5Sum(`${item.nickname}${item.timestamp}`);
- }
- /** finds an item with a specific hash */
- findHash(hash) {
- return this.getVotes().find((item) => item.hash === hash);
- }
- /** handles a full client check */
- checkClient(client) {
- this.getUnclaimedByNickname(client.nick()).forEach(item => this.tryMakeClaim(item, client));
- this.checkGroups(client);
- }
- /** tries to claim a possible not claimed item */
- tryMakeClaim(item, client) {
- if (!this.isUnclaimed(item))
- return false;
- client = client ? client : this.getClientByItem(item);
- if (!client)
- return false;
- engine.log(`Client ${client.nick()} (${client.uid()}) claims a vote (${item.hash})`);
- this.flagItemClaimed(item, client.uid());
- this.saveItem(item);
- this.checkGroups(client);
- return true;
- }
- /** checks wether an item is unclaimed or not */
- isUnclaimed(item) {
- return item.claimedBy === null;
- }
- /** tries to retrieve the client for which the vote is for */
- getClientByItem(item) {
- return backend.getClientByName(item.nickname);
- }
- /** validates the groups a client has */
- checkGroups(client) {
- const group = this.getGroupFromVoteCount(this.getVotesByClient(client).length);
- if (group === -1)
- return;
- return this.whiteListGroup(client, [group], availableGroups);
- }
- /**
- * adds a set of groups to a client and removes groups he should not be in
- * @param client the client to add/remove groups from
- * @param group the groups a client can have
- * @param whitelisted whitelisted groups
- */
- whiteListGroup(client, groups, whitelisted) {
- let assign = groups.map(g => String(g));
- const remove = whitelisted.map(w => String(w)).filter(w => !assign.includes(w));
- client.getServerGroups().forEach(group => {
- if (remove.includes(group.id())) {
- client.removeFromServerGroup(group.id());
- }
- else if (assign.includes(group.id())) {
- assign.splice(assign.indexOf(group.id()), 1);
- }
- });
- assign.forEach(g => client.addToServerGroup(g));
- }
- /**
- * retrieves the servergroup the amount of counts should get
- * @param votes the votecount to check
- */
- getGroupFromVoteCount(votes) {
- let g = rewardSorted.find(g => g.amount <= votes);
- if (!g) {
- if (rewardSorted.length === 0 || rewardSorted[0].amount > votes) {
- g = { amount: -1, group: -1 };
- }
- else {
- g = rewardSorted[rewardSorted.length - 1];
- }
- }
- return g.group;
- }
- /**
- * retrieves the vote items a client has been assigned
- * @param client the client to retrieve
- */
- getVotesByClient(client) {
- return this.getVotes().filter(item => item.claimedBy === client.uid());
- }
- /**
- * gets all unclaimed votes a client nickname can be assigned to
- * @param nick the nickname to check
- */
- getUnclaimedByNickname(nick) {
- return this.getVotes()
- .filter(item => this.isUnclaimed(item))
- .filter(item => item.nickname === nick);
- }
- /**
- * removes all items which are older than the days given in config
- */
- cleanOldItems() {
- const votes = this.getVotes();
- const cleaned = votes.filter(item => !this.isOld(item));
- if (votes.length === cleaned.length)
- return;
- this.setVotes(cleaned);
- }
- /**
- * interval checks
- */
- cron() {
- this.cleanOldItems();
- this.check();
- }
- /**
- * sets an items status to claimed
- * @param item the item which should get claimed
- * @param uid the uid which claimed the item
- */
- flagItemClaimed(item, uid) {
- item.claimedBy = uid;
- item.claimedAt = Date.now();
- return this;
- }
- /**
- * creates a fully valid VoteItem
- * @param item the item which should be upgraded
- */
- createVoteItem(item) {
- return {
- ...item,
- added: Date.now(),
- hash: this.getHash(item),
- claimedBy: null,
- claimedAt: 0
- };
- }
- }
- class TeamSpeakServers extends Vote {
- constructor({ key, sid, createCommand }) {
- super();
- this.namespace = "teamspeakServersDotOrg_";
- this.apikey = key;
- this.sid = sid;
- this.registerCommand(createCommand);
- this.init();
- }
- registerCommand(createCommand) {
- createCommand("vote")
- .help("retrieves the vote link from teamspeak-servers.org")
- .manual("retrieves the vote link for teamspeak-servers.org")
- .manual(`vote daily to get rewarded with servergroups!`)
- .exec((client, _, reply) => {
- reply(`[b][url=https://teamspeak-servers.org/server/${this.sid}/vote/?username=${encodeURI(client.nick())}]VOTE HERE[/url]`);
- reply(`It can take a few minutes until your vote gets counted!`);
- if (removeAfter === -1) {
- reply(`You have have voted ${this.getVotesByClient(client).length} times!`);
- }
- else {
- reply(`You have have voted ${this.getVotesByClient(client).length} times in the last ${removeTime} days!`);
- }
- });
- }
- async check() {
- const votes = await this.fetchVotes();
- votes.forEach(vote => this.requestAdd({
- nickname: vote.nickname,
- timestamp: vote.timestamp
- }));
- }
- fetchVotes() {
- return new Promise((fulfill, reject) => {
- http.simpleRequest({
- method: "GET",
- url: `https://teamspeak-servers.org/api/?object=servers&element=votes&key=${this.apikey}&format=json`
- }, (err, res) => {
- if (err)
- return reject(new Error(`Failed to retrieve data from teamspeak-servers.org api! (Error ${err})`));
- if (res.statusCode !== 200)
- return reject(new Error(`Failed to retrieve data from teamspeak-servers.org api! (Code ${res.statusCode})`));
- try {
- fulfill(JSON.parse(res.data.toString()).votes);
- }
- catch (e) {
- engine.log(`got response from teamspeak-servers.org: ${res.data.toString()}`);
- return reject(e);
- }
- });
- });
- }
- }
- const votings = [];
- function doGlobalCheck() {
- votings.forEach(vote => vote.cron());
- backend.getClients()
- .filter(c => !c.isSelf())
- .forEach(c => votings.forEach(v => v.checkClient(c)));
- }
- event.on("connect", () => {
- if (initialized)
- return;
- initialized = true;
- doGlobalCheck();
- });
- event.on("disconnect", () => {
- initialized = false;
- });
- event.on("clientMove", ({ fromChannel, client }) => {
- if (fromChannel || client.isSelf())
- return;
- votings.forEach(v => v.checkClient(client));
- });
- event.on("clientNick", client => votings.forEach(v => v.checkClient(client)));
- event.on("serverGroupAdded", ev => votings.forEach(v => v.checkClient(ev.client)));
- event.on("serverGroupRemoved", ev => votings.forEach(v => v.checkClient(ev.client)));
- setInterval(() => {
- if (!backend.isConnected())
- return;
- votings.forEach(vote => vote.cron());
- }, CHECK_INTERVAL);
- event.on("load", () => {
- const command = require("command");
- const { createCommand } = command;
- votings.push(new TeamSpeakServers({ key, sid, createCommand }));
- if (backend.isConnected()) {
- initialized = true;
- doGlobalCheck();
- }
- });
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement