-
Notifications
You must be signed in to change notification settings - Fork 0
/
TFCmaps.py
176 lines (142 loc) · 5.46 KB
/
TFCmaps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# bot.py
from __future__ import print_function
import os
import random
# import pickle
from discord.ext import commands
from dotenv import load_dotenv
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google.oauth2 import service_account
# from google.auth.transport.requests import Request
# from google.oauth2.credentials import Credentials
# from google.auth.exceptions import RefreshError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly']
# The ID and range of Neon's gsheet of maps and team sizes.
MAPS_SPREADSHEET_ID = '1sXUDGC9XrRqKNbjq-qZeMNIgQDeRXdimEY1PZmXt6cY'
# This range includes the following fields:
# mapname: [name of map]
# style (not used): ctf|adl|r-ctf|1flag-ctf|cp|fun
# team sizes: 2v2 through 10v10 depending on map
# mirvs (not used): recommended mirv class count
MAPS_RANGE_NAME = 'Full List!A3:D'
# Using a Sheets API service account makes things easier.
# Remember to share the spreadsheet with the service account.
secret_file = os.path.join(os.getcwd(), 'SvcAcctCredentials.json')
# Initializing list of maps here
maps = []
def load_maps():
creds = None
# The file SvcAcctCredentials.json stores service account credentials
# The spreadsheet must be shared with this service account
if os.path.exists('SvcAcctCredentials.json'):
creds = service_account.Credentials.from_service_account_file(secret_file, scopes=SCOPES)
# If service account isn't set up, try prompting the user to log in
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# # Save the credentials for the next run - N/A with service account
# https://developers.google.com/sheets/api/quickstart/python
# with open('token.json', 'w') as token:
# token.write(creds.to_json())
# Pull the maps
try:
service = build('sheets', 'v4', credentials=creds)
# Call the Sheets API and get the sheet range contents
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=MAPS_SPREADSHEET_ID,
range=MAPS_RANGE_NAME).execute()
values = result.get('values', [])
# If it's empty say so
if not values:
print('No data found.')
return
except HttpError as err:
print(err)
return values
def filter_maps(players='2'):
maps_filtered = [] # Initialize empty list
# Check playercount so we can get the right maps
match players:
case '3':
playercount = '3v3'
case '4':
playercount = '4v4'
case '5':
playercount = '5v5'
case '6':
playercount = '6v6'
case '7':
playercount = '7v7'
case '8':
playercount = '8v8'
case '9':
playercount = '9v9'
case '10':
playercount = '10v10'
case _:
playercount = '2v2'
# Pull map names from column A (0) based on team sizes in column C (2)
try:
for row in maps:
if playercount in row[2]:
maps_filtered.append(row[0])
except HttpError as err:
print(err)
return maps_filtered
# DISCORD BOT STUFF
# Bot expects !commands
bot = commands.Bot(command_prefix='!')
# TODO: track how many players have done !add and give hints about next steps (!maps2 or add more or !maps3 etc)
# TODO: automatically newmaps
# TODO: some kind of vote tracking/closure system?
@bot.command(name='test', help='Debugging/helper command because Nomad is kind of dumb.')
async def test_stuff(ctx):
response = ('testing')
message = await ctx.send(response)
@bot.command(name='maps', help='Returns 3 random maps from neon\'s spreadsheet, use !maps 3 for 3v3, !maps 4 for 4v4 etc.')
async def choose_maps(ctx, players='2'):
# Filter the maplist based on player count
maplistsheets = filter_maps(players)
# Get 3 at random
# TODO: make this less than fully random? remember previous pick(s)?
mapstochoose = [random.sample(maplistsheets,3)]
print(mapstochoose)
# Format response and offer a new maps option
# TODO: update results with names of voters?
# TODO: automatically newmaps at (playercount) total votes?
response = ( '```'
'1 ' + mapstochoose[0][0] + '\n'
'2 ' + mapstochoose[0][1] + '\n'
'3 ' + mapstochoose[0][2] + '\n'
'4 newmaps```'
)
message = await ctx.send(response)
# Add reactions for vote tracking
emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣']
for emoji in emojis:
await message.add_reaction(emoji)
# If something bad happens write it down
@bot.event
async def on_error(event, *args, **kwargs):
with open('err.log', 'a') as f:
if event == 'on_message':
f.write(f'Unhandled message: {args[0]}\n')
else:
raise
# Bot's secret, see ID https://discord.com/developers/docs/topics/oauth2
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
# Populate maplist on launch
maps = load_maps()
# Announce when ready
@bot.event
async def on_ready():
print(f'{bot.user.name} has connected to Discord! Now online in these servers...')
for i in bot.guilds:
print(i)
# Start the bot when this file is running
bot.run(TOKEN)