work on replays
Co-authored-by: GM <giulio.migani@studenti.unitn.it>
This commit is contained in:
parent
fa983d44dc
commit
7f9e0bd964
@ -1,7 +1,6 @@
|
||||
import os
|
||||
import json
|
||||
import random
|
||||
from tests.dummy_socket import DummySocket
|
||||
from typing import List
|
||||
import eventlet
|
||||
import socketio
|
||||
@ -335,7 +334,7 @@ def chat_message(sid, msg, pl=None):
|
||||
bot.bot_spin()
|
||||
return
|
||||
if '/report' in msg and not ses.game.is_replay:
|
||||
data = "\n".join(ses.game.rpc_log).strip()
|
||||
data = "\n".join(ses.game.rpc_log[:-1]).strip()
|
||||
response = requests.post("http://hastebin.com/documents", data)
|
||||
key = json.loads(response.text).get('key')
|
||||
webhook = DiscordWebhook(url=os.environ['DISCORD_WEBHOOK'], content=f'New bug report, replay at https://hastebin.com/{key}')
|
||||
@ -348,47 +347,13 @@ def chat_message(sid, msg, pl=None):
|
||||
response = requests.get(f"http://hastebin.com/raw/{replay_id}")
|
||||
log = response.text.splitlines()
|
||||
ses.game.spectators.append(ses)
|
||||
ses.game.players = []
|
||||
ses.game.is_replay = True
|
||||
for i in range(len(log)):
|
||||
print('replay:', i, 'of', len(log))
|
||||
cmd = log[i].split(';')
|
||||
if cmd[1] == 'players':
|
||||
ses.game.expansions = json.loads(cmd[4].replace("'",'"'))
|
||||
pnames = json.loads(cmd[3].replace("'",'"'))
|
||||
for p in pnames:
|
||||
ses.game.add_player(Player(p, p, DummySocket(), bot=False))
|
||||
continue
|
||||
if cmd[1] == 'start_game':
|
||||
ses.game.start_game(int(cmd[2]))
|
||||
continue
|
||||
player = [p for p in ses.game.players if p.name == cmd[0]][0]
|
||||
if cmd[1] == 'set_character':
|
||||
player.set_character(cmd[2])
|
||||
if cmd[1] == 'draw':
|
||||
player.draw(cmd[2])
|
||||
if cmd[1] == 'pick':
|
||||
player.pick()
|
||||
if cmd[1] == 'end_turn':
|
||||
player.end_turn()
|
||||
if cmd[1] == 'play_card':
|
||||
data = json.loads(cmd[2])
|
||||
player.play_card(data['index'], data['against'], data['with'])
|
||||
if cmd[1] == 'respond':
|
||||
player.respond(int(cmd[2]))
|
||||
if cmd[1] == 'choose':
|
||||
player.choose(int(cmd[2]))
|
||||
if cmd[1] == 'scrap':
|
||||
player.scrap(int(cmd[2]))
|
||||
if cmd[1] == 'special':
|
||||
player.special(json.loads(cmd[2]))
|
||||
if cmd[1] == 'gold_rush_discard':
|
||||
player.gold_rush_discard()
|
||||
if cmd[1] == 'buy_gold_rush_card':
|
||||
player.buy_gold_rush_card(int(cmd[2]))
|
||||
if cmd[1] == 'chat_message':
|
||||
chat_message(None, cmd[2], player)
|
||||
eventlet.sleep(1)
|
||||
ses.game.replay(log)
|
||||
return
|
||||
if '/replayspeed' in msg:
|
||||
_cmd = msg.split()
|
||||
if len(_cmd) == 2:
|
||||
ses.game.replay_speed = float(cmd[1])
|
||||
return
|
||||
if '/startwithseed' in msg and not ses.game.started:
|
||||
if len(msg.split()) > 1:
|
||||
ses.game.start_game(int(msg.split()[1]))
|
||||
|
@ -13,7 +13,6 @@ import bang.expansions.fistful_of_cards.card_events as ce
|
||||
import bang.expansions.high_noon.card_events as ceh
|
||||
import bang.expansions.gold_rush.shop_cards as grc
|
||||
import bang.expansions.gold_rush.characters as grch
|
||||
|
||||
class Game:
|
||||
def __init__(self, name, sio:socketio):
|
||||
super().__init__()
|
||||
@ -74,6 +73,52 @@ class Game:
|
||||
eventlet.sleep(0.5)
|
||||
self.notify_room()
|
||||
|
||||
def replay(self, log):
|
||||
from tests.dummy_socket import DummySocket
|
||||
self.players = []
|
||||
self.is_hidden = True
|
||||
self.is_replay = True
|
||||
self.replay_speed = 1
|
||||
for i in range(len(log)):
|
||||
print('replay:', i, 'of', len(log))
|
||||
cmd = log[i].split(';')
|
||||
if cmd[1] == 'players':
|
||||
self.expansions = json.loads(cmd[4].replace("'",'"'))
|
||||
pnames = json.loads(cmd[3].replace("'",'"'))
|
||||
for p in pnames:
|
||||
self.add_player(pl.Player(p, p, DummySocket(self.sio), bot=False))
|
||||
continue
|
||||
if cmd[1] == 'start_game':
|
||||
self.start_game(int(cmd[2]))
|
||||
continue
|
||||
player = [p for p in self.players if p.name == cmd[0]][0]
|
||||
if cmd[1] == 'set_character':
|
||||
player.set_character(cmd[2])
|
||||
if cmd[1] == 'draw':
|
||||
player.draw(cmd[2])
|
||||
if cmd[1] == 'pick':
|
||||
player.pick()
|
||||
if cmd[1] == 'end_turn':
|
||||
player.end_turn()
|
||||
if cmd[1] == 'play_card':
|
||||
data = json.loads(cmd[2])
|
||||
player.play_card(data['index'], data['against'], data['with'])
|
||||
if cmd[1] == 'respond':
|
||||
player.respond(int(cmd[2]))
|
||||
if cmd[1] == 'choose':
|
||||
player.choose(int(cmd[2]))
|
||||
if cmd[1] == 'scrap':
|
||||
player.scrap(int(cmd[2]))
|
||||
if cmd[1] == 'special':
|
||||
player.special(json.loads(cmd[2]))
|
||||
if cmd[1] == 'gold_rush_discard':
|
||||
player.gold_rush_discard()
|
||||
if cmd[1] == 'buy_gold_rush_card':
|
||||
player.buy_gold_rush_card(int(cmd[2]))
|
||||
# if cmd[1] == 'chat_message':
|
||||
# chat_message(None, cmd[2], player)
|
||||
eventlet.sleep(self.replay_speed)
|
||||
|
||||
def notify_room(self, sid=None):
|
||||
if len([p for p in self.players if p.character == None]) != 0 or sid:
|
||||
self.sio.emit('room', room=self.name if not sid else sid, data={
|
||||
|
@ -135,7 +135,9 @@ class Player:
|
||||
self.sio.emit('characters', room=self.sid, data=json.dumps(
|
||||
available, default=lambda o: o.__dict__))
|
||||
else:
|
||||
self.set_character(available[randrange(0, len(available))].name)
|
||||
char_name = available[randrange(0, len(available))].name
|
||||
self.game.rpc_log.append(f'{self.name};set_character;{char_name}')
|
||||
self.set_character(char_name)
|
||||
|
||||
def notify_card(self, player, card, message=''):
|
||||
try:
|
||||
@ -233,8 +235,10 @@ class Player:
|
||||
else:
|
||||
return
|
||||
if self.pending_action == PendingAction.PICK:
|
||||
self.game.rpc_log.append(f'{self.name};pick;')
|
||||
self.pick()
|
||||
elif self.pending_action == PendingAction.DRAW:
|
||||
self.game.rpc_log.append(f'{self.name};draw;')
|
||||
self.draw('')
|
||||
elif self.pending_action == PendingAction.PLAY:
|
||||
non_blocked_cards = [card for card in self.hand if (not self.game.check_event(ceh.Manette) or card.suit == self.committed_suit_manette)]
|
||||
@ -253,6 +257,7 @@ class Player:
|
||||
if self.gold_nuggets > 0 and any([c.number <= self.gold_nuggets for c in self.game.deck.shop_cards]):
|
||||
for i in range(len(self.game.deck.shop_cards)):
|
||||
if self.game.deck.shop_cards[i].number <= self.gold_nuggets:
|
||||
self.game.rpc_log.append(f'{self.name};buy_gold_rush_card;{i}')
|
||||
self.buy_gold_rush_card(i)
|
||||
return
|
||||
if len(equippables) > 0 and not self.game.check_event(ce.IlGiudice):
|
||||
@ -305,26 +310,33 @@ class Player:
|
||||
if maxcards == self.lives and len([c for c in self.gold_rush_equipment if isinstance(c, grc.Cinturone)]) > 0:
|
||||
maxcards = 8
|
||||
if len(self.hand) > maxcards:
|
||||
self.game.rpc_log.append(f'{self.name};scrap;{0}')
|
||||
self.scrap(0)
|
||||
else:
|
||||
self.game.rpc_log.append(f'{self.name};end_turn')
|
||||
self.end_turn()
|
||||
elif self.pending_action == PendingAction.RESPOND:
|
||||
did_respond = False
|
||||
for i in range(len(self.hand)):
|
||||
if self.hand[i].can_be_used_now and (self.hand[i].name in self.expected_response or self.character.check(self.game, chd.ElenaFuente)):
|
||||
self.game.rpc_log.append(f'{self.name};respond;{i}')
|
||||
self.respond(i)
|
||||
did_respond = True
|
||||
break
|
||||
for i in range(len(self.equipment)):
|
||||
if not self.game.check_event(ce.Lazo) and self.equipment[i].name in self.expected_response:
|
||||
self.game.rpc_log.append(f'{self.name};respond;{len(self.hand)+i}')
|
||||
self.respond(len(self.hand)+i)
|
||||
did_respond = True
|
||||
break
|
||||
if not did_respond:
|
||||
self.game.rpc_log.append(f'{self.name};respond;{-1}')
|
||||
self.respond(-1)
|
||||
elif self.pending_action == PendingAction.CHOOSE:
|
||||
if not self.target_p:
|
||||
self.choose(randrange(0, len(self.available_cards)))
|
||||
card_index = randrange(0, len(self.available_cards))
|
||||
self.game.rpc_log.append(f'{self.name};choose;{card_index}')
|
||||
self.choose(card_index)
|
||||
else:
|
||||
target = self.game.get_player_named(self.target_p)
|
||||
if len(target.hand)+len(target.equipment) == 0:
|
||||
@ -332,8 +344,11 @@ class Player:
|
||||
self.notify_self()
|
||||
else:
|
||||
try:
|
||||
self.choose(randrange(0, len(target.hand)+len(target.equipment)))
|
||||
card_index = randrange(0, len(target.hand)+len(target.equipment))
|
||||
self.game.rpc_log.append(f'{self.name};choose;{card_index}')
|
||||
self.choose(card_index)
|
||||
except:
|
||||
self.game.rpc_log.append(f'{self.name};choose;{0}')
|
||||
self.choose(0)
|
||||
|
||||
|
||||
@ -577,6 +592,13 @@ class Player:
|
||||
return playable_cards
|
||||
|
||||
def play_card(self, hand_index: int, against=None, _with=None):
|
||||
if self.is_bot:
|
||||
data = {
|
||||
"index": hand_index,
|
||||
"against": against,
|
||||
"with": _with
|
||||
}
|
||||
self.game.rpc_log.append(f'{self.name};play_card;{json.dumps(data)}')
|
||||
print(self.name, 'wants to play card ', hand_index, ' against:', against, ' with:', _with)
|
||||
if not self.is_my_turn or self.pending_action != PendingAction.PLAY or self.game.is_handling_death:
|
||||
print('but cannot')
|
||||
|
@ -1,6 +1,11 @@
|
||||
|
||||
class DummySocket():
|
||||
def __init__(self, sio=None):
|
||||
self.true_sio = sio
|
||||
|
||||
def emit(self, event, data=None, to=None, room=None, skip_sid=None, namespace=None, callback=None, **kwargs):
|
||||
# print(f'event: {event}, data: {data}, to: {to}, room: {room}')
|
||||
if self.true_sio and event == 'chat_message':
|
||||
self.true_sio.emit(event, data, to, room, skip_sid, namespace, callback, **kwargs)
|
||||
return True
|
||||
is_fake = True
|
Loading…
Reference in New Issue
Block a user