-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtelegram_controller.py
More file actions
151 lines (137 loc) · 5.96 KB
/
telegram_controller.py
File metadata and controls
151 lines (137 loc) · 5.96 KB
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
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from settings import TOKEN
from position import Position
from game import Game, GameEnded
from reader import read_field
from player import Player
from random import shuffle, randint
import dill as pickle
from emoji import emojize
from string import ascii_lowercase
import linecache
class TelegramController:
instances = {}
chat_codes = {}
debug = False
add_command = "/go {} <начальная позиция>"
@classmethod
def wait(cls):
cls.updater = Updater(token=TOKEN)
cls.updater.dispatcher.add_handler(CommandHandler('start', cls.create))
cls.updater.dispatcher.add_handler(CommandHandler('go', cls.go))
cls.updater.dispatcher.add_handler(CommandHandler('ready', cls.ready))
cls.updater.dispatcher.add_handler(
MessageHandler([Filters.text], cls.on_message))
if cls.do_pickle:
try:
with open("pickle.bin", "rb") as f:
cls.instances = pickle.load(f)
except FileNotFoundError:
pass
cls.updater.start_polling()
cls.updater.idle()
for instance in cls.instances.values():
if hasattr(instance, 'log_file'):
instance.log_file.close()
@staticmethod
def create(bot, update):
instance = TelegramController(
bot, update.message.chat_id, update.message.text.split()[1])
TelegramController.instances[update.message.chat_id] = instance
instance.start()
@classmethod
def go(cls, bot, update):
try:
_, chat_code, pos = update.message.text.split()
except ValueError:
update.message.reply_text(
"Неверный формат, чтобы присоединиться к игре введите: " + cls.add_command.format('<код игры>')
)
return
pid = update.message.from_user.id
name = update.message.from_user.username
print(chat_code)
print(TelegramController.chat_codes)
if chat_code not in TelegramController.chat_codes:
update.message.reply_text("Нет такой игры")
return
TelegramController.chat_codes[chat_code].add(update, pid, name, pos)
def __init__(self, bot, chat_id, fname):
self.bot = bot
self.field = read_field(fname)
self.chat_id = chat_id
self.players = []
self.game_started = False
self.game = None
def start(self):
rand_id = randint(0, 10000)
word = linecache.getline("word_dict.txt", rand_id)[:-1]
TelegramController.chat_codes[word] = self
self.log_file = open('logs/' + word + '.log', 'w')
size = self.field.fields[0].size
assert size <= len(ascii_lowercase), 'size {} is too big'.format(size)
self.log("Начинается игра!")
self.log("Поле имеет размеры {0}x{0}".format(size))
self.log('Чтобы присоединиться, напишите мне в личку ' + self.add_command.format(word))
self.log("Маленькие английские буквы по горизонтали, число с нуля по вертикали. Например, 'b3'")
self.log("Когда все игроки присоединятся, напишите /ready, чтобы начать игру")
if self.field.description:
self.log(self.field.description)
def add(self, update, pid, name, pos):
try:
x = int(pos[1:])
y = ord(pos[0]) - ord('a')
pos = Position(0, x, y)
if not self.field.is_legal(pos):
raise ValueError
except ValueError:
update.message.reply_text("Недопустимая позиция")
return
player = Player(name, pos, pid)
print(player.name, pos, file=self.log_file)
if self.game_started:
self.game.add_player(player)
else:
self.players.append(player)
update.message.reply_text("Отлично")
self.log("Присоединился игрок {}".format(player))
@staticmethod
def ready(bot, update):
if update.message.chat_id in TelegramController.instances:
self = TelegramController.instances[update.message.chat_id]
self.game_started = True
self.log("Игра началась")
self.log("Пишите 'помощь' в свой ход, чтобы узнать, что делать")
shuffle(self.players)
self.game = Game(self, self.field, self.players, self.debug)
def log(self, message):
print(message, file=self.log_file)
self.bot.sendMessage(chat_id=self.chat_id,
text=emojize(message, use_aliases=True))
def action(self, message):
action = message.text
if not self.game:
return
if message.from_user.id != self.game.player().pid:
return
print('>>>' + action, file=self.log_file)
self.game.action(action)
@classmethod
def on_message(cls, bot, update):
if cls.do_pickle:
with open("pickle.bin", "wb") as f:
pickle.dump(TelegramController.instances, f)
if update.message.chat_id in TelegramController.instances:
TelegramController.instances[update.message.chat_id].bot = bot
try:
TelegramController.instances[
update.message.chat_id].action(update.message)
except GameEnded:
bot = TelegramController.instances[update.message.chat_id]
bot.log_file.close()
del TelegramController.instances[update.message.chat_id]
def __getstate__(self):
return (self.chat_id, self.game)
def __setstate__(self, state):
self.chat_id, self.game = state
self.game.controller = self