...
This commit is contained in:
11
run.py
11
run.py
@@ -15,8 +15,11 @@ from emojis import *
|
|||||||
from settings import *
|
from settings import *
|
||||||
|
|
||||||
intents = nextcord.Intents.default()
|
intents = nextcord.Intents.default()
|
||||||
|
# noinspection PyDunderSlots,PyUnresolvedReferences
|
||||||
intents.typing = False
|
intents.typing = False
|
||||||
|
# noinspection PyDunderSlots,PyUnresolvedReferences
|
||||||
intents.presences = False
|
intents.presences = False
|
||||||
|
# noinspection PyDunderSlots,PyUnresolvedReferences
|
||||||
intents.message_content = True
|
intents.message_content = True
|
||||||
|
|
||||||
bot = nextcord.Client(intents=intents)
|
bot = nextcord.Client(intents=intents)
|
||||||
@@ -45,6 +48,7 @@ async def on_ready():
|
|||||||
print(f"Écoute pour Spoutnik sur {channel.guild} > {channel.name}")
|
print(f"Écoute pour Spoutnik sur {channel.guild} > {channel.name}")
|
||||||
|
|
||||||
current_date = None
|
current_date = None
|
||||||
|
events_done = []
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(HEARTBEAT)
|
await asyncio.sleep(HEARTBEAT)
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
@@ -63,7 +67,7 @@ async def on_ready():
|
|||||||
await wordle_game.reset()
|
await wordle_game.reset()
|
||||||
elif event[0] == SPOUTNIK:
|
elif event[0] == SPOUTNIK:
|
||||||
for spoutnik_game in spoutnik_games.values():
|
for spoutnik_game in spoutnik_games.values():
|
||||||
await spoutnik_game.reset()
|
await spoutnik_game.reset(preset=SPOUTNIK_PRESETS[event[2]], force=False)
|
||||||
|
|
||||||
|
|
||||||
# Receiving a message
|
# Receiving a message
|
||||||
@@ -104,9 +108,9 @@ async def on_message(message):
|
|||||||
output += f"{spoutnik_game.channel.guild} > {spoutnik_game.channel.name} : {spoutnik_game.target}\n"
|
output += f"{spoutnik_game.channel.guild} > {spoutnik_game.channel.name} : {spoutnik_game.target}\n"
|
||||||
await message.author.send(output)
|
await message.author.send(output)
|
||||||
|
|
||||||
if regex := re.search(r"^[sS]poutnik reset ([0-9]+)$", content_lowercase):
|
if regex := re.search(r"^[sS]poutnik reset ([0-9]+) (.+)$", content_lowercase):
|
||||||
channel_id = int(regex.group(1))
|
channel_id = int(regex.group(1))
|
||||||
await spoutnik_games[channel_id].reset()
|
await spoutnik_games[channel_id].reset(preset=SPOUTNIK_PRESETS[regex.group(2).strip()], force=True)
|
||||||
|
|
||||||
if re.search(r"^[eE]phemeris$", content_lowercase):
|
if re.search(r"^[eE]phemeris$", content_lowercase):
|
||||||
embed = ephemeris.digest()
|
embed = ephemeris.digest()
|
||||||
@@ -244,6 +248,7 @@ async def on_message(message):
|
|||||||
poll = polls.Poll()
|
poll = polls.Poll()
|
||||||
poll.owner = message.author
|
poll.owner = message.author
|
||||||
poll.intro = intro
|
poll.intro = intro
|
||||||
|
letter = None
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if re.fullmatch(bullet, part): # the part is a bullet
|
if re.fullmatch(bullet, part): # the part is a bullet
|
||||||
letter = part[0].lower()
|
letter = part[0].lower()
|
||||||
|
|||||||
31
spoutnik.py
31
spoutnik.py
@@ -43,6 +43,7 @@ class Game:
|
|||||||
def __init__(self, channel):
|
def __init__(self, channel):
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.target = None
|
self.target = None
|
||||||
|
self.preset = None
|
||||||
self.file = f"/tmp/spoutnik_{channel}.jpg"
|
self.file = f"/tmp/spoutnik_{channel}.jpg"
|
||||||
self.winner = None
|
self.winner = None
|
||||||
self.last_player = None
|
self.last_player = None
|
||||||
@@ -50,22 +51,27 @@ class Game:
|
|||||||
self.resetters = set()
|
self.resetters = set()
|
||||||
self.jump_url = None
|
self.jump_url = None
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self, preset, force=False):
|
||||||
|
if not force and not self.winner and self.last_datetime and (datetime.now() - self.last_datetime).total_seconds() < SPOUTNIK_EXPIRY_TIMEOUT:
|
||||||
|
return
|
||||||
|
|
||||||
output = ""
|
output = ""
|
||||||
|
self.preset = preset
|
||||||
|
zoom = self.preset["zoom"]
|
||||||
if self.target and not self.winner:
|
if self.target and not self.winner:
|
||||||
output = f":expressionless: Le lieu précédent était [ici](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{SPOUTNIK_ZOOM}z>).\n\n"
|
output = f":expressionless: Le lieu précédent était [ici](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{zoom}z>).\n\n"
|
||||||
random_lat, random_lon = random_point(SPOUTNIK_FILE)
|
random_lat, random_lon = random_point(self.preset["geojson_file"])
|
||||||
tile_x, tile_y = wgs84_to_tile(random_lat, random_lon, SPOUTNIK_ZOOM)
|
tile_x, tile_y = wgs84_to_tile(random_lat, random_lon, zoom)
|
||||||
req = requests.get(f"https://khms2.google.com/kh/v=1000?x={tile_x}&y={tile_y}&z={SPOUTNIK_ZOOM}")
|
req = requests.get(f"https://khms2.google.com/kh/v=1000?x={tile_x}&y={tile_y}&z={zoom}")
|
||||||
with open(self.file, "wb") as f:
|
with open(self.file, "wb") as f:
|
||||||
f.write(req.content)
|
f.write(req.content)
|
||||||
self.target = tile_to_wgs84(tile_x + 0.5, tile_y + 0.5, SPOUTNIK_ZOOM)
|
self.target = tile_to_wgs84(tile_x + 0.5, tile_y + 0.5, zoom)
|
||||||
self.winner = None
|
self.winner = None
|
||||||
self.last_player = None
|
self.last_player = None
|
||||||
self.last_datetime = None
|
self.last_datetime = None
|
||||||
self.resetters = set()
|
self.resetters = set()
|
||||||
output += f":satellite_orbital: Il y a un nouveau lieu à trouver !"
|
output += f":satellite_orbital: Il y a un nouveau lieu à trouver ! Le terrain de jeu est {self.preset["label"]}."
|
||||||
output += f"\n\nDonnez-moi les coordonnées GPS du centre de l'image, à {SPOUTNIK_MAX_DISTANCE} m près."
|
output += f"\n\nDonnez-moi les coordonnées GPS du centre de l'image, à {self.preset["max_distance"]} m près."
|
||||||
output += f"\n\n*Sur le site Google Maps, clic droit puis clic sur les coordonnées.*"
|
output += f"\n\n*Sur le site Google Maps, clic droit puis clic sur les coordonnées.*"
|
||||||
output += f"\n*Sur l'app Google Maps, appui long puis appui sur les coordonnées.*"
|
output += f"\n*Sur l'app Google Maps, appui long puis appui sur les coordonnées.*"
|
||||||
self.jump_url = (await self.channel.send(output, file=File(self.file))).jump_url
|
self.jump_url = (await self.channel.send(output, file=File(self.file))).jump_url
|
||||||
@@ -80,7 +86,7 @@ class Game:
|
|||||||
self.resetters.add(message.author)
|
self.resetters.add(message.author)
|
||||||
await self.channel.send(f"Réinitialisation : {len(self.resetters)}/{SPOUTNIK_RESETTERS_NEEDED}")
|
await self.channel.send(f"Réinitialisation : {len(self.resetters)}/{SPOUTNIK_RESETTERS_NEEDED}")
|
||||||
if len(self.resetters) >= SPOUTNIK_RESETTERS_NEEDED:
|
if len(self.resetters) >= SPOUTNIK_RESETTERS_NEEDED:
|
||||||
await self.reset()
|
await self.reset(preset=self.preset, force=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
# if somebody has already won, return silently
|
# if somebody has already won, return silently
|
||||||
@@ -114,17 +120,18 @@ class Game:
|
|||||||
|
|
||||||
distance = geodesic((lat, lon), self.target).meters
|
distance = geodesic((lat, lon), self.target).meters
|
||||||
blurred_distance = f"{ceil(distance / 1000)} km" if distance > 1000 else f"{ceil(distance / 100) * 100} m"
|
blurred_distance = f"{ceil(distance / 1000)} km" if distance > 1000 else f"{ceil(distance / 100) * 100} m"
|
||||||
if distance <= SPOUTNIK_MAX_DISTANCE:
|
zoom = self.preset["zoom"]
|
||||||
|
if distance <= self.preset["max_distance"]:
|
||||||
self.winner = message.author
|
self.winner = message.author
|
||||||
self.resetters = set()
|
self.resetters = set()
|
||||||
output = f":trophy: YOUPI ! {message.author.mention} a trouvé le lieu ! :trophy:"
|
output = f":trophy: YOUPI ! {message.author.mention} a trouvé le lieu ! :trophy:"
|
||||||
output += f"\n\n[Lieu exact](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{SPOUTNIK_ZOOM}z>)"
|
output += f"\n\n[Lieu exact](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{zoom}z>)"
|
||||||
await self.channel.send(output)
|
await self.channel.send(output)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
address = clean_address(geolocator.reverse((lat, lon), language="fr").address)
|
address = clean_address(geolocator.reverse((lat, lon), language="fr").address)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
address = "un lieu apparemment invalide"
|
address = "un lieu apparemment invalide"
|
||||||
output = f"{message.author.mention} propose [un point](<https://www.google.ch/maps/@{lat},{lon},{SPOUTNIK_ZOOM}z>) proche de {address}."
|
output = f"{message.author.mention} propose [un point](<https://www.google.ch/maps/@{lat},{lon},{zoom}z>) proche de {address}."
|
||||||
output += f"\n\nC'est pas ça chef, mais tu es à moins de {blurred_distance} de [la cible](<{self.jump_url}>) !"
|
output += f"\n\nC'est pas ça chef, mais tu es à moins de {blurred_distance} de [la cible](<{self.jump_url}>) !"
|
||||||
await self.channel.send(output)
|
await self.channel.send(output)
|
||||||
Reference in New Issue
Block a user