Skip to content

Commit

Permalink
It works! Added setup script. Need more work on the usage guide
Browse files Browse the repository at this point in the history
  • Loading branch information
MeLlamoPablo committed Dec 8, 2016
1 parent 5ca7ac0 commit 530ebcb
Show file tree
Hide file tree
Showing 11 changed files with 351 additions and 28 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# ScheduleBot
# ScheduleBot | Dota Edition
> A Discord bot that makes scheduling easy
*Note: you're currently viewing the Dota version. This version support Dota 2 inhouses and it's
configuration is a bit trickier because you need a Steam Bot.
If you're looking for the standard version,
[go here](https://github.com/MeLlamoPablo/schedulebot#schedulebot)*

ScheduleBot is a bot that manages events, such as a practice game with your team, or a league
inhouse, or a tournament match.

## Features

* **Dota inhouses**: the Dota version makes it easy to create inhouses, as you can link an event
to an inhouse. A Dota bot will automatically create a lobby and invite every player who have
confirmed their attendance.
* **Time zone handling**: ScheduleBot manages timezons for you. If there are European and
American people on your team, if an European creates an event, Americans will be able to convert
it to their timezone with the `convert` command.
Expand All @@ -21,12 +29,13 @@ event.

## Local installation

To run ScheduleBot locally, you will need:
To run ScheduleBot Dota Edition locally, you will need:

* [NodeJS](https://nodejs.org/en/download/) 6 or above.
* [PostgreSQL](https://www.postgresql.org/download/).
* You'll need to create an empty database for ScheduleBot.
* [git](https://git-scm.com/downloads), so you can easily clone this repo (optional).
* A second [Steam](http://steamcommunity.com/) account for your bot.

Start by cloning this repo, and then install the dependencies:

Expand All @@ -44,6 +53,7 @@ should at least edit:
`Developer Mode`. After that, right click on your channel, and click `Copy ID`.
* `default_timezone` with the time zone which will be used by the bot.
* `db` with yout postgres database settings.
* `steam.profile_url` with your Steam bot's profile URL.

Now, make sure that your postgres server is running, and run the database setup script:

Expand All @@ -55,7 +65,13 @@ The script will take your database settings from `config.js`, so you can just go
enter. When asked if you want to connect over SSL, unless you have configured your postgres
server to use it, you should say no. Then follow the script's instructions to finish the setup.

After that, you're good to go. You can run your bot with:
After that, you need to configure your Steam credentials:

```sh
$ npm run setup-steam
```

Follow the script's instructions and you're good to go. You can run then your bot with:

```sh
$ npm run bot
Expand Down
12 changes: 6 additions & 6 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {

// The master channel
// The bot will announce the events to this channel. It won't listen to other channels.
master_channel: "195150546057822209",
master_channel: "YOUR_MASTER_CHANNEL",

// Events are considered "happening" for a margin of time, where users can see that the event
// is happening right now. During that time, the event is not considered expired yet.+
Expand Down Expand Up @@ -49,18 +49,18 @@ module.exports = {
disallow_talking: true,

db: {
"user": "postgres",
"password": "1234abcd",
"host": "localhost",
"database": "schedulebot"
"user": "",
"password": "",
"host": "",
"database": ""
},

steam: {
// The name that the Steam bot will take
name: "ScheduleBot",

// The bot's profile URL. It's needed to redirect users to it.
profile_url: "http://steamcommunity.com/profiles/76561198316109487/"
profile_url: "http://steamcommunity.com/profiles/YOUR_BOT_ID/"
},

dota: {
Expand Down
18 changes: 11 additions & 7 deletions lib/commands/admin/get-lobby.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ module.exports = new Clapp.Command({
let lobby = context.dotaHandler.currentLobbyName;
let pass = context.dotaHandler.currentLobbyPassword;

context.msg.author.sendMessage(
"Hello! Here's the information you requested:\n\n" +
if (lobby !== null) {
context.msg.author.sendMessage(
"Hello! Here's the information you requested:\n\n" +

"- **Current lobby name**: `" + lobby + "`\n" +
"- **Current lobby password**: `" + pass + "`"
).then(() => {
fulfill("The information you requested was sent to you in a DM.");
}).catch(reject);
"- **Current lobby name**: `" + lobby + "`\n" +
"- **Current lobby password**: `" + pass + "`"
).then(() => {
fulfill("The information you requested was sent to you in a DM.");
}).catch(reject);
} else {
fulfill("The Dota bot is not in a lobby.");
}
});
}
});
9 changes: 8 additions & 1 deletion lib/commands/general/add-inhouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ module.exports = new Clapp.Command({

inhouseProps.gameMode = argv.flags.gamemode.toLowerCase().replace(" ", "");
inhouseProps.server = argv.flags.server.toLowerCase().replace(" ", "");
inhouseProps.autoBalance = !argv.flags["no-balance"];

db.events.addInhouse(event, inhouseProps).then(() => {

// Kick every user that hasn't linked their Steam from the event
db.confirms.getByEvent(event).then(confirms => {
let people = confirms.map(e => { return e.user });
Expand Down Expand Up @@ -113,6 +113,13 @@ module.exports = new Clapp.Command({
}
}
]
}),
new Clapp.Flag({
name: "no-balance",
desc: "Disable automatic team balance.",
type: "boolean",
default: false,
alias: "n"
})
]
});
2 changes: 1 addition & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let masterChannel, summaryHandler, botAdmins, blacklist = [], verificator, dotaH
steamClient = new Steam.SteamClient(),
steamUser = new Steam.SteamUser(steamClient),
steamFriends = new Steam.SteamFriends(steamClient),
dotaClient = new Dota2.Dota2Client(steamClient, true, true);
dotaClient = new Dota2.Dota2Client(steamClient, false, false);

let generalApp = new Clapp.App({
name: cfg.name,
Expand Down
49 changes: 46 additions & 3 deletions lib/modules/dotahandler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@ class DotaHandler {

constructor(dotaClient) {
this.client = dotaClient;

this.currentLobbyName = null;
this.currentLobbyPassword = null;
this.currentLobbyChatChannel = null;
this.starting = false;
this.enoughPeople = false;

this.client.on("practiceLobbyUpdate", lobby => {
this.currentLobbyChatChannel = "Lobby_" + lobby.lobby_id;

let people = lobby.members.filter(e => {
return e.slot !== 0 && e.slot !== null
// e.team: 0 - Radiant
// 1 - Dire
// 2 - Casters |
// 3 - Coaches |-> Filter out these
// 4 - Unassigned |
return e.team === 0 || e.team === 1
}).length;

if (!this.starting) {
Expand All @@ -32,6 +42,7 @@ class DotaHandler {
this.currentLobbyEvent = inhouseProps.event;
this.currentLobbyName = inhouseProps.event.name;
this.currentLobbyPassword = DotaHandler.generatePassword();
this.autoBalance = inhouseProps.autoBalance;

let server;

Expand Down Expand Up @@ -157,6 +168,11 @@ class DotaHandler {
return new Promise((fulfill, reject) => {
this.starting = true;

if (this.autoBalance) {
this.client.balancedShuffleLobby();
this.sendMessageToLobby("Teams were automatically balanced.");
}

let remainingSeconds = 10;
let self = this;

Expand All @@ -168,7 +184,7 @@ class DotaHandler {
remainingSeconds--;
} else {
self.client.launchPracticeLobby();
self.currentLobbyEvent.setLobbyEnded().then(fulfill).catch(reject);
self.closeLobby().then(fulfill).catch(reject);
}
} else {
self.sendMessageToLobby("Aborting start: someone left.");
Expand All @@ -183,6 +199,16 @@ class DotaHandler {
this.sendMessageToLobby("Game start was forced");
this.starting = true;

try {
if (this.autoBalance) {
this.client.balancedShuffleLobby();
this.sendMessageToLobby("Teams were automatically balanced.");
}
} catch (e) {
console.error(e);
}


let remainingSeconds = 10;
let self = this;

Expand All @@ -193,12 +219,29 @@ class DotaHandler {
remainingSeconds--;
} else {
self.client.launchPracticeLobby();
self.currentLobbyEvent.setLobbyEnded().then(fulfill).catch(reject);
self.closeLobby().then(fulfill).catch(reject);
}
})();
});
}

closeLobby() {
return new Promise((fulfill, reject) => {
// Wait a bit before leaving the lobby, just in case.
setTimeout(() => {
console.log("[DOTA] Closed lobby " + this.currentLobbyName);

this.currentLobbyName = null;
this.currentLobbyPassword = null;
this.currentLobbyChatChannel = null;
this.starting = false;
this.enoughPeople = false;
this.client.leavePracticeLobby();
this.currentLobbyEvent.setLobbyEnded().then(fulfill).catch(reject);
}, 30000);
});
}

static generateStatusMessage(people) {
return "Hello! The game will autostart when 10 people join. (We need " + (10 - people)
+ " more). To force a start, tell an admin to run the command force-lobby-start in" +
Expand Down
9 changes: 6 additions & 3 deletions lib/modules/summaryhandler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class SummaryHandler {
break;
}

inhouseProps.autoBalance = inhouseProps.autoBalance ? "Enabled" : "Disabled";

switch (status) {
case "pending":
summary += "That's " + event.time.fromNow() + ".\n\n";
Expand All @@ -88,8 +90,8 @@ class SummaryHandler {
case "happening":
case "expired":
if (!lobbyEnded) {
summary += "The lobby is up! If you haven't got an invite, run the" +
" command `resend-invite`\n\n";
summary += "The lobby is up! If you haven't got an invite, run" +
" the command `resend-invite`\n\n";
} else {
summary += "The lobby for this event is closed\n\n";
}
Expand All @@ -100,7 +102,8 @@ class SummaryHandler {
summary += "**Lobby details**\n\n" +

"- Game mode: *" + inhouseProps.gameMode + "*\n" +
"- Server: *" + inhouseProps.server + "*\n\n"
"- Server: *" + inhouseProps.server + "*\n" +
"- Automatic team balance: *" + inhouseProps.autoBalance + "*\n\n";
}

summary += "**Will attend** ("
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"scripts": {
"bot": "node ./lib/index.js",
"setup": "node ./setup.js",
"setup-steam": "node ./setup-steam.js",
"prepublish": "gulp nsp",
"postinstall": "node ./postinstall.js"
},
Expand Down
Loading

0 comments on commit 530ebcb

Please sign in to comment.