~xenrox/10man-ts3

e15ff8337c3f2de433c5acf38265cfffc1873448 — Thorben Günther 2 years ago c9ade69
Implement match vote with ban command
1 files changed, 126 insertions(+), 0 deletions(-)

M app.ts
M app.ts => app.ts +126 -0
@@ 6,6 6,7 @@ type Variables = { [key: string]: any };

dotenv.config();

var voter = "";
const teamspeak = new TeamSpeak({
    host: process.env.HOST,
    protocol: QueryProtocol.RAW, //optional


@@ 26,6 27,10 @@ let commands = new Map([
    ["!play", "Go into the queue"],
    ["!cancel", "Cancel you queue"],
    ["!help", "Show this help text"],
    [
        "!ban <MAP>",
        "Ban <MAP> if you are a captain and it is your turn to vote",
    ],
]);

let admin_commands = new Map([


@@ 82,6 87,9 @@ teamspeak.on("textmessage", (ev) => {
        case "!move":
            move_clients_wrapper(clid, teamspeakID, argv[1]);
            break;
        case "!ban":
            ban(clid, teamspeakID, argv[1]);
            break;
    }
});



@@ 95,6 103,18 @@ function message_channel(msg: string) {
    });
}

// wrapper to send msg to a teamspeakID
async function message_id(teamspeakID: string, msg: string) {
    const client = await teamspeak
        .getClientByUid(teamspeakID)
        .then((client) => {
            message(client!.clid, msg);
        })
        .catch(function (e) {
            console.error(e);
        });
}

function get_error(e: unknown): string {
    return JSON.parse(JSON.stringify(e)).response.errors[0].message;
}


@@ 364,6 384,7 @@ async function start_match() {
        const data = await request(mutation);
        message_channel("Started match.");
        move_clients();
        vote_map();
    } catch (e) {
        const error = get_error(e);
        switch (error) {


@@ 525,3 546,108 @@ async function set_elo(clid: string, steamID64: string, elo: string) {
        message(clid, "Elo update failed.");
    }
}

async function vote_map() {
    var voting_side = "";

    // get captains
    const query = gql`
        query {
            getTeams {
                captain1 {
                    teamspeakID
                }
                captain2 {
                    teamspeakID
                }
            }
        }
    `;

    var data = await request(query);
    const captain1 = data.getTeams.captain1.teamspeakID;
    const captain2 = data.getTeams.captain2.teamspeakID;

    while (true) {
        // get voting information
        const mutation = gql`
            mutation {
                vetoMap {
                    status
                    maps
                }
            }
        `;

        var data = await request(mutation);
        var status = data.vetoMap.status;
        const maps = data.vetoMap.maps.join(", ");

        if (status === "DONE") {
            // Forbid votes
            voter = "";
            const msg = maps + " was selected.";
            message_id(captain1, msg);
            message_id(captain2, msg);
            break;
        }
        if (voting_side !== status) {
            voting_side = status;
            const msg =
                "Please ban one of the following maps with !ban: " + maps;

            if (voting_side === "TEAM1") {
                voter = captain1;
                message_id(captain1, msg);
            }

            if (voting_side === "TEAM2") {
                voter = captain2;
                message_id(captain2, msg);
            }
        }

        await sleep(10000);
    }
}

async function ban(clid: string, teamspeakID: string, map: string) {
    if (teamspeakID !== voter) {
        message(clid, "You are not allowed to ban right now");
        return;
    }

    const mutation = gql`
        mutation ($map: String!) {
            vetoMap(map: $map) {
                status
            }
        }
    `;
    const variables = { map: map };

    try {
        const data = await request(mutation, variables);
    } catch (e) {
        const error = get_error(e);
        switch (error) {
            case "no legal vote":
                message(clid, "You have not entered a correct mapname.");
                break;
            case "must be defined":
                message(clid, "Put a mapname after !ban.");
                break;
            default:
                message(
                    clid,
                    "Ban was not successful, please contact an admin."
                );
                console.error(error);
                break;
        }
    }
}

function sleep(ms: number) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}