def __init__(self, gid, gamecls, name, invite_only): g = gamecls() self.game = g self.users = BatchList([ClientPlaceHolder] * g.n_persons) self.game_started = False self.game_name = name self.banlist = defaultdict(set) self.ob_banlist = defaultdict(set) self.gameid = gid self.gamecls = gamecls self.game_items = defaultdict(set) # userid -> {'item:meh', ...} self.game_params = {k: v[0] for k, v in gamecls.params_def.items()} self.is_match = False self.match_users = [] self.invite_only = invite_only self.invite_list = set() self.muted = False g.gameid = gid g._manager = self g.rndseed = random.getrandbits(63) g.random = random.Random(g.rndseed) g.players = BatchList() g.gr_groups = WeakSet()
def testChooseOptionInputlet(self): from game import autoenv from game.autoenv import user_input from client.core import TheChosenOne, PeerPlayer from thb.thb3v3 import THBattle from thb.inputlets import ChooseOptionInputlet from utils import BatchList autoenv.init('Server') g = THBattle() g.IS_DEBUG = True pl = [create_mock_player([]) for i in xrange(6)] p = pl[0] g.me = p p.client.gdlist.extend([ ['I:ChooseOption:1', True], ['I&:ChooseOption:2', False], ['I|:ChooseOption:3', True], ]) p.client.gdevent.set() g.players = BatchList(pl) hook_game(g) g.gr_groups = WeakSet() ilet = ChooseOptionInputlet(self, (False, True)) eq_(user_input([p], ilet), True) eq_(user_input([p], ilet, type='all'), {p: False}) eq_(user_input([p], ilet, type='any'), (p, True)) for p in pl: eq_(p.client.gdhistory, [ ['RI:ChooseOption:1', True], ['RI&:ChooseOption:2', False], ['RI|:ChooseOption:3', True], ]) autoenv.init('Client') g = THBattle() pl = [PeerPlayer() for i in xrange(6)] svr = MockConnection([ ['RI:ChooseOption:1', True], ['RI&:ChooseOption:2', False], ['RI|:ChooseOption:3', True], ]) p = TheChosenOne(svr) pl[0] = p g.me = p svr.gdevent.set() g.players = BatchList(pl) hook_game(g) assert autoenv.Game.getgame() is g ilet = ChooseOptionInputlet(self, (False, True)) eq_(user_input([p], ilet), True) eq_(user_input([p], ilet, type='all'), {p: False}) eq_(user_input([p], ilet, type='any'), (p, True))
def effect_string(act): # for LaunchCard.ui_meta.effect_string source = act.source card = act.card tl = BatchList(act.target_list) cl = BatchList(card.associated_cards) s = u'|G【%s】|r发动了|G变化|r技能,将|G%s|r当作|G%s|r对|G【%s】|r使用。' % ( source.ui_meta.name, u'|r、|G'.join(cl.ui_meta.name), card.treat_as.ui_meta.name, u'】|r、|G【'.join(tl.ui_meta.name), ) return s
def worker(): if msg.startswith('!!') and (options.freeplay or acc.userid in self.admins): self.handle_admin_cmd(user, msg[2:]) return manager = GameManager.get_by_user(user) if manager.muted: user.write(['system_msg', [None, u'当前房间被管理员禁言']]) return packed = (acc.username, msg) if user.state == 'hang': # lobby chat log.info(u'(Lobby): %s' % msg) for u in self.users.values(): if u.state == 'hang': u.write(['chat_msg', packed]) elif user.state in ('inroomwait', 'ready', 'ingame', 'observing'): # room chat log.info(u'(%s): %s' % (user.current_game.gameid, msg)) ul = manager.users obl = BatchList() map(obl.__iadd__, ul.observers) _type = 'ob_msg' if user.state == 'observing' else 'chat_msg' ul.write([_type, packed]) # should be here? obl.write([_type, packed])
def observe_started(self, data): Executive.server.gclear() if self.last_game: self.last_game.kill(ForcedKill) self.last_game.get() self.last_game = None params, tgtid, pldata = data from client.core import PeerPlayer, TheLittleBrother pl = [PeerPlayer.parse(i) for i in pldata] pid = [i.account.userid for i in pl] i = pid.index(tgtid) self.last_game_info = params, i, pldata g = self.game g.players = BatchList(pl) me = g.players[i] me.__class__ = TheLittleBrother me.server = Executive.server g.me = me g.game_params = params # g.start() Starts by UI log.info('=======OBSERVE STARTED=======') log.info(g) @g.link_exception def crash(*a): self.event_cb('game_crashed', g) @g.link_value def finish(*a): v = g.get() if not isinstance(v, ForcedKill): self.event_cb('client_game_finished', g) self.event_cb('game_started', (g, params, pldata, g.players[:]))
def worker(): if msg.startswith('!!') and (options.freeplay or user.account.userid in (2, )): # admin commands cmd = msg[2:] if cmd == 'stacktrace': admin_stacktrace(user.current_game) return elif cmd == 'clearzombies': admin_clearzombies() return elif cmd == 'ping': admin_ping(user) return packed = (user.account.username, msg) if user.state == 'hang': # hall chat for u in users.values(): if u.state == 'hang': u.write(['chat_msg', packed]) elif user.state in ('inroomwait', 'ready', 'ingame', 'observing'): # room chat ul = user.current_game.players.client obl = BatchList() map(obl.__iadd__, ul.observers) _type = 'ob_msg' if user.state == 'observing' else 'chat_msg' ul.write([_type, packed]) # should be here? obl.write([_type, packed])
def apply_action(self): src = self.source tgt = self.target g = Game.getgame() pl = BatchList([tgt, src]) pindian_card = {src: None, tgt: None} with InputTransaction('Pindian', pl) as trans: for p in pl: cards = user_choose_cards(self, p, ('cards', 'showncards'), trans=trans) if cards: card = cards[0] else: card = random_choose_card([p.cards, p.showncards]) pindian_card[p] = card detach_cards([card]) g.emit_event('pindian_card_chosen', (p, card)) g.players.reveal([pindian_card[src], pindian_card[tgt]]) g.emit_event('pindian_card_revealed', self) # for ui. migrate_cards([pindian_card[src], pindian_card[tgt]], g.deck.droppedcards, unwrap=True, is_bh=True) return pindian_card[src].number > pindian_card[tgt].number
def build_initial_players(self): from server.core.game_server import Player, NPCPlayer pl = BatchList([Player(u) for u in self.users]) pl[:0] = [NPCPlayer(NPCClient(i.name), i.input_handler) for i in self.game.npc_players] return pl
def __init__(self, sock, addr): Endpoint.__init__(self, sock, addr) Greenlet.__init__(self) self.observers = BatchList() self.gamedata = Gamedata() self.cmd_listeners = defaultdict(WeakSet) self.current_game = None
def __init__(self, sock, addr): Endpoint.__init__(self, sock, addr) Greenlet.__init__(self) self.observers = BatchList() self.init_gamedata_mixin() self.gdhistory = [] self.usergdhistory = []
def game_started(self, pldata): Executive.server.gclear() if self.last_game: self.last_game.kill(ForcedKill) self.last_game.get() self.last_game = None from client.core import PeerPlayer, TheChosenOne pl = [PeerPlayer.parse(i) for i in pldata] pid = [i.account.userid for i in pl] me = TheChosenOne(Executive.server) me.account = self.account i = pid.index(me.account.userid) pl[i] = me g = self.game g.me = me g.players = BatchList(pl) #g.start() log.info('=======GAME STARTED: %d=======' % g.gameid) log.info(g) @g.link_exception def crash(*a): self.event_cb('game_crashed', g) @g.link_value def finish(*a): v = g.get() if not isinstance(v, ForcedKill): self.event_cb('client_game_finished', g) self.event_cb('game_started', g)
def __init__(self): Greenlet.__init__(self) game.base.Game.__init__(self) self.players = BatchList() self.game_params = {} self.game_items = {} self._my_user_input = (None, None)
class ClientPlaceHolder(object): state = 'left' account = None observers = BatchList() raw_write = write = lambda *a: False def __data__(self): return (None, None, 'left')
def effect_string_before(act): s, tl = act.source, BatchList(act.target_list) c = act.card from gamepack.thb.cards import Skill if isinstance(c, Skill): return c.ui_meta.effect_string(act) elif c: return u'|G【%s】|r对|G【%s】|r使用了|G%s|r。' % ( s.ui_meta.char_name, u'】|r、|G【'.join( tl.ui_meta.char_name), act.card.ui_meta.name)
def __init__(self, target, dmgact): self.source = self.target = target self.dmgact = dmgact g = Game.getgame() if target.dead: log.error('TryRevive buggy condition, __init__') return self.asklist = BatchList( p for p in g.players if not p.dead ).rotate_to(target)
def effect_string(act): # for LaunchCard.ui_meta.effect_string source = act.source tl = BatchList(act.target_list) return u'全人类的绯想天,当然不能只打一个!于是|G【%s】|r选了|G【%s】|r一共%d个目标!' % ( source.ui_meta.name, u'】|r、|G【'.join(tl.ui_meta.name), len(tl), )
def end_game(self): if self.is_match and not self.game.suicide: gevent.spawn(lambda: interconnect.publish( 'speaker', [u'文文', u'“%s”结束了!获胜玩家:%s' % ( self.game_name, u','.join(BatchList(self.game.winners).account.username) )] )) for u in self.users: u.write(['end_game', None]) u.observers and u.observers.write(['end_game', None]) u.state = 'hang'
def effect_string_before(act): s, tl = act.source, BatchList(act.target_list) c = act.card if not c: return meta = getattr(c, 'ui_meta', None) effect_string = getattr(meta, 'effect_string', None) if effect_string: return effect_string(act) return u'|G【%s】|r对|G【%s】|r使用了|G%s|r。' % ( s.ui_meta.name, u'】|r、|G【'.join( tl.ui_meta.name), act.card.ui_meta.name)
def worker(): packed = (user.account.username, msg) if user.state == 'hang': # hall chat for u in users.values(): if u.state == 'hang': u.write(['chat_msg', packed]) elif user.state in ('inroomwait', 'ready', 'ingame', 'observing'): # room chat ul = user.current_game.players.client obl = BatchList() map(obl.__iadd__, ul.observers) _type = 'ob_msg' if user.state == 'observing' else 'chat_msg' ul.write([_type, packed]) # should be here? obl.write([_type, packed])
def __init__(self, sock, addr): Endpoint.__init__(self, sock, addr) Greenlet.__init__(self) self.gdqueue = deque(maxlen=100) self.gdevent = Event() self.observers = BatchList() import socket try: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True) sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 30) sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 6) sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 3) except: pass
def effect_string(act): # for LaunchCard.ui_meta.effect_string source = act.source card = act.card.associated_cards[0] tl = BatchList(act.target_list) if card.is_card(cards.AttackCard): s = u'弹幕掺了金坷垃,攻击范围一千八!' else: s = u'符卡掺了金坷垃,一张能顶两张用!' return u'|G【%s】|r:“%s|G【%s】|r接招吧!”' % ( source.ui_meta.name, s, u'】|r、|G【'.join(tl.ui_meta.name), )
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, SpellCardAction): if act.cancelled: return act # some other thing have done the job if act.non_responsive: return act g = Game.getgame() has_reject = False while g.SERVER_SIDE: from ..characters.baseclasses import Character from ..characters.reimu import SpiritualAttack for p in g.players: if isinstance(p, Character) and p.has_skill(SpiritualAttack): has_reject = True break if has_reject: break from .definition import RejectCard for c in flatten([[p.cards, p.showncards] for p in g.players]): if isinstance(c, RejectCard): has_reject = True break break has_reject = sync_primitive(has_reject, g.players) if not has_reject: return act self.target_act = act pl = BatchList(p for p in g.players if not p.dead) with InputTransaction('AskForRejectAction', pl) as trans: p, rst = ask_for_action(self, pl, ('cards', 'showncards'), [], trans) if not p: return act cards, _ = rst assert cards and self.cond(cards) g.process_action( LaunchCard(p, [act.target], cards[0], Reject(p, act))) return act
def makeGame(self): from game import autoenv from thb.thb3v3 import THBattle from thb.cards import Deck, CardList from thb.characters.eirin import FirstAid, Medic from utils import BatchList autoenv.init('Server') g = THBattle() g.IS_DEBUG = True g.random = random hook_game(g) deck = Deck() g.deck = deck g.action_stack = [autoenv.Action(None, None)] g.gr_groups = WeakSet() pl = [create_mock_player([]) for i in xrange(6)] for p in pl: p.skills = [FirstAid, Medic] p.cards = CardList(p, 'cards') # Cards in hand p.showncards = CardList( p, 'showncard' ) # Cards which are shown to the others, treated as 'Cards in hand' p.equips = CardList(p, 'equips') # Equipments p.fatetell = CardList(p, 'fatetell') # Cards in the Fatetell Zone p.faiths = CardList(p, 'faiths') # Cards in the Fatetell Zone p.special = CardList(p, 'special') # used on special purpose p.showncardlists = [p.showncards, p.fatetell] p.tags = defaultdict(int) p.dead = False p = pl[0] p.client.gdevent.set() g.players = BatchList(pl) return g, p
def user_input_all(self, tag, process, attachment=None, timeout=15): g = Game.getgame() g.emit_event('user_input_all_begin', (self, tag, attachment)) st = g.get_synctag() workers = BatchList() try: def worker(p, i): retry = 0 while True: input = p.user_input( tag, attachment=attachment, timeout=timeout, g=g, st=100000 + st * 1000 + i * 10 + retry, ) try: input = process(p, input) except ValueError: retry += 1 if retry >= 3: input = None break continue g.emit_event('user_input_all_data', (tag, p, input)) break for i, p in enumerate(self): w = gevent.spawn(worker, p, i) w.game = g workers.append(w) workers.join() finally: workers.kill() g.emit_event('user_input_all_end', tag)
def create_game(user, gametype, gamename): from gamepack import gamemodes if not gametype in gamemodes: user.write(['gamehall_error', 'gametype_not_exist']) return g = gamemodes[gametype]() g.game_started = False g.game_name = gamename g.players = BatchList([PlayerPlaceHolder] * g.n_persons) g.players_original = None g.rndseed = random.randint(1, 10**20) g.random = random.Random(g.rndseed) g.banlist = defaultdict(set) g.gr_groups = WeakSet() gid = new_gameid() g.gameid = gid games[gid] = g log.info("create game") evt_datachange.set() return g
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, SpellCardAction): if act.cancelled: return act # some other thing have done the job if isinstance(act, NonResponsiveInstantSpellCardAction): return act g = Game.getgame() has_reject = False while g.SERVER_SIDE: from ..characters.reimu import Reimu for p in g.players: if isinstance(p, Reimu): has_reject = True break if has_reject: break from .definition import RejectCard for c in flatten([[p.cards, p.showncards] for p in g.players]): if isinstance(c, RejectCard): has_reject = True break break has_reject = sync_primitive(has_reject, g.players) if not has_reject: return act self.target_act = act # for ui pl = BatchList(p for p in g.players if not p.dead) p, rst = ask_for_action(self, pl, ['cards', 'showncards'], []) if not p: return act cards, _ = rst assert cards and self.cond(cards) g.process_action(LaunchReject(p, act, cards[0])) return act
def start_replay(self, rep, event_cb): assert self.state == 'initial' self.state = 'replay' from client.core import PeerPlayer, TheLittleBrother from thb import modes g = modes[rep.game_mode]() self.server = ReplayEndpoint(rep, g) pl = [PeerPlayer.parse(i) for i in rep.users] g.players = BatchList(pl) me = g.players[rep.me_index] me.__class__ = TheLittleBrother me.server = self.server g.me = me g.game_params = rep.game_params g.game_items = rep.game_items log.info('=======REPLAY STARTED=======') # g.start() Starts by UI @g.link_exception def crash(*a): self.state = 'initial' event_cb('game_crashed', g) @g.link_value def finish(*a): self.state = 'initial' v = g.get() if not isinstance(v, ForcedKill): event_cb('client_game_finished', g) event_cb('end_game', g) return g
def start_game(g): log.info("game started") g.game_started = True g.players_original = BatchList(g.players) g.usergdhistory = ugh = [] g.gdhistory = [list() for p in g.players] for i, (u, l) in enumerate(zip(g.players.client, g.gdhistory)): u.player_index = i u.usergdhistory = ugh u.gdhistory = l g.start_time = time.time() for u in g.players.client: u.write(["game_started", g.players]) u.gclear() if u.observers: u.observers.gclear() u.observers.write( ['observe_started', [u.account.userid, g.players]]) u.state = 'ingame' evt_datachange.set()
from client.core import game_client game_client.Executive = Executive # Hack GameMode = modes[mode] npcs = len(GameMode.npc_players) players = [PeerPlayer() for i in xrange(GameMode.n_persons + npcs)] players[loc + npcs].__class__ = TheLittleBrother players[loc + npcs].server = server for p in players: p.account = Account.authenticate('Proton', '123') g = GameMode() g.players = BatchList(players) g.game_params = params g.game_items = items g.me = players[loc + npcs] g.replay_file = options.replay_file @hook(g) def pause(*a): pass @hook(g) def get_synctag(ori): tag = ori() if options.print_synctag:
def testBuildChoices(self): import logging from thb.common import build_choices import random from thb.characters.baseclasses import get_characters from thb import characters from game import autoenv # def build_choices(g, items, candidates, players, num, akaris, shared): log = logging.getLogger('test') g = ObjectDict({ 'players': BatchList([ ObjectDict({ 'account': ObjectDict({'userid': i}), 'reveal': lambda o, i=i: log.info('Reveal to %s: %s', i, o), }) for i in xrange(8) ]), 'random': random.Random(12341234), 'SERVER_SIDE': True, 'CLIENT_SIDE': False, }) autoenv.Game.getgame = staticmethod(lambda: g) chars = get_characters('common', '3v3') assert chars choices, imperial = build_choices(g, {}, chars, g.players, 10, 3, True) eq_(len(choices.items()), len(g.players)) eq_(len(set([id(i) for i in choices.values()])), 1) eq_(set(choices.keys()), set(g.players)) eq_(imperial, []) choices, imperial = build_choices( g, {0: ['imperial-choice:SpAya', 'foo']}, chars, g.players, 10, 3, True) eq_(len(choices.items()), len(g.players)) eq_(len(set([id(i) for i in choices.values()])), 1) eq_(set(choices.keys()), set(g.players)) p, c = imperial[0] eq_((p, c.char_cls), (g.players[0], characters.sp_aya.SpAya)) assert c in choices[p] del c eq_(sum([c.akari for c in choices[p]]), 3) choices, imperial = build_choices( g, {0: ['imperial-choice:SpAya', 'foo']}, chars, g.players, [4] * 8, [1] * 8, False) eq_(len(choices.items()), len(g.players)) eq_(len(set([id(i) for i in choices.values()])), 8) eq_(set(choices.keys()), set(g.players)) eq_([len(i) for i in choices.values()], [4] * 8) eq_([len([j for j in i if j.akari]) for i in choices.values()], [1] * 8) p, c = imperial[0] eq_((p, c.char_cls), (g.players[0], characters.sp_aya.SpAya)) assert c in choices[p]