2016-05-26 09:52:01 +00:00
|
|
|
#!/usr/bin/env python3.5
|
2016-04-25 16:13:16 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2017-01-25 17:11:39 +00:00
|
|
|
import datetime
|
2017-01-31 13:47:56 +00:00
|
|
|
import pickle # Per salvare la partita su file.
|
2016-12-09 17:43:14 +00:00
|
|
|
import math
|
2017-07-04 22:40:23 +00:00
|
|
|
import time
|
2016-12-09 17:43:14 +00:00
|
|
|
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
|
2017-07-17 23:13:38 +00:00
|
|
|
from telegram import ParseMode, InlineKeyboardButton, InlineKeyboardMarkup, Bot
|
2017-07-13 14:16:38 +00:00
|
|
|
from telegram.error import Unauthorized, TimedOut, RetryAfter
|
2016-04-21 16:57:23 +00:00
|
|
|
import filemanager
|
2016-04-25 17:39:57 +00:00
|
|
|
import random
|
2016-05-25 11:57:15 +00:00
|
|
|
import strings as s
|
2016-08-10 14:05:30 +00:00
|
|
|
import logging
|
2017-07-10 16:51:04 +00:00
|
|
|
from roles.roles import *
|
2016-08-10 14:05:30 +00:00
|
|
|
|
2016-12-05 18:34:01 +00:00
|
|
|
logging.basicConfig(level=logging.WARNING,
|
2016-08-10 14:05:30 +00:00
|
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
2016-04-21 20:14:35 +00:00
|
|
|
|
2016-04-21 16:57:23 +00:00
|
|
|
token = filemanager.readfile('telegramapi.txt')
|
|
|
|
updater = Updater(token)
|
|
|
|
|
2016-05-26 09:04:16 +00:00
|
|
|
freenames = s.names_list.copy()
|
2016-04-21 16:57:23 +00:00
|
|
|
|
2016-05-27 22:13:34 +00:00
|
|
|
|
2016-04-21 18:20:26 +00:00
|
|
|
class Player:
|
2016-05-27 11:42:25 +00:00
|
|
|
"""Classe di un giocatore. Contiene tutti i dati riguardanti un giocatore all'interno di una partita, come il ruolo,
|
2016-08-09 11:51:56 +00:00
|
|
|
e i dati riguardanti telegram, come ID e username."""
|
2017-07-17 22:57:51 +00:00
|
|
|
def __init__(self, game: Game, tid: int, tusername: str, dummy=False):
|
2016-05-25 09:52:53 +00:00
|
|
|
self.tid = tid # ID di Telegram
|
|
|
|
self.tusername = tusername # Username di Telegram
|
2016-12-05 18:07:18 +00:00
|
|
|
self.role = Role(self) # Di base, ogni giocatore è un ruolo indefinito
|
2017-02-02 13:07:48 +00:00
|
|
|
self.alive = True # Il giocatore è vivo?
|
2016-05-22 15:13:26 +00:00
|
|
|
self.votingfor = None # Diventa un player se ha votato
|
2016-05-25 09:52:53 +00:00
|
|
|
self.votes = 0 # Voti che sta ricevendo questo giocatore. Aggiornato da updatevotes()
|
2017-02-02 13:07:48 +00:00
|
|
|
self.protectedby = None # Protettore. Oggetto player che protegge questo giocatore dalla mifia. Se è None, la mifia può uccidere questo giocatore
|
2016-05-26 13:12:49 +00:00
|
|
|
self.mifiavotes = 0 # Voti che sta ricevendo questo giocatore dalla mifia. Aggiornato da updatemifiavotes()
|
2017-02-02 13:07:48 +00:00
|
|
|
self.dummy = dummy # E' un bot? Usato solo per il debug (/debugjoin)
|
2017-07-17 22:57:51 +00:00
|
|
|
self.game = game # La partita associata al giocatore
|
2016-04-21 18:20:26 +00:00
|
|
|
|
2016-05-27 09:46:54 +00:00
|
|
|
def __repr__(self) -> str:
|
2017-07-04 22:40:23 +00:00
|
|
|
return "<Player {username}>".format(username=self.tusername)
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return "@{}".format(self.tusername)
|
2016-05-26 09:04:16 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def message(self, bot: Bot, text: str):
|
2016-05-26 09:04:16 +00:00
|
|
|
"""Manda un messaggio privato al giocatore."""
|
2016-12-09 16:52:15 +00:00
|
|
|
if not self.dummy:
|
2017-07-08 12:31:37 +00:00
|
|
|
bot.sendMessage(self.tid, text, parse_mode=ParseMode.MARKDOWN)
|
2016-05-26 09:04:16 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def kill(self, bot: Bot):
|
2016-05-26 09:04:16 +00:00
|
|
|
"""Uccidi il giocatore."""
|
2017-07-17 23:06:30 +00:00
|
|
|
self.role.ondeath(bot)
|
2016-05-26 09:04:16 +00:00
|
|
|
self.alive = False
|
2016-05-25 09:52:53 +00:00
|
|
|
|
2016-05-27 22:13:34 +00:00
|
|
|
|
2016-04-21 18:20:26 +00:00
|
|
|
class Game:
|
2016-12-11 15:31:44 +00:00
|
|
|
"""Classe di una partita, contenente parametri riguardanti stato della partita
|
2016-05-27 11:42:25 +00:00
|
|
|
e informazioni sul gruppo di Telegram."""
|
2017-07-17 23:13:38 +00:00
|
|
|
def __init__(self, groupid: int):
|
2016-05-25 09:52:53 +00:00
|
|
|
self.groupid = groupid # ID del gruppo in cui si sta svolgendo una partita
|
2016-12-04 18:54:33 +00:00
|
|
|
self.admin = None # ID telegram dell'utente che ha creato la partita con /newgame
|
2016-05-25 09:52:53 +00:00
|
|
|
self.players = list() # Lista dei giocatori in partita
|
2016-05-22 15:13:26 +00:00
|
|
|
self.tokill = list() # Giocatori che verranno uccisi all'endday
|
2016-12-09 17:43:14 +00:00
|
|
|
self.phase = 'Join' # Fase di gioco: 'Join', 'Preset', 'Config', 'Voting'
|
2016-12-09 16:36:43 +00:00
|
|
|
self.day = 0 # Numero del giorno. 0 se la partita deve ancora iniziare
|
2016-05-26 11:42:50 +00:00
|
|
|
|
|
|
|
self.configstep = 0 # Passo attuale di configurazione
|
2016-08-10 12:55:58 +00:00
|
|
|
self.roleconfig = dict() # Dizionario con le quantità di ruoli da aggiungere
|
2016-05-26 13:12:49 +00:00
|
|
|
self.votingmifia = False # Seguire le regole originali della mifia che vota?
|
2016-05-26 11:42:50 +00:00
|
|
|
|
2016-05-26 13:18:03 +00:00
|
|
|
# Liste di ruoli in gioco, per velocizzare gli endday
|
2016-08-10 12:55:58 +00:00
|
|
|
self.playersinrole = dict()
|
|
|
|
for currentrole in rolepriority:
|
|
|
|
self.playersinrole[currentrole.__name__] = list()
|
2016-05-26 13:18:03 +00:00
|
|
|
|
2016-05-26 09:04:16 +00:00
|
|
|
# Trova un nome per la partita
|
|
|
|
if len(freenames) > 0:
|
2016-05-26 09:49:40 +00:00
|
|
|
random.shuffle(freenames)
|
2016-05-26 09:08:50 +00:00
|
|
|
self.name = freenames.pop()
|
2016-05-26 09:04:16 +00:00
|
|
|
else:
|
2016-05-26 09:08:50 +00:00
|
|
|
self.name = str(groupid)
|
2016-05-26 09:04:16 +00:00
|
|
|
|
2016-08-10 15:02:30 +00:00
|
|
|
self.lastlynch = None # Ultima persona uccisa dai Royal, diventa un player
|
|
|
|
|
2016-05-26 09:04:16 +00:00
|
|
|
def __del__(self):
|
2016-05-26 09:08:50 +00:00
|
|
|
# Rimetti il nome che si è liberato in disponibili.
|
|
|
|
try:
|
|
|
|
int(self.name)
|
2016-05-26 09:10:52 +00:00
|
|
|
except ValueError:
|
2016-05-26 09:08:50 +00:00
|
|
|
freenames.append(self.name)
|
2017-07-17 22:57:51 +00:00
|
|
|
for player in self.players:
|
|
|
|
player.game = None
|
2016-05-26 09:04:16 +00:00
|
|
|
|
2016-05-26 09:08:50 +00:00
|
|
|
def __repr__(self):
|
2016-05-27 11:42:25 +00:00
|
|
|
r = "<Game {name} in group {groupid} with {nplayers} players in phase {phase}>" \
|
|
|
|
.format(name=self.name, groupid=self.groupid, nplayers=len(self.players), phase=self.phase)
|
2016-05-26 09:08:50 +00:00
|
|
|
return r
|
2016-04-21 18:20:26 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def message(self, bot: Bot, text: str):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Manda un messaggio nel gruppo."""
|
2016-05-26 13:25:54 +00:00
|
|
|
bot.sendMessage(self.groupid, text, parse_mode=ParseMode.MARKDOWN)
|
2016-04-21 18:20:26 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def adminmessage(self, bot: Bot, text: str):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Manda un messaggio privato al creatore della partita."""
|
2016-12-04 18:54:33 +00:00
|
|
|
self.admin.message(bot, text)
|
2016-04-21 18:20:26 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def mifiamessage(self, bot: Bot, text: str):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Manda un messaggio privato a tutti i Mifiosi nella partita."""
|
2016-04-21 18:20:26 +00:00
|
|
|
# Trova tutti i mifiosi nell'elenco dei giocatori
|
|
|
|
for player in self.players:
|
|
|
|
if isinstance(player.role, Mifioso):
|
|
|
|
player.message(bot, text)
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def findplayerbyid(self, tid: int):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Trova il giocatore con un certo id."""
|
2016-04-22 17:21:50 +00:00
|
|
|
for player in self.players:
|
|
|
|
if player.tid == tid:
|
|
|
|
return player
|
2017-07-17 23:13:38 +00:00
|
|
|
return None
|
2016-04-22 17:21:50 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def findplayerbyusername(self, tusername: str):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Trova il giocatore con un certo username."""
|
2016-04-22 17:21:50 +00:00
|
|
|
for player in self.players:
|
2017-01-28 23:36:58 +00:00
|
|
|
if player.tusername.lower() == tusername.strip("@").lower():
|
2016-04-22 17:21:50 +00:00
|
|
|
return player
|
2017-07-17 23:13:38 +00:00
|
|
|
return None
|
2016-04-22 17:21:50 +00:00
|
|
|
|
2017-07-17 22:57:51 +00:00
|
|
|
# def updategroupname(self, bot: Bot):
|
2017-07-11 22:19:10 +00:00
|
|
|
# """Cambia il titolo della chat. Per qualche motivo non funziona."""
|
|
|
|
# try:
|
|
|
|
# if self.phase == "Voting":
|
|
|
|
# bot.set_chat_title(self.groupid, s.group_name.format(phase=s.day.format(day=self.day), name=self.name))
|
|
|
|
# else:
|
|
|
|
# bot.set_chat_title(self.groupid, s.group_name.format(phase=self.phase, name=self.name))
|
|
|
|
# except Unauthorized:
|
|
|
|
# print("Bot is not administrator in group {}".format(self.groupid))
|
2017-07-11 22:02:58 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def assignroles(self, bot: Bot):
|
2017-07-08 12:31:37 +00:00
|
|
|
"""Assegna i ruoli specificati ib playersinrole a tutti i giocatori."""
|
2016-04-22 17:55:24 +00:00
|
|
|
random.seed()
|
|
|
|
playersleft = self.players.copy()
|
2017-02-02 13:07:48 +00:00
|
|
|
# Assegna i ruoli secondo i numeri all'interno di playersinrole
|
2016-08-10 12:55:58 +00:00
|
|
|
for currentrole in rolepriority:
|
|
|
|
for player in random.sample(playersleft, self.roleconfig[currentrole.__name__]):
|
|
|
|
self.playersinrole[currentrole.__name__].append(player)
|
2016-12-05 18:33:00 +00:00
|
|
|
player.role = currentrole(player)
|
2016-08-10 12:55:58 +00:00
|
|
|
playersleft.remove(player)
|
2016-04-22 17:55:24 +00:00
|
|
|
# Assegna il ruolo di Royal a tutti gli altri
|
|
|
|
for player in playersleft:
|
2016-12-05 18:07:18 +00:00
|
|
|
player.role = Royal(self)
|
2016-04-23 16:26:32 +00:00
|
|
|
# Manda i ruoli assegnati a tutti
|
|
|
|
for player in self.players:
|
2016-05-25 11:57:15 +00:00
|
|
|
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
|
2016-05-26 09:40:59 +00:00
|
|
|
if player.role.powerdesc is not None:
|
|
|
|
player.message(bot, player.role.powerdesc.format(gamename=self.name))
|
2016-06-01 12:21:51 +00:00
|
|
|
# Manda ai mifiosi l'elenco dei loro compagni di squadra
|
|
|
|
text = s.mifia_team_intro
|
2016-08-10 12:55:58 +00:00
|
|
|
for player in self.playersinrole['Mifioso']:
|
2016-06-01 12:21:51 +00:00
|
|
|
text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername)
|
2017-07-03 16:54:35 +00:00
|
|
|
for player in self.playersinrole['Corrotto']:
|
|
|
|
text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername)
|
2016-08-10 12:55:58 +00:00
|
|
|
for player in self.playersinrole['Mifioso']:
|
2016-06-01 12:21:51 +00:00
|
|
|
player.message(bot, text)
|
2017-07-03 16:54:35 +00:00
|
|
|
for player in self.playersinrole['Corrotto']:
|
|
|
|
player.message(bot, text)
|
2016-06-01 12:21:51 +00:00
|
|
|
|
2016-04-22 19:14:14 +00:00
|
|
|
def updatevotes(self):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Aggiorna il conteggio dei voti di tutti i giocatori."""
|
2016-04-22 19:14:14 +00:00
|
|
|
for player in self.players:
|
|
|
|
player.votes = 0
|
|
|
|
for player in self.players:
|
2016-05-25 14:27:11 +00:00
|
|
|
if player.votingfor is not None and player.alive:
|
2016-04-23 15:37:43 +00:00
|
|
|
player.votingfor.votes += 1
|
2016-04-22 19:14:14 +00:00
|
|
|
|
2016-05-27 08:51:52 +00:00
|
|
|
def updatemifiavotes(self):
|
2016-05-26 13:12:49 +00:00
|
|
|
"""Aggiorna il conteggio dei voti mifiosi di tutti i giocatori."""
|
|
|
|
for player in self.players:
|
|
|
|
player.mifiavotes = 0
|
2016-08-10 12:55:58 +00:00
|
|
|
for player in self.playersinrole['Mifioso']:
|
2016-05-27 11:44:51 +00:00
|
|
|
if player.alive:
|
2016-05-26 13:12:49 +00:00
|
|
|
if player.role.target is not None:
|
|
|
|
player.role.target.mifiavotes += 1
|
|
|
|
|
2016-05-25 14:27:11 +00:00
|
|
|
def mostvotedplayer(self) -> list:
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Trova il giocatore più votato."""
|
2016-05-25 14:27:11 +00:00
|
|
|
mostvoted = list()
|
|
|
|
currenttop = 0
|
2016-04-22 19:14:14 +00:00
|
|
|
self.updatevotes()
|
|
|
|
for player in self.players:
|
2016-05-25 14:27:11 +00:00
|
|
|
if player.votes > currenttop:
|
2016-05-27 09:51:57 +00:00
|
|
|
mostvoted = list()
|
|
|
|
mostvoted.append(player)
|
|
|
|
currenttop = player.votes
|
2016-05-25 14:27:11 +00:00
|
|
|
elif player.votes == currenttop:
|
|
|
|
mostvoted.append(player)
|
2016-05-26 13:12:49 +00:00
|
|
|
if currenttop > 0:
|
|
|
|
return mostvoted
|
|
|
|
else:
|
2016-05-27 08:51:52 +00:00
|
|
|
return list()
|
2016-05-26 13:12:49 +00:00
|
|
|
|
|
|
|
def mostvotedmifia(self) -> list:
|
|
|
|
"""Trova il giocatore più votato dalla mifia."""
|
|
|
|
mostvoted = list()
|
|
|
|
currenttop = 0
|
2016-05-27 08:51:52 +00:00
|
|
|
self.updatemifiavotes()
|
2016-05-26 13:12:49 +00:00
|
|
|
for player in self.players:
|
2016-05-27 09:51:57 +00:00
|
|
|
if player.mifiavotes > currenttop:
|
|
|
|
mostvoted = list()
|
|
|
|
mostvoted.append(player)
|
2016-08-09 11:51:56 +00:00
|
|
|
currenttop = player.mifiavotes
|
2016-05-27 09:51:57 +00:00
|
|
|
elif player.votes == currenttop:
|
2016-05-26 13:12:49 +00:00
|
|
|
mostvoted.append(player)
|
|
|
|
if currenttop > 0:
|
|
|
|
return mostvoted
|
|
|
|
else:
|
2016-05-27 08:51:52 +00:00
|
|
|
return list()
|
2016-05-26 13:12:49 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def endday(self, bot: Bot):
|
2016-05-25 14:27:11 +00:00
|
|
|
"""Finisci la giornata, uccidi il più votato del giorno ed esegui gli endday di tutti i giocatori."""
|
2017-01-25 17:11:39 +00:00
|
|
|
# SALVA LA PARTITA, così se crasha si riprende da qui
|
2017-01-28 23:36:58 +00:00
|
|
|
self.save(bot)
|
2016-05-25 14:27:11 +00:00
|
|
|
# Conta i voti ed elimina il più votato.
|
|
|
|
topvotes = self.mostvotedplayer()
|
|
|
|
if len(topvotes) > 0:
|
|
|
|
# In caso di pareggio, elimina un giocatore casuale.
|
|
|
|
random.seed()
|
|
|
|
random.shuffle(topvotes)
|
|
|
|
lynched = topvotes.pop()
|
2016-05-26 09:59:58 +00:00
|
|
|
if lynched.alive:
|
2016-05-27 11:42:25 +00:00
|
|
|
self.message(bot, s.player_lynched.format(name=lynched.tusername,
|
|
|
|
icon=lynched.role.icon,
|
|
|
|
role=lynched.role.name))
|
2016-08-10 15:02:30 +00:00
|
|
|
self.lastlynch = lynched
|
2016-08-09 11:51:56 +00:00
|
|
|
lynched.kill(bot, self)
|
2016-12-09 16:52:15 +00:00
|
|
|
elif self.day > 1:
|
2016-05-25 14:27:11 +00:00
|
|
|
self.message(bot, s.no_players_lynched)
|
2016-05-03 10:43:00 +00:00
|
|
|
# Fai gli endday in un certo ordine.
|
|
|
|
# Si potrebbe fare più velocemente, credo.
|
2016-05-25 14:27:11 +00:00
|
|
|
# Ma non sto ho voglia di ottimizzare ora.
|
2017-02-02 13:07:48 +00:00
|
|
|
# Endday dei mifiosi se votingmifia è attivo
|
2016-05-26 13:12:49 +00:00
|
|
|
if self.votingmifia:
|
|
|
|
# Trova il più votato dai mifiosi e uccidilo
|
2016-05-27 09:16:02 +00:00
|
|
|
killlist = self.mostvotedmifia()
|
2016-05-26 13:12:49 +00:00
|
|
|
if len(killlist) > 0:
|
|
|
|
# In caso di pareggio, elimina un giocatore casuale.
|
|
|
|
random.seed()
|
|
|
|
random.shuffle(killlist)
|
|
|
|
killed = killlist.pop()
|
|
|
|
if killed.alive:
|
2016-05-27 22:40:30 +00:00
|
|
|
if killed.protectedby is None:
|
2017-07-13 17:36:37 +00:00
|
|
|
killed.kill(bot, self)
|
|
|
|
self.message(bot, s.mifia_target_killed.format(target=killed.tusername,
|
|
|
|
icon=killed.role.icon,
|
|
|
|
role=killed.role.name))
|
2016-05-27 22:40:30 +00:00
|
|
|
else:
|
|
|
|
self.message(bot, s.mifia_target_protected.format(target=killed.tusername,
|
|
|
|
icon=killed.protectedby.role.icon,
|
|
|
|
protectedby=killed.protectedby.tusername))
|
2017-07-17 23:06:30 +00:00
|
|
|
# Attiva gli \
|
2016-08-10 12:55:58 +00:00
|
|
|
for currentrole in rolepriority:
|
|
|
|
for player in self.playersinrole[currentrole.__name__]:
|
|
|
|
if player.alive:
|
2017-07-17 23:06:30 +00:00
|
|
|
player.role.onendday(bot)
|
2016-05-26 13:18:03 +00:00
|
|
|
# Cancella tutti i voti
|
2016-04-23 15:37:43 +00:00
|
|
|
for player in self.players:
|
|
|
|
player.votingfor = None
|
2017-02-02 13:07:48 +00:00
|
|
|
# Incrementa il giorno
|
2016-12-09 16:36:43 +00:00
|
|
|
self.day += 1
|
2017-02-03 22:29:39 +00:00
|
|
|
# Notifica dell'inizi
|
|
|
|
self.message(bot, s.new_day.format(day=self.day))
|
2017-07-07 20:50:28 +00:00
|
|
|
# Controlla se qualcuno ha vinto
|
|
|
|
self.victoryconditions(bot)
|
2016-04-23 16:26:32 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def startpreset(self, bot: Bot):
|
2016-12-09 17:43:14 +00:00
|
|
|
"""Inizio della fase di preset"""
|
|
|
|
self.phase = 'Preset'
|
2017-07-11 22:02:58 +00:00
|
|
|
# Aggiorna il nome del gruppo
|
2017-07-11 22:19:10 +00:00
|
|
|
# self.updategroupname(bot)
|
2017-07-06 17:22:10 +00:00
|
|
|
# Crea la tastiera
|
|
|
|
kbmarkup = InlineKeyboardMarkup([
|
|
|
|
[
|
|
|
|
InlineKeyboardButton(s.preset_simple, callback_data="simple"),
|
2017-07-13 17:36:37 +00:00
|
|
|
InlineKeyboardButton(s.preset_classic, callback_data="classic")
|
2017-07-06 17:22:10 +00:00
|
|
|
],
|
|
|
|
[
|
2017-07-17 22:50:31 +00:00
|
|
|
InlineKeyboardButton(s.preset_oneofall, callback_data="oneofall")
|
2017-07-06 17:22:10 +00:00
|
|
|
]
|
|
|
|
])
|
|
|
|
# Manda la tastiera
|
|
|
|
bot.sendMessage(self.groupid, s.preset_choose, parse_mode=ParseMode.MARKDOWN, reply_markup=kbmarkup)
|
2017-01-29 13:22:00 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def loadpreset(self, bot: Bot, preset: str):
|
2017-01-29 13:22:00 +00:00
|
|
|
"""Fine della fase di preset: carica il preset selezionato o passa a config"""
|
|
|
|
if preset == "simple":
|
2017-02-02 13:07:48 +00:00
|
|
|
# Preset semplice (solo Royal, Mifiosi e Investigatori)
|
2016-12-09 17:43:14 +00:00
|
|
|
self.roleconfig = {
|
2017-01-29 13:22:00 +00:00
|
|
|
"Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori
|
|
|
|
"Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori
|
2017-07-04 22:40:23 +00:00
|
|
|
"Corrotto": 0,
|
2017-01-29 13:22:00 +00:00
|
|
|
"Angelo": 0,
|
|
|
|
"Terrorista": 0,
|
|
|
|
"Derek": 0,
|
|
|
|
"Disastro": 0,
|
|
|
|
"Mamma": 0,
|
|
|
|
"Stagista": 0,
|
|
|
|
"SignoreDelCaos": 0,
|
|
|
|
"Servitore": 0
|
2016-12-09 17:43:14 +00:00
|
|
|
}
|
|
|
|
self.votingmifia = True
|
2017-05-08 10:07:19 +00:00
|
|
|
self.message(bot, s.preset_simple_selected.format(mifioso=self.roleconfig["Mifioso"],
|
|
|
|
investigatore=self.roleconfig["Investigatore"],
|
|
|
|
royal=len(self.players) - self.roleconfig["Mifioso"] - self.roleconfig["Investigatore"]))
|
2016-12-09 17:43:14 +00:00
|
|
|
self.endconfig(bot)
|
|
|
|
elif preset == "classic":
|
2017-02-02 13:07:48 +00:00
|
|
|
# Preset classico (solo Royal, Mifiosi, Investigatori, Angeli e Terroristi)
|
2016-12-09 17:43:14 +00:00
|
|
|
self.roleconfig = {
|
2017-01-29 13:22:00 +00:00
|
|
|
"Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori
|
|
|
|
"Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori
|
2017-07-06 17:21:38 +00:00
|
|
|
"Corrotto": 0,
|
2017-01-29 13:22:00 +00:00
|
|
|
"Angelo": math.floor(len(self.players) / 10) + 1, # 1 Angelo ogni 10 giocatori
|
2017-07-13 13:14:06 +00:00
|
|
|
"Terrorista": 1 if random.randrange(0, 100) >= 50 else 0, # 50% di avere un terrorista
|
2017-01-29 13:22:00 +00:00
|
|
|
"Derek": 0,
|
|
|
|
"Disastro": 0,
|
|
|
|
"Mamma": 0,
|
|
|
|
"Stagista": 0,
|
|
|
|
"SignoreDelCaos": 0,
|
|
|
|
"Servitore": 0
|
2016-12-09 17:43:14 +00:00
|
|
|
}
|
|
|
|
self.votingmifia = True
|
2017-07-13 15:28:00 +00:00
|
|
|
self.message(bot, s.preset_classic_selected.format(mifioso=self.roleconfig["Mifioso"], investigatore=self.roleconfig["Investigatore"], angelo=self.roleconfig["Angelo"], royal=len(self.players) - self.roleconfig["Mifioso"] - self.roleconfig["Investigatore"] - self.roleconfig["Angelo"], royalmenouno=len(self.players) - self.roleconfig["Mifioso"] - self.roleconfig["Investigatore"] - self.roleconfig["Angelo"] - 1))
|
2016-12-09 17:43:14 +00:00
|
|
|
self.endconfig(bot)
|
2017-07-08 12:31:37 +00:00
|
|
|
elif preset == "oneofall":
|
|
|
|
self.roleconfig = {
|
|
|
|
"Mifioso": 1,
|
|
|
|
"Investigatore": 1,
|
|
|
|
"Corrotto": 1,
|
|
|
|
"Angelo": 1,
|
|
|
|
"Terrorista": 1,
|
|
|
|
"Derek": 1,
|
|
|
|
"Disastro": 1,
|
|
|
|
"Mamma": 1,
|
|
|
|
"Stagista": 1,
|
|
|
|
"SignoreDelCaos": 0,
|
|
|
|
"Servitore": 0
|
|
|
|
}
|
|
|
|
unassignedplayers = len(self.players) - 9
|
|
|
|
availableroles = list()
|
|
|
|
while unassignedplayers > 0:
|
|
|
|
if len(availableroles) == 0:
|
|
|
|
availableroles = rolepriority.copy()
|
|
|
|
availableroles.remove(SignoreDelCaos)
|
|
|
|
availableroles.remove(Servitore)
|
|
|
|
random.shuffle(availableroles)
|
|
|
|
self.roleconfig[availableroles.pop().__name__] += 1
|
|
|
|
unassignedplayers -= 1
|
|
|
|
self.votingmifia = False
|
|
|
|
self.message(bot, s.preset_oneofall_selected)
|
2016-12-09 17:43:14 +00:00
|
|
|
self.endconfig(bot)
|
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def endconfig(self, bot: Bot):
|
2016-05-27 13:34:23 +00:00
|
|
|
"""Fine della fase di config, inizio assegnazione ruoli"""
|
2016-08-10 13:09:34 +00:00
|
|
|
# Controlla che ci siano abbastanza giocatori per avviare la partita
|
|
|
|
requiredplayers = 0
|
2016-08-10 13:53:55 +00:00
|
|
|
for selectedrole in self.roleconfig:
|
|
|
|
requiredplayers += self.roleconfig[selectedrole]
|
2016-08-10 13:09:34 +00:00
|
|
|
# Se non ce ne sono abbastanza, torna alla fase di join
|
|
|
|
if requiredplayers > len(self.players):
|
2016-08-10 13:53:55 +00:00
|
|
|
self.message(bot, s.error_not_enough_players)
|
2017-07-11 22:02:58 +00:00
|
|
|
self.phase = "Join"
|
2017-07-11 22:19:10 +00:00
|
|
|
# self.updategroupname(bot)
|
2016-05-27 13:34:23 +00:00
|
|
|
else:
|
2016-08-10 13:09:34 +00:00
|
|
|
self.phase = 'Voting'
|
2017-07-11 22:19:10 +00:00
|
|
|
# self.updategroupname(bot)
|
2016-12-09 16:36:43 +00:00
|
|
|
self.day += 1
|
2017-07-13 17:36:37 +00:00
|
|
|
self.players.sort(key=lambda p: p.tusername)
|
2016-08-10 13:09:34 +00:00
|
|
|
self.assignroles(bot)
|
2016-05-27 13:39:17 +00:00
|
|
|
self.message(bot, s.roles_assigned_successfully)
|
2016-12-11 15:31:44 +00:00
|
|
|
for player in self.players:
|
2017-07-17 23:06:30 +00:00
|
|
|
player.role.onstartgame(bot)
|
2016-05-27 13:34:23 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def revealallroles(self, bot: Bot):
|
2017-07-07 20:46:58 +00:00
|
|
|
text = s.status_header.format(name=self.name, admin=self.admin.tusername, phase=self.phase)
|
2017-07-04 22:48:33 +00:00
|
|
|
self.updatevotes()
|
|
|
|
# Aggiungi l'elenco dei giocatori
|
|
|
|
for player in self.players:
|
|
|
|
text += s.status_basic_player.format(icon=player.role.icon,
|
|
|
|
name=player.tusername)
|
|
|
|
self.message(bot, text)
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def endgame(self, bot: Bot):
|
2017-07-07 20:46:58 +00:00
|
|
|
self.revealallroles(bot)
|
2017-07-06 17:04:57 +00:00
|
|
|
for player in self.players:
|
|
|
|
# Togli la referenza circolare
|
|
|
|
player.role.player = None
|
2016-04-23 16:26:32 +00:00
|
|
|
inprogress.remove(self)
|
2016-04-22 19:14:14 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def save(self, bot: Bot):
|
2016-05-29 15:12:23 +00:00
|
|
|
# Crea il file.
|
2016-06-03 20:04:37 +00:00
|
|
|
try:
|
|
|
|
file = open(str(self.groupid) + ".p", 'x')
|
|
|
|
except FileExistsError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
file.close()
|
2016-05-29 15:12:23 +00:00
|
|
|
# Scrivi sul file.
|
|
|
|
file = open(str(self.groupid) + ".p", 'wb')
|
|
|
|
pickle.dump(self, file)
|
|
|
|
file.close()
|
2017-01-25 17:11:39 +00:00
|
|
|
# Crea un file uguale ma con un timestamp
|
2017-01-28 23:36:58 +00:00
|
|
|
# Non sono troppo sicuro che il timestamp si faccia così però funziona
|
|
|
|
t = datetime.datetime(2000,1,1,1,1).now()
|
2017-01-25 17:11:39 +00:00
|
|
|
try:
|
|
|
|
file = open("{group}-{yy}-{mm}-{dd}-{hh}-{mi}.p".format(group=str(self.groupid), yy=t.year, mm=t.month, dd=t.day, hh=t.hour, mi=t.minute), 'x')
|
|
|
|
except FileExistsError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
file.close()
|
|
|
|
# Scrivi sul file.
|
|
|
|
file = open("{group}-{yy}-{mm}-{dd}-{hh}-{mi}.p".format(group=str(self.groupid), yy=t.year, mm=t.month, dd=t.day, hh=t.hour, mi=t.minute), 'wb')
|
|
|
|
pickle.dump(self, file)
|
2017-07-13 17:36:37 +00:00
|
|
|
self.adminmessage(bot, s.game_saved.format(name=self.name))
|
2017-01-25 17:11:39 +00:00
|
|
|
file.close()
|
2016-05-29 15:12:23 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def victoryconditions(self, bot: Bot):
|
2017-01-28 22:21:52 +00:00
|
|
|
"""Controlla se qualcuno ha completato le condizioni di vittoria."""
|
2016-08-10 15:42:57 +00:00
|
|
|
good = 0
|
|
|
|
evil = 0
|
2017-01-29 19:18:23 +00:00
|
|
|
alive = 0
|
2016-08-10 15:42:57 +00:00
|
|
|
for player in self.players:
|
2017-01-29 19:18:23 +00:00
|
|
|
if player.alive:
|
|
|
|
if player.role.team == 'Evil':
|
|
|
|
evil += 1
|
|
|
|
elif player.role.team == 'Good':
|
|
|
|
good += 1
|
|
|
|
alive += 1
|
2016-08-10 15:42:57 +00:00
|
|
|
# Distruzione atomica!
|
2017-01-29 19:18:23 +00:00
|
|
|
if alive == 0:
|
2016-08-10 15:42:57 +00:00
|
|
|
self.message(bot, s.end_game_wiped)
|
|
|
|
for player in self.players:
|
|
|
|
player.message(bot, s.end_game_wiped + s.tie)
|
2017-07-04 22:48:33 +00:00
|
|
|
self.revealallroles(bot)
|
2017-07-07 20:46:58 +00:00
|
|
|
self.endgame(bot)
|
2017-01-31 13:28:42 +00:00
|
|
|
# I mifiosi sono più del 50% dei vivi se la mifia è infallibile
|
|
|
|
# o non ci sono più personaggi buoni se la mifia può mancare i colpi
|
2017-07-13 17:36:37 +00:00
|
|
|
elif evil >= (alive - evil) or good == 0:
|
2016-08-10 15:42:57 +00:00
|
|
|
self.message(bot, s.end_mifia_outnumber + s.victory_mifia)
|
|
|
|
for player in self.players:
|
|
|
|
if player.role.team == 'Good':
|
|
|
|
player.message(bot, s.end_mifia_outnumber + s.defeat)
|
|
|
|
elif player.role.team == 'Evil':
|
|
|
|
player.message(bot, s.end_mifia_outnumber + s.victory)
|
2017-01-29 19:18:23 +00:00
|
|
|
elif player.role.team == 'Chaos':
|
|
|
|
player.message(bot, s.end_game_chaos + s.victory)
|
2017-07-07 20:46:58 +00:00
|
|
|
self.endgame(bot)
|
2016-08-10 15:42:57 +00:00
|
|
|
# Male distrutto
|
|
|
|
elif evil == 0:
|
|
|
|
self.message(bot, s.end_mifia_killed + s.victory_royal)
|
|
|
|
for player in self.players:
|
|
|
|
if player.role.team == 'Good':
|
|
|
|
player.message(bot, s.end_mifia_killed + s.victory)
|
|
|
|
elif player.role.team == 'Evil':
|
|
|
|
player.message(bot, s.end_mifia_killed + s.defeat)
|
2017-01-29 19:18:23 +00:00
|
|
|
elif player.role.team == 'Chaos':
|
|
|
|
player.message(bot, s.end_game_chaos + s.victory)
|
2017-07-07 20:46:58 +00:00
|
|
|
self.endgame(bot)
|
2016-08-10 12:55:58 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def changerole(self, bot: Bot, player: Player, newrole):
|
2017-01-28 22:21:52 +00:00
|
|
|
"""Cambia il ruolo di un giocatore, aggiornando tutti i valori"""
|
2017-01-29 13:22:00 +00:00
|
|
|
# Aggiorna le liste dei ruoli
|
2017-01-28 23:36:58 +00:00
|
|
|
if player.role.__class__ != Royal:
|
|
|
|
self.playersinrole[player.role.__class__.__name__].remove(player)
|
2017-01-29 19:18:23 +00:00
|
|
|
if newrole != Royal:
|
2017-01-29 13:22:00 +00:00
|
|
|
self.playersinrole[newrole.__name__].append(player)
|
|
|
|
# Cambia il ruolo al giocatore
|
2017-01-28 22:21:52 +00:00
|
|
|
player.role = newrole(player)
|
2017-01-29 13:22:00 +00:00
|
|
|
# Manda i messaggi del nuovo ruolo
|
|
|
|
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
|
|
|
|
if player.role.powerdesc is not None:
|
|
|
|
player.message(bot, player.role.powerdesc.format(gamename=self.name))
|
2017-07-13 17:36:37 +00:00
|
|
|
# Manda ai mifiosi l'elenco dei loro compagni di squadra
|
|
|
|
text = s.mifia_team_intro
|
|
|
|
for player in self.playersinrole['Mifioso']:
|
|
|
|
text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername)
|
|
|
|
for player in self.playersinrole['Corrotto']:
|
|
|
|
text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername)
|
|
|
|
for player in self.playersinrole['Mifioso']:
|
|
|
|
player.message(bot, text)
|
|
|
|
for player in self.playersinrole['Corrotto']:
|
|
|
|
player.message(bot, text)
|
2017-01-28 22:21:52 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def joinplayer(self, bot: Bot, player: Player, silent=False):
|
2017-07-06 15:55:41 +00:00
|
|
|
self.players.append(player)
|
2017-07-13 14:16:38 +00:00
|
|
|
if not silent:
|
2017-07-13 17:36:37 +00:00
|
|
|
self.message(bot, s.player_joined.format(name=player.tusername, players=len(self.players)))
|
2017-07-06 15:55:41 +00:00
|
|
|
# Se è il primo giocatore ad unirsi, diventa admin
|
2017-07-07 20:19:56 +00:00
|
|
|
if len(self.players) == 1:
|
2017-07-06 15:55:41 +00:00
|
|
|
self.admin = player
|
|
|
|
|
2017-07-07 14:29:44 +00:00
|
|
|
def getrandomrole(self):
|
|
|
|
availableroles = list()
|
2017-07-13 13:40:05 +00:00
|
|
|
for existingrole in self.playersinrole:
|
|
|
|
if len(existingrole) > 0:
|
|
|
|
availableroles.append(existingrole)
|
|
|
|
return globals()[random.sample(availableroles, 1)[0]] # EWWW
|
2017-07-07 14:29:44 +00:00
|
|
|
|
|
|
|
|
2017-01-28 22:21:52 +00:00
|
|
|
|
2016-04-21 20:14:35 +00:00
|
|
|
# Partite in corso
|
|
|
|
inprogress = list()
|
|
|
|
|
2016-04-21 18:20:26 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def findgamebyid(gid: int) -> Game:
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Trova una partita con un certo id."""
|
2016-04-21 21:04:53 +00:00
|
|
|
for game in inprogress:
|
|
|
|
if game.groupid == gid:
|
|
|
|
return game
|
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def findgamebyname(name: str) -> Game:
|
2016-05-26 09:08:50 +00:00
|
|
|
"""Trova una partita con un certo nome."""
|
|
|
|
for game in inprogress:
|
|
|
|
if game.name.lower() == name.lower():
|
2016-05-26 10:10:07 +00:00
|
|
|
return game
|
2016-05-26 09:04:16 +00:00
|
|
|
|
2016-05-27 22:13:34 +00:00
|
|
|
|
2016-04-21 17:52:01 +00:00
|
|
|
# Comandi a cui risponde il bot
|
2017-07-17 23:13:38 +00:00
|
|
|
def ping(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Ping!"""
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.pong, parse_mode=ParseMode.MARKDOWN)
|
2016-04-21 16:57:23 +00:00
|
|
|
|
2016-04-21 20:14:35 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def newgame(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Crea una nuova partita."""
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.chat.type != 'private':
|
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-05-26 09:04:16 +00:00
|
|
|
if game is None:
|
2017-07-07 19:47:37 +00:00
|
|
|
game = Game(update.message.chat.id)
|
2016-05-26 09:04:16 +00:00
|
|
|
inprogress.append(game)
|
2017-07-13 17:36:37 +00:00
|
|
|
game.message(bot, s.new_game.format(name=game.name))
|
2016-12-04 18:54:33 +00:00
|
|
|
join(bot, update)
|
2016-04-25 17:39:57 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_game_in_progress, parse_mode=ParseMode.MARKDOWN)
|
2016-04-21 20:14:35 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_chat_type, parse_mode=ParseMode.MARKDOWN)
|
2016-04-21 21:04:53 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def join(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Unisciti a una partita."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2017-07-06 15:55:41 +00:00
|
|
|
# Nessuna partita in corso
|
|
|
|
if game is None:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2017-07-06 15:55:41 +00:00
|
|
|
return
|
|
|
|
# Fase di join finita
|
|
|
|
if game.phase != 'Join':
|
|
|
|
game.message(bot, s.error_join_phase_ended)
|
|
|
|
return
|
|
|
|
p = game.findplayerbyid(update.message.from_user['id'])
|
|
|
|
# Giocatore già in partita
|
|
|
|
if p is not None:
|
|
|
|
game.message(bot, s.error_player_already_joined)
|
|
|
|
return
|
|
|
|
# Giocatore senza username
|
2017-07-07 20:17:35 +00:00
|
|
|
if update.message.from_user.username is None:
|
2017-07-06 15:55:41 +00:00
|
|
|
game.message(bot, s.error_no_username)
|
|
|
|
return
|
2017-07-17 22:57:51 +00:00
|
|
|
p = Player(game, update.message.from_user.id, update.message.from_user.username)
|
2017-07-06 15:55:41 +00:00
|
|
|
try:
|
2017-07-15 22:25:47 +00:00
|
|
|
p.message(bot, s.you_joined.format(game=game.name, adminname=game.admin.tusername if game.admin is not None else p.tusername))
|
2017-07-06 15:55:41 +00:00
|
|
|
except Unauthorized:
|
|
|
|
# Bot bloccato dall'utente
|
|
|
|
game.message(bot, s.error_chat_unavailable)
|
|
|
|
return
|
|
|
|
# Aggiungi il giocatore alla partita
|
|
|
|
game.joinplayer(bot, p)
|
|
|
|
# Salva
|
|
|
|
game.save(bot)
|
2016-04-22 17:21:50 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def debugjoin(bot: Bot, update):
|
2017-07-13 13:42:13 +00:00
|
|
|
"""Aggiungi dei bot alla partita."""
|
2016-12-09 16:43:44 +00:00
|
|
|
if __debug__:
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2017-07-06 15:55:41 +00:00
|
|
|
if game is None:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2017-07-06 15:55:41 +00:00
|
|
|
return
|
|
|
|
if game.phase != 'Join':
|
|
|
|
game.message(bot, s.error_join_phase_ended)
|
|
|
|
return
|
|
|
|
arg = update.message.text.split(" ")
|
2017-07-13 13:53:40 +00:00
|
|
|
for name in range(1, int(arg[1]) + 1):
|
2017-07-17 22:57:51 +00:00
|
|
|
p = Player(game, int(name), str(name), True)
|
2017-07-13 14:16:38 +00:00
|
|
|
try:
|
|
|
|
game.joinplayer(bot, p, silent=True)
|
|
|
|
except RetryAfter:
|
|
|
|
pass
|
2016-12-09 16:43:44 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def status(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Visualizza lo stato della partita."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-05-26 09:04:16 +00:00
|
|
|
if game is not None:
|
2016-12-09 16:52:15 +00:00
|
|
|
text = str()
|
2016-12-04 18:54:33 +00:00
|
|
|
if __debug__:
|
|
|
|
text += s.debug_mode
|
2017-07-07 14:37:41 +00:00
|
|
|
text += s.status_header.format(name=game.name, admin=game.admin.tusername if game.admin is not None else "-", phase=game.phase)
|
2016-04-23 15:37:43 +00:00
|
|
|
game.updatevotes()
|
2016-04-22 17:21:50 +00:00
|
|
|
# Aggiungi l'elenco dei giocatori
|
|
|
|
for player in game.players:
|
2016-04-23 15:07:09 +00:00
|
|
|
if not player.alive:
|
2016-05-26 09:52:01 +00:00
|
|
|
text += s.status_dead_player.format(name=player.tusername)
|
2016-12-09 16:36:43 +00:00
|
|
|
elif game.day > 1:
|
2016-06-02 15:09:07 +00:00
|
|
|
text += s.status_alive_player.format(icon="\U0001F610",
|
|
|
|
name=player.tusername,
|
|
|
|
votes=str(player.votes))
|
2016-12-09 16:36:43 +00:00
|
|
|
else:
|
|
|
|
text += s.status_basic_player.format(icon="\U0001F610",
|
|
|
|
name=player.tusername)
|
2016-05-26 09:04:16 +00:00
|
|
|
game.message(bot, text)
|
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-04-22 17:21:50 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def endjoin(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Termina la fase di join e inizia quella di votazione."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-06-03 20:54:09 +00:00
|
|
|
if game is not None and game.phase == 'Join':
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.from_user.id == game.admin.tid:
|
2016-12-09 17:50:18 +00:00
|
|
|
game.message(bot, s.join_phase_ended)
|
2016-12-09 17:43:14 +00:00
|
|
|
game.startpreset(bot)
|
2016-05-26 09:08:50 +00:00
|
|
|
else:
|
|
|
|
game.message(bot, s.error_not_admin)
|
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-05-25 11:57:15 +00:00
|
|
|
|
2016-05-27 22:13:34 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def vote(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Vota per uccidere una persona."""
|
2016-12-09 16:36:43 +00:00
|
|
|
# Trova la partita
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-12-09 16:36:43 +00:00
|
|
|
if game is None:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-12-09 16:36:43 +00:00
|
|
|
return
|
|
|
|
elif game.phase is not 'Voting':
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-12-09 16:36:43 +00:00
|
|
|
return
|
|
|
|
elif game.day <= 1:
|
|
|
|
game.message(bot, s.error_no_votes_on_first_day)
|
|
|
|
return
|
2017-01-29 17:57:22 +00:00
|
|
|
# Genera la tastiera
|
|
|
|
table = list()
|
|
|
|
for player in game.players:
|
2017-07-13 17:36:37 +00:00
|
|
|
if not player.alive:
|
|
|
|
continue
|
2017-01-29 17:57:22 +00:00
|
|
|
row = list()
|
2017-07-17 22:46:57 +00:00
|
|
|
row.append(InlineKeyboardButton(s.vote_keyboard_line.format(player=player, votes=player.votes), callback_data=player.tusername))
|
2017-01-29 17:57:22 +00:00
|
|
|
table.append(row)
|
2017-07-17 22:46:57 +00:00
|
|
|
row = list()
|
|
|
|
row.append(InlineKeyboardButton(s.vote_keyboard_nobody, callback_data="-"))
|
|
|
|
table.append(row)
|
2017-01-29 17:57:22 +00:00
|
|
|
keyboard = InlineKeyboardMarkup(table)
|
|
|
|
# Manda la tastiera
|
|
|
|
bot.sendMessage(game.groupid, s.vote_keyboard, parse_mode=ParseMode.MARKDOWN, reply_markup=keyboard)
|
2016-04-21 21:04:53 +00:00
|
|
|
|
2016-04-21 20:14:35 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def endday(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Termina la giornata attuale."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
|
|
|
if game is not None and game.phase is 'Voting' and update.message.from_user.id == game.admin.tid:
|
2016-04-22 19:14:14 +00:00
|
|
|
game.endday(bot)
|
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def power(bot: Bot, update):
|
2016-05-25 09:52:53 +00:00
|
|
|
"""Attiva il potere del tuo ruolo."""
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.chat.type == 'private':
|
2016-04-23 15:07:09 +00:00
|
|
|
cmd = update.message.text.split(' ', 2)
|
2016-05-26 09:04:16 +00:00
|
|
|
game = findgamebyname(cmd[1])
|
|
|
|
# Se non lo trovi con il nome, prova con l'id
|
|
|
|
if game is None:
|
2016-12-24 18:15:29 +00:00
|
|
|
try:
|
|
|
|
game = findgamebyid(int(cmd[1]))
|
|
|
|
except ValueError:
|
|
|
|
pass
|
2016-04-23 15:07:09 +00:00
|
|
|
if game is not None:
|
2017-07-07 19:47:37 +00:00
|
|
|
player = game.findplayerbyid(int(update.message.from_user.id))
|
2016-05-26 09:04:16 +00:00
|
|
|
if player is not None:
|
2016-05-26 09:08:50 +00:00
|
|
|
if player.alive:
|
2017-01-25 17:11:39 +00:00
|
|
|
if len(cmd) > 2:
|
2017-07-17 23:06:30 +00:00
|
|
|
player.role.power(bot, cmd[2])
|
2017-01-25 17:11:39 +00:00
|
|
|
else:
|
|
|
|
player.message(bot, s.error_missing_parameters)
|
2016-05-26 09:08:50 +00:00
|
|
|
else:
|
|
|
|
player.message(bot, s.error_dead)
|
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_not_in_game, parse_mode=ParseMode.MARKDOWN)
|
2016-04-23 15:07:09 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-04-23 15:07:09 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_private_required, parse_mode=ParseMode.MARKDOWN)
|
2016-04-23 15:07:09 +00:00
|
|
|
|
2016-05-27 22:13:34 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def role(bot: Bot, update):
|
2016-05-26 09:08:50 +00:00
|
|
|
"""Visualizza il tuo ruolo."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-05-26 09:04:16 +00:00
|
|
|
if game is not None and game.phase is 'Voting':
|
2017-07-07 19:47:37 +00:00
|
|
|
player = game.findplayerbyid(update.message.from_user.id)
|
2016-05-26 09:04:16 +00:00
|
|
|
if player is not None:
|
2016-05-26 09:08:50 +00:00
|
|
|
if player.alive:
|
2016-06-01 07:19:37 +00:00
|
|
|
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
|
2016-05-26 09:08:50 +00:00
|
|
|
game.message(bot, s.check_private)
|
|
|
|
else:
|
|
|
|
game.message(bot, s.error_dead)
|
2016-05-26 09:04:16 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_not_in_game, parse_mode=ParseMode.MARKDOWN)
|
2016-05-26 09:04:16 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-05-26 09:04:16 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def kill(bot: Bot, update):
|
2016-05-26 09:08:50 +00:00
|
|
|
"""Uccidi un giocatore in partita."""
|
2016-06-01 11:52:00 +00:00
|
|
|
if __debug__:
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-06-01 11:52:00 +00:00
|
|
|
if game is not None and game.phase is 'Voting':
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.from_user.id == game.admin.tid:
|
2016-06-01 11:52:00 +00:00
|
|
|
target = game.findplayerbyusername(update.message.text.split(' ')[1])
|
|
|
|
if target is not None:
|
2016-08-09 11:51:56 +00:00
|
|
|
target.kill(bot, game)
|
|
|
|
game.message(bot, s.admin_killed.format(name=target.tusername,
|
|
|
|
icon=target.role.icon,
|
2016-06-01 11:52:00 +00:00
|
|
|
role=target.role.name))
|
|
|
|
else:
|
|
|
|
game.message(bot, s.error_username)
|
2016-05-26 09:08:50 +00:00
|
|
|
else:
|
2016-06-01 11:52:00 +00:00
|
|
|
game.message(bot, s.error_not_admin)
|
2016-05-26 09:08:50 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-04-25 17:44:40 +00:00
|
|
|
|
2016-05-26 11:42:50 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def delete(bot: Bot, update):
|
2016-06-01 11:39:41 +00:00
|
|
|
"""Elimina una partita in corso."""
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.chat.type == 'private':
|
|
|
|
if update.message.from_user.username == "Steffo":
|
2016-06-01 11:39:41 +00:00
|
|
|
cmd = update.message.text.split(' ', 2)
|
|
|
|
game = findgamebyname(cmd[1])
|
|
|
|
# Se non lo trovi con il nome, prova con l'id
|
|
|
|
if game is None:
|
|
|
|
game = findgamebyid(int(cmd[1]))
|
|
|
|
if game is not None:
|
2016-06-02 15:09:07 +00:00
|
|
|
game.message(bot, s.owner_ended)
|
2017-07-07 20:46:58 +00:00
|
|
|
game.endgame(bot)
|
2016-06-01 11:39:41 +00:00
|
|
|
else:
|
|
|
|
game.message(bot, s.error_no_games_found)
|
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_not_owner, parse_mode=ParseMode.MARKDOWN)
|
2016-06-01 11:39:41 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_chat_type, parse_mode=ParseMode.MARKDOWN)
|
2016-06-01 11:39:41 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def fakerole(bot: Bot, update):
|
2016-05-26 12:55:02 +00:00
|
|
|
"""Manda un finto messaggio di ruolo."""
|
2017-07-07 19:47:37 +00:00
|
|
|
if update.message.chat.type == 'private':
|
2017-07-04 22:40:23 +00:00
|
|
|
roles = rolepriority.copy()
|
|
|
|
roles.append(Royal)
|
|
|
|
for singlerole in roles:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.role_assigned.format(icon=singlerole.icon, name=singlerole.name),
|
2016-12-05 17:56:34 +00:00
|
|
|
parse_mode=ParseMode.MARKDOWN)
|
2016-05-26 12:55:02 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_private_required, parse_mode=ParseMode.MARKDOWN)
|
2016-05-26 12:55:02 +00:00
|
|
|
|
2016-05-29 15:12:23 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def load(bot: Bot, update):
|
2016-05-29 15:12:23 +00:00
|
|
|
"""Carica una partita salvata."""
|
2017-07-07 19:47:37 +00:00
|
|
|
file = open(str(update.message.chat.id) + ".p", "rb")
|
2016-05-29 15:12:23 +00:00
|
|
|
game = pickle.load(file)
|
|
|
|
inprogress.append(game)
|
|
|
|
game.message(bot, s.game_loaded)
|
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def save(bot: Bot, update):
|
2016-05-29 15:12:23 +00:00
|
|
|
"""Salva una partita su file."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-05-29 15:12:23 +00:00
|
|
|
if game is not None:
|
2017-01-28 23:36:58 +00:00
|
|
|
game.save(bot)
|
2016-05-29 15:12:23 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-05-29 15:12:23 +00:00
|
|
|
|
2016-06-01 11:21:50 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def debug(bot: Bot, update):
|
2016-06-01 11:21:50 +00:00
|
|
|
"""Visualizza tutti i ruoli e gli id."""
|
|
|
|
if __debug__:
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2016-06-01 11:21:50 +00:00
|
|
|
if game is not None:
|
2017-07-07 20:47:58 +00:00
|
|
|
game.revealallroles(bot)
|
2017-01-28 23:36:58 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2017-01-28 23:36:58 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def debugchangerole(bot: Bot, update):
|
2017-01-28 23:36:58 +00:00
|
|
|
"""Cambia il ruolo a un giocatore."""
|
|
|
|
if __debug__:
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.message.chat.id)
|
2017-01-28 23:36:58 +00:00
|
|
|
if game is not None:
|
|
|
|
cmd = update.message.text.split(' ', 2)
|
2017-01-29 13:22:00 +00:00
|
|
|
game.changerole(bot, game.findplayerbyusername(cmd[1]), globals()[cmd[2]])
|
2016-06-01 11:21:50 +00:00
|
|
|
else:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
|
2016-06-01 11:21:50 +00:00
|
|
|
|
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def debuggameslist(bot: Bot, update):
|
2016-06-01 11:21:50 +00:00
|
|
|
"""Visualizza l'elenco delle partite in corso."""
|
|
|
|
if __debug__:
|
2017-07-07 19:47:37 +00:00
|
|
|
bot.sendMessage(update.message.from_user.id, repr(inprogress), parse_mode=ParseMode.MARKDOWN)
|
2016-06-01 11:21:50 +00:00
|
|
|
|
2016-08-10 14:03:11 +00:00
|
|
|
|
2017-07-17 23:13:38 +00:00
|
|
|
def inlinekeyboard(bot: Bot, update):
|
2016-12-09 17:43:14 +00:00
|
|
|
"""Seleziona un preset dalla tastiera."""
|
2017-07-07 19:47:37 +00:00
|
|
|
game = findgamebyid(update.callback_query.message.chat.id)
|
2017-07-07 20:58:55 +00:00
|
|
|
if game is None:
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.error_no_games_found, show_alert=True)
|
|
|
|
return
|
|
|
|
if game.phase is 'Preset':
|
|
|
|
if update.callback_query.from_user.id != game.admin.tid:
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.error_not_admin, show_alert=True)
|
|
|
|
return
|
|
|
|
game.loadpreset(bot, update.callback_query.data)
|
2017-07-08 12:31:37 +00:00
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.preset_selected.format(selected=update.callback_query.data))
|
2017-07-07 20:58:55 +00:00
|
|
|
elif game.phase is 'Voting':
|
|
|
|
# Trova il giocatore
|
|
|
|
player = game.findplayerbyid(update.callback_query.from_user.id)
|
|
|
|
if player is None:
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.error_not_in_game, show_alert=True)
|
|
|
|
return
|
|
|
|
if not player.alive:
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.error_dead, show_alert=True)
|
|
|
|
return
|
2017-07-17 22:46:57 +00:00
|
|
|
if update.callback_query.data == "-":
|
|
|
|
# Annulla il voto
|
|
|
|
player.votingfor = None
|
|
|
|
game.message(bot, s.vote_none.format(player=player))
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.vote_none_fp)
|
|
|
|
else:
|
|
|
|
# Cambia il voto
|
|
|
|
target = game.findplayerbyusername(update.callback_query.data)
|
|
|
|
player.votingfor = target
|
|
|
|
game.message(bot, s.vote.format(voting=player.tusername, voted=target.tusername))
|
|
|
|
bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.vote_fp.format(voted=target.tusername))
|
2016-12-09 17:43:14 +00:00
|
|
|
|
|
|
|
|
2016-06-03 20:04:37 +00:00
|
|
|
updater.dispatcher.add_handler(CommandHandler('ping', ping))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('newgame', newgame))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('join', join))
|
2016-12-09 16:43:44 +00:00
|
|
|
updater.dispatcher.add_handler(CommandHandler('debugjoin', debugjoin))
|
2016-06-03 20:04:37 +00:00
|
|
|
updater.dispatcher.add_handler(CommandHandler('endjoin', endjoin))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('vote', vote))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('endday', endday))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('power', power))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('status', status))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('role', role))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('debug', debug))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('debuggameslist', debuggameslist))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('kill', kill))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('fakerole', fakerole))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('save', save))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('load', load))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('delete', delete))
|
2017-01-28 23:36:58 +00:00
|
|
|
updater.dispatcher.add_handler(CommandHandler('debugchangerole', debugchangerole))
|
2017-01-29 17:57:22 +00:00
|
|
|
updater.dispatcher.add_handler(CallbackQueryHandler(inlinekeyboard))
|
2016-04-21 20:14:35 +00:00
|
|
|
updater.start_polling()
|
2016-05-27 09:34:06 +00:00
|
|
|
print("Bot avviato!")
|
|
|
|
if __name__ == "__main__":
|
2017-07-04 22:48:33 +00:00
|
|
|
while True:
|
2017-07-04 22:40:23 +00:00
|
|
|
try:
|
|
|
|
updater.idle()
|
|
|
|
except TimedOut:
|
2017-07-04 22:48:33 +00:00
|
|
|
time.sleep(10)
|