def refreshStats(self):
        
        liveplayers={}
        nextMap=''
        currentMap=''
        global stats
        
        for i in _ba.get_game_roster():
            try:
                liveplayers[i['account_id']]={'name':i['players'][0]['name_full'],'client_id':i['client_id'],'device_id':i['display_string']}
            except:
                liveplayers[i['account_id']]={'name':"<in-lobby>",'clientid':i['client_id'],'device_id':i['display_string']}
        try:    
            nextMap=_ba.get_foreground_host_session().get_next_game_description().evaluate()

            current_game_spec=_ba.get_foreground_host_session()._current_game_spec
            gametype: Type[GameActivity] =current_game_spec['resolved_type']
            
            currentMap=gametype.get_settings_display_string(current_game_spec).evaluate()
        except:
            pass
        minigame={'current':currentMap,'next':nextMap}
        # system={'cpu':p.cpu_percent(),'ram':p.virtual_memory().percent}
        #system={'cpu':80,'ram':34}
        # stats['system']=system
        stats['roster']=liveplayers
        stats['chats']=_ba.get_chat_messages()
        stats['playlist']=minigame
Exemplo n.º 2
0
    def return_to_main_menu_session_gracefully(self) -> None:
        """Attempt to cleanly get back to the main menu."""
        # pylint: disable=cyclic-import
        from ba import _benchmark
        from ba._general import Call
        from bastd.mainmenu import MainMenuSession
        _ba.app.main_window = None
        if isinstance(_ba.get_foreground_host_session(), MainMenuSession):
            # It may be possible we're on the main menu but the screen is faded
            # so fade back in.
            _ba.fade_screen(True)
            return

        _benchmark.stop_stress_test()  # Stop stress-test if in progress.

        # If we're in a host-session, tell them to end.
        # This lets them tear themselves down gracefully.
        host_session: Optional[ba.Session] = _ba.get_foreground_host_session()
        if host_session is not None:

            # Kick off a little transaction so we'll hopefully have all the
            # latest account state when we get back to the menu.
            _ba.add_transaction({
                'type': 'END_SESSION',
                'sType': str(type(host_session))
            })
            _ba.run_transactions()

            host_session.end()

        # Otherwise just force the issue.
        else:
            _ba.pushcall(Call(_ba.new_host_session, MainMenuSession))
Exemplo n.º 3
0
def QuickAccess(msg,client_id):
	if msg.startswith(","):
		acid=""
		teamid=0
		for i in _ba.get_foreground_host_session().sessionplayers:
			if i.inputdevice.client_id==client_id:
				teamid=i.sessionteam.id

		for i in _ba.get_foreground_host_session().sessionplayers:
			if teamid==i.sessionteam.id and i.inputdevice.client_id!=client_id:
				_ba.screenmessage(i.getname(True)+":"+msg[1:],clients=[i.inputdevice.client_id],color=(0.3,0.6,0.3))
	
	return None;
Exemplo n.º 4
0
        def _put_log() -> None:
            try:
                sessionname = str(_ba.get_foreground_host_session())
            except Exception:
                sessionname = 'unavailable'
            try:
                activityname = str(_ba.get_foreground_host_activity())
            except Exception:
                activityname = 'unavailable'

            info = {
                'log': _ba.getlog(),
                'version': app.version,
                'build': app.build_number,
                'userAgentString': app.user_agent_string,
                'session': sessionname,
                'activity': activityname,
                'fatal': 0,
                'userRanCommands': _ba.has_user_run_commands(),
                'time': _ba.time(TimeType.REAL),
                'userModded': _ba.has_user_mods(),
                'newsShow': _ba.get_news_show(),
            }

            def response(data: Any) -> None:
                # A non-None response means success; lets
                # take note that we don't need to report further
                # log info this run
                if data is not None:
                    app.log_have_new = False
                    _ba.mark_log_sent()

            master_server_post('bsLog', info, response)
 def check(self):
     current = ba.time(ba.TimeType.REAL,
                       timeformat=ba.TimeFormat.MILLISECONDS)
     for player in _ba.get_foreground_host_session().sessionplayers:
         last_input = int(player.inputdevice.get_last_input_time())
         afk_time = int((current - last_input) / 1000)
         if afk_time in range(INGAME_TIME, INGAME_TIME + 20):
             self.warn_player(
                 player.get_account_id(), "Press any button within " +
                 str(INGAME_TIME + 20 - afk_time) + " secs")
         if afk_time > INGAME_TIME + 20:
             player.remove_from_game()
     if LOBBY_KICK:
         current_players = []
         for player in _ba.get_game_roster():
             if player['client_id'] != -1 and len(player['players']) == 0:
                 current_players.append(player['client_id'])
                 if player['client_id'] not in self.lobbies:
                     self.lobbies[player['client_id']] = current
                 lobby_afk = int(
                     (current - self.lobbies[player['client_id']]) / 1000)
                 if lobby_afk in range(INLOBBY_TIME, INLOBBY_TIME + 10):
                     _ba.screenmessage("Join game within " +
                                       str(INLOBBY_TIME + 10 - lobby_afk) +
                                       " secs",
                                       color=(1, 0, 0),
                                       transient=True,
                                       clients=[player['client_id']])
                 if lobby_afk > INLOBBY_TIME + 10:
                     _ba.disconnect_client(player['client_id'], 0)
         # clean the lobbies dict
         temp = self.lobbies.copy()
         for clid in temp:
             if clid not in current_players:
                 del self.lobbies[clid]
def clientid_to_myself(clientid):
    """Return Player Index Of Self Player"""

    session = _ba.get_foreground_host_session()

    for i in range(len(session.sessionplayers)):
        if session.sessionplayers[i].inputdevice.client_id == clientid:
            return int(session.sessionplayers[i].id)
def set_custom_effect(arguments):
    try:
        session = _ba.get_foreground_host_session()
        for i in session.sessionplayers:
            if i.inputdevice.client_id == int(arguments[1]):
                roles = pdata.set_effect(arguments[0], i.get_account_id())
    except:
        return
Exemplo n.º 8
0
    def __init__(self, transition: Optional[str] = 'in_right'):
        # pylint: disable=cyclic-import
        import threading
        from bastd.mainmenu import MainMenuSession
        self._in_game = not isinstance(_ba.get_foreground_host_session(),
                                       MainMenuSession)

        # Preload some modules we use in a background thread so we won't
        # have a visual hitch when the user taps them.
        threading.Thread(target=self._preload_modules).start()

        if not self._in_game:
            ba.set_analytics_screen('Main Menu')
            self._show_remote_app_info_on_first_launch()

        # Make a vanilla container; we'll modify it to our needs in refresh.
        super().__init__(root_widget=ba.containerwidget(
            transition=transition,
            toolbar_visibility='menu_minimal_no_back' if self.
            _in_game else 'menu_minimal_no_back'))

        # Grab this stuff in case it changes.
        self._is_demo = ba.app.demo_mode
        self._is_arcade = ba.app.arcade_mode
        self._is_iircade = ba.app.iircade_mode

        self._tdelay = 0.0
        self._t_delay_inc = 0.02
        self._t_delay_play = 1.7
        self._p_index = 0
        self._use_autoselect = True
        self._button_width = 200.0
        self._button_height = 45.0
        self._width = 100.0
        self._height = 100.0
        self._demo_menu_button: Optional[ba.Widget] = None
        self._gather_button: Optional[ba.Widget] = None
        self._start_button: Optional[ba.Widget] = None
        self._watch_button: Optional[ba.Widget] = None
        self._gc_button: Optional[ba.Widget] = None
        self._how_to_play_button: Optional[ba.Widget] = None
        self._credits_button: Optional[ba.Widget] = None
        self._settings_button: Optional[ba.Widget] = None

        self._store_char_tex = self._get_store_char_tex()

        self._refresh()
        self._restore_state()

        # Keep an eye on a few things and refresh if they change.
        self._account_state = _ba.get_account_state()
        self._account_state_num = _ba.get_account_state_num()
        self._account_type = (_ba.get_account_type()
                              if self._account_state == 'signed_in' else None)
        self._refresh_timer = ba.Timer(1.0,
                                       ba.WeakCall(self._check_refresh),
                                       repeat=True,
                                       timetype=ba.TimeType.REAL)
Exemplo n.º 9
0
def _reset_stress_test(args: Dict[str, Any]) -> None:
    from ba._general import Call
    from ba._enums import TimeType
    _ba.set_stress_testing(False, args['player_count'])
    _ba.screenmessage('Resetting stress test...')
    session = _ba.get_foreground_host_session()
    assert session is not None
    session.end()
    _ba.timer(1.0, Call(start_stress_test, args), timetype=TimeType.REAL)
def remove(arguments):

    if arguments == [] or arguments == ['']:
        return

    elif arguments[0] == 'all':
        session = _ba.get_foreground_host_session()
        for i in session.sessionplayers:
            i.remove_from_game()

    else:
        try:
            session = _ba.get_foreground_host_session()
            for i in session.sessionplayers:
                if i.inputdevice.client_id == int(arguments[0]):
                    i.remove_from_game()
        except:
            return
def add_role_to_player(arguments):
    try:

        session = _ba.get_foreground_host_session()
        for i in session.sessionplayers:
            if i.inputdevice.client_id == int(arguments[1]):
                roles = pdata.add_player_role(arguments[0], i.get_account_id())
    except:
        return
Exemplo n.º 12
0
def handle_hit(msg, hp, dmg, hit_by, msg_pos):
    #Check
    if not msg.hit_type: return

    #Record Out Data
    dmg = dmg / 10
    if hit_by is not None:
        hit_by_id = None
        hit_by_id = hit_by.node.playerID
        if hit_by_id is not None:
            hit_by_account_id = None
            for c in _ba.get_foreground_host_session().sessionplayers:
                if (c.activityplayer) and (c.activityplayer.node.playerID
                                           == hit_by_id):
                    hit_by_account_id = c.get_account_id()
                    if hit_by_account_id in damage_data:
                        damage_data[hit_by_account_id] += float(dmg)
                    else:
                        damage_data[hit_by_account_id] = float(dmg)
    #Send Screen Texts in enabled
    if our_settings['enableHitTexts']:
        try:
            if hp <= 0:
                PopupText("Rest In Peace !",
                          color=(1, 0.2, 0.2),
                          scale=1.6,
                          position=msg_pos).autoretain()
            else:
                if dmg >= 800:
                    PopupText("#PRO !",
                              color=(1, 0.2, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 600 and dmg < 800:
                    PopupText("GOOD ONE!",
                              color=(1, 0.3, 0.1),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 400 and dmg < 600:
                    PopupText("OH! YEAH",
                              color=(1, 0.5, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 200 and dmg < 400:
                    PopupText("WTF!",
                              color=(0.7, 0.4, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg > 0 and dmg < 200:
                    PopupText("!!!",
                              color=(1, 1, 1),
                              scale=1.6,
                              position=msg_pos).autoretain()
        except:
            pass
    return
Exemplo n.º 13
0
def set_playlist_inline(playlist, newPLaylistType):
    session = _ba.get_foreground_host_session()

    if (isinstance(session, DualTeamSession)
            or isinstance(session, CoopSession)) and newPLaylistType == 'ffa':
        #_ba.get_foreground_host_activity().end_game()
        _ba.get_foreground_host_session().end()
        _thread.start_new_thread(withDelay, (
            FreeForAllSession,
            playlist,
        ))
    elif (isinstance(session, FreeForAllSession)
          or isinstance(session, CoopSession)) and newPLaylistType == "teams":
        _ba.get_foreground_host_session().end()
        _thread.start_new_thread(withDelay, (
            DualTeamSession,
            playlist,
        ))
    else:
        updatePlaylist(playlist)
Exemplo n.º 14
0
def setTeamCharacter():
    if not _setting["sameCharacterForTeam"]:
        return
    used = []
    teams = _ba.get_foreground_host_session().sessionteams
    if len(teams) < 10:
        for team in teams:
            character = getRandomCharacter(used)
            used.append(character)
            team.name = character
            team.customdata["character"] = character
Exemplo n.º 15
0
def updatePlaylist(playlist):

    session = _ba.get_foreground_host_session()
    content = ba._playlist.filter_playlist(
        playlist,
        sessiontype=type(session),
        add_resolved_type=True,
    )
    playlist = ba._multiteamsession.ShuffleList(content, shuffle=False)
    session._playlist = playlist
    set_next_map(session, playlist.pull_next())
def movePlayers(fromTeam,toTeam,count):
	session=_ba.get_foreground_host_session()
	fromTeam=session.sessionteams[fromTeam]
	toTeam=session.sessionteams[toTeam]
	for i in range(0,count):
		player=fromTeam.players.pop()
		print("moved"+player.get_account_id())
		broadCastShiftMsg(player.get_account_id())
		player.setdata(team=toTeam,character=player.character,color=toTeam.color,highlight=player.highlight)
		iconinfo=player.get_icon_info()
		player.set_icon_info(iconinfo['texture'],iconinfo['tint_texture'],toTeam.color,player.highlight)
		toTeam.players.append(player)
def on_player_join():
	session = _ba.get_foreground_host_session()
	if len(session.sessionplayers)>1:
		return
	if isinstance(session,DualTeamSession):
		if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
			playlist.setPlaylist('coop')

	# this not usefull now ., leave it here for now
	elif isinstance(session,CoopSession):
		if len(session.sessionplayers) >= settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
			playlist.setPlaylist('default')
def get_roles_of_player(arguments, clientid):
    try:
        session = _ba.get_foreground_host_session()
        roles = []
        reply = ""
        for i in session.sessionplayers:
            if i.inputdevice.client_id == int(arguments[0]):
                roles = pdata.get_player_roles(i.get_account_id())
                print(roles)
        for role in roles:
            reply = reply + role + ","
        send(reply, clientid)
    except:
        return
Exemplo n.º 19
0
def handle_party_invite(name: str, invite_id: str) -> None:
    """Handle an incoming party invitation."""
    from bastd import mainmenu
    from bastd.ui import confirm
    ba.playsound(ba.getsound('fanfare'))

    # if we're not in the main menu, just print the invite
    # (don't want to screw up an in-progress game)
    in_game = not isinstance(_ba.get_foreground_host_session(),
                             mainmenu.MainMenuSession)
    if in_game:
        ba.screenmessage(ba.Lstr(
            value='${A}\n${B}',
            subs=[('${A}',
                   ba.Lstr(resource='gatherWindow.partyInviteText',
                           subs=[('${NAME}', name)])),
                  ('${B}',
                   ba.Lstr(
                       resource='gatherWindow.partyInviteGooglePlayExtraText'))
                  ]),
                         color=(0.5, 1, 0))
    else:

        def do_accept(inv_id: str) -> None:
            _ba.accept_party_invitation(inv_id)

        conf = confirm.ConfirmWindow(
            ba.Lstr(resource='gatherWindow.partyInviteText',
                    subs=[('${NAME}', name)]),
            ba.Call(do_accept, invite_id),
            width=500,
            height=150,
            color=(0.75, 1.0, 0.0),
            ok_text=ba.Lstr(resource='gatherWindow.partyInviteAcceptText'),
            cancel_text=ba.Lstr(resource='gatherWindow.partyInviteIgnoreText'))

        # FIXME: Ugly.
        # Let's store the invite-id away on the confirm window so we know if
        # we need to kill it later.
        # noinspection PyTypeHints
        conf.party_invite_id = invite_id  # type: ignore

        # store a weak-ref so we can get at this later
        ba.app.invite_confirm_windows.append(weakref.ref(conf))

        # go ahead and prune our weak refs while we're here.
        ba.app.invite_confirm_windows = [
            w for w in ba.app.invite_confirm_windows if w() is not None
        ]
Exemplo n.º 20
0
    def __init__(self, transition: Optional[str] = 'in_right'):
        # pylint: disable=cyclic-import
        from bastd import mainmenu
        self._in_game = not isinstance(_ba.get_foreground_host_session(),
                                       mainmenu.MainMenuSession)
        if not self._in_game:
            ba.set_analytics_screen('Main Menu')

            self._show_remote_app_info_on_first_launch()

        # Make a vanilla container; we'll modify it to our needs in refresh.
        super().__init__(root_widget=ba.containerwidget(
            transition=transition,
            toolbar_visibility='menu_minimal_no_back' if self.
            _in_game else 'menu_minimal_no_back'))

        self._is_kiosk = ba.app.kiosk_mode
        self._tdelay = 0.0
        self._t_delay_inc = 0.02
        self._t_delay_play = 1.7
        self._p_index = 0
        self._use_autoselect = True
        self._button_width = 200.0
        self._button_height = 45.0
        self._width = 100.0
        self._height = 100.0
        self._demo_menu_button: Optional[ba.Widget] = None
        self._gather_button: Optional[ba.Widget] = None
        self._start_button: Optional[ba.Widget] = None
        self._watch_button: Optional[ba.Widget] = None
        self._gc_button: Optional[ba.Widget] = None
        self._how_to_play_button: Optional[ba.Widget] = None
        self._credits_button: Optional[ba.Widget] = None

        self._store_char_tex = self._get_store_char_tex()

        self._refresh()
        self._restore_state()

        # Keep an eye on a few things and refresh if they change.
        self._account_state = _ba.get_account_state()
        self._account_state_num = _ba.get_account_state_num()
        self._account_type = (_ba.get_account_type()
                              if self._account_state == 'signed_in' else None)
        self._refresh_timer = ba.Timer(1.0,
                                       ba.WeakCall(self._check_refresh),
                                       repeat=True,
                                       timetype=ba.TimeType.REAL)
Exemplo n.º 21
0
def list(clientid):
	"""Returns The List Of Players Clientid and index"""
	
	p = u'{0:^16}{1:^15}{2:^10}'
	seprator = '\n______________________________\n'
	
	
	list = p.format('Name', 'Client ID' , 'Player ID')+seprator
	session = _ba.get_foreground_host_session()
	
	
	for index, player in enumerate(session.sessionplayers):
		list += p.format(player.getname(icon = False),
		player.inputdevice.client_id, index)+"\n"

	send(list, clientid)
Exemplo n.º 22
0
def accountid_request(arguments, clientid, accountid):
	"""Returns The Account Id Of Players"""
	
	if arguments == [] or arguments == ['']:
		send(f"Your account id is {accountid} ", clientid)
		
	else:
		try:
			session = _ba.get_foreground_host_session()
			player = session.sessionplayers[int(arguments[0])]
			
			name = player.getname(full=True, icon=True)
			accountid = player.get_account_id()
			
			send(f" {name}'s account id is '{accountid}' ", clientid)
		except:
			return
Exemplo n.º 23
0
	def __init__(self):
		modifyspaz.setTeamCharacter()
		
		
		data = setti['textonmap']
		left = data['bottom left watermark']
		top = data['top watermark']
		nextMap=""
		try:

			nextMap=_ba.get_foreground_host_session().get_next_game_description().evaluate()
		except:
			pass
		self.index = 0
		self.highlights = data['center highlights']["msg"]
		self.left_watermark(left)
		self.top_message(top)
		self.nextGame(nextMap)
		if setti["leaderboard"]["enable"]:
			self.leaderBoard()
		self.timer = ba.timer(8, ba.Call(self.highlights_), repeat=True)
Exemplo n.º 24
0
 def _on_party_member_press(self, client_id: int, is_host: bool,
                            widget: ba.Widget) -> None:
     # if we're the host, pop up 'kick' options for all non-host members
     if _ba.get_foreground_host_session() is not None:
         kick_str = ba.Lstr(resource='kickText')
     else:
         # kick-votes appeared in build 14248
         if (_ba.get_connection_to_host_info().get('build_number', 0) <
                 14248):
             return
         kick_str = ba.Lstr(resource='kickVoteText')
     popup.PopupMenuWindow(
         position=widget.get_screen_space_center(),
         scale=2.3 if ba.app.small_ui else 1.65 if ba.app.med_ui else 1.23,
         choices=['kick'],
         choices_display=[kick_str],
         current_choice='kick',
         delegate=self)
     self._popup_type = 'partyMemberPress'
     self._popup_party_member_client_id = client_id
     self._popup_party_member_is_host = is_host
def balanceTeams():
	
	session = _ba.get_foreground_host_session()
	if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
		playlist.setPlaylist('coop')
		return
	
	if not isinstance(session,DualTeamSession) or len(session.sessionplayers)<4 or len(session.sessionteams)!=2:
		return
	teamASize=0
	teamBSize=0

	for player in session.sessionplayers:
		if player.sessionteam.id==0:
			teamASize+=1
		else:
			teamBSize+=1
	
	if abs(teamBSize-teamASize)>=0:
		if teamBSize> teamASize and teamBSize!=0:
			movePlayers(1,0,abs(teamBSize-teamASize)-1)
		elif teamASize>teamBSize and teamASize!=0:
			movePlayers(0,1,abs(teamBSize-teamASize)-1)
    def getTeamInfo(self):
        data = {}

        session = _ba.get_foreground_host_session()
        data['sessionType'] = type(session).__name__
        teams = session.sessionteams
        for team in teams:
            data[team.id] = {
                'name': team.name.evaluate(),
                'color': list(team.color),
                'score': team.customdata['score'],
                'players': []
            }
            for player in team.players:
                teamplayer = {
                    'name': player.getname(),
                    'device_id': player.inputdevice.get_account_name(True),
                    'inGame': player.in_game,
                    'character': player.character,
                    'account_id': player.get_account_id()
                }
                data[team.id]['players'].append(teamplayer)

        return data
Exemplo n.º 27
0
def call_after_ad(call: Callable[[], Any]) -> None:
    """Run a call after potentially showing an ad."""
    # pylint: disable=too-many-statements
    # pylint: disable=too-many-branches
    # pylint: disable=too-many-locals
    from ba._account import have_pro
    from ba._enums import TimeType
    import time
    app = _ba.app
    show = True

    # No ads without net-connections, etc.
    if not _ba.can_show_ad():
        show = False
    if have_pro():
        show = False  # Pro disables interstitials.
    try:
        session = _ba.get_foreground_host_session()
        assert session is not None
        is_tournament = session.tournament_id is not None
    except Exception:
        is_tournament = False
    if is_tournament:
        show = False  # Never show ads during tournaments.

    if show:
        interval: Optional[float]
        launch_count = app.config.get('launchCount', 0)

        # If we're seeing short ads we may want to space them differently.
        interval_mult = (_ba.get_account_misc_read_val(
            'ads.shortIntervalMult', 1.0) if app.last_ad_was_short else 1.0)
        if app.ad_amt is None:
            if launch_count <= 1:
                app.ad_amt = _ba.get_account_misc_read_val(
                    'ads.startVal1', 0.99)
            else:
                app.ad_amt = _ba.get_account_misc_read_val(
                    'ads.startVal2', 1.0)
            interval = None
        else:
            # So far we're cleared to show; now calc our ad-show-threshold and
            # see if we should *actually* show (we reach our threshold faster
            # the longer we've been playing).
            base = 'ads' if _ba.has_video_ads() else 'ads2'
            min_lc = _ba.get_account_misc_read_val(base + '.minLC', 0.0)
            max_lc = _ba.get_account_misc_read_val(base + '.maxLC', 5.0)
            min_lc_scale = (_ba.get_account_misc_read_val(
                base + '.minLCScale', 0.25))
            max_lc_scale = (_ba.get_account_misc_read_val(
                base + '.maxLCScale', 0.34))
            min_lc_interval = (_ba.get_account_misc_read_val(
                base + '.minLCInterval', 360))
            max_lc_interval = (_ba.get_account_misc_read_val(
                base + '.maxLCInterval', 300))
            if launch_count < min_lc:
                lc_amt = 0.0
            elif launch_count > max_lc:
                lc_amt = 1.0
            else:
                lc_amt = ((float(launch_count) - min_lc) / (max_lc - min_lc))
            incr = (1.0 - lc_amt) * min_lc_scale + lc_amt * max_lc_scale
            interval = ((1.0 - lc_amt) * min_lc_interval +
                        lc_amt * max_lc_interval)
            app.ad_amt += incr
        assert app.ad_amt is not None
        if app.ad_amt >= 1.0:
            app.ad_amt = app.ad_amt % 1.0
            app.attempted_first_ad = True

        # After we've reached the traditional show-threshold once,
        # try again whenever its been INTERVAL since our last successful show.
        elif (app.attempted_first_ad
              and (app.last_ad_completion_time is None or
                   (interval is not None
                    and _ba.time(TimeType.REAL) - app.last_ad_completion_time >
                    (interval * interval_mult)))):
            # Reset our other counter too in this case.
            app.ad_amt = 0.0
        else:
            show = False

    # If we're *still* cleared to show, actually tell the system to show.
    if show:
        # As a safety-check, set up an object that will run
        # the completion callback if we've returned and sat for 10 seconds
        # (in case some random ad network doesn't properly deliver its
        # completion callback).
        class _Payload:
            def __init__(self, pcall: Callable[[], Any]):
                self._call = pcall
                self._ran = False

            def run(self, fallback: bool = False) -> None:
                """Run the fallback call (and issues a warning about it)."""
                if not self._ran:
                    if fallback:
                        print((
                            'ERROR: relying on fallback ad-callback! '
                            'last network: ' + app.last_ad_network + ' (set ' +
                            str(int(time.time() -
                                    app.last_ad_network_set_time)) +
                            's ago); purpose=' + app.last_ad_purpose))
                    _ba.pushcall(self._call)
                    self._ran = True

        payload = _Payload(call)
        with _ba.Context('ui'):
            _ba.timer(5.0,
                      lambda: payload.run(fallback=True),
                      timetype=TimeType.REAL)
        show_ad('between_game', on_completion_call=payload.run)
    else:
        _ba.pushcall(call)  # Just run the callback without the ad.
Exemplo n.º 28
0
    def _refresh_in_game(
        self, positions: List[Tuple[float, float,
                                    float]]) -> Tuple[float, float, float]:
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        custom_menu_entries: List[Dict[str, Any]] = []
        session = _ba.get_foreground_host_session()
        if session is not None:
            try:
                custom_menu_entries = session.get_custom_menu_entries()
                for cme in custom_menu_entries:
                    if (not isinstance(cme, dict) or 'label' not in cme
                            or not isinstance(cme['label'], (str, ba.Lstr))
                            or 'call' not in cme or not callable(cme['call'])):
                        raise ValueError('invalid custom menu entry: ' +
                                         str(cme))
            except Exception:
                custom_menu_entries = []
                ba.print_exception(
                    f'Error getting custom menu entries for {session}')
        self._width = 250.0
        self._height = 250.0 if self._input_player else 180.0
        if (self._is_demo or self._is_arcade) and self._input_player:
            self._height -= 40
        if not self._have_settings_button:
            self._height -= 50
        if self._connected_to_remote_player:
            # In this case we have a leave *and* a disconnect button.
            self._height += 50
        self._height += 50 * (len(custom_menu_entries))
        uiscale = ba.app.ui.uiscale
        ba.containerwidget(
            edit=self._root_widget,
            size=(self._width, self._height),
            scale=(2.15 if uiscale is ba.UIScale.SMALL else
                   1.6 if uiscale is ba.UIScale.MEDIUM else 1.0))
        h = 125.0
        v = (self._height - 80.0 if self._input_player else self._height - 60)
        h_offset = 0
        d_h_offset = 0
        v_offset = -50
        for _i in range(6 + len(custom_menu_entries)):
            positions.append((h, v, 1.0))
            v += v_offset
            h += h_offset
            h_offset += d_h_offset
        self._start_button = None
        ba.app.pause()

        # Player name if applicable.
        if self._input_player:
            player_name = self._input_player.getname()
            h, v, scale = positions[self._p_index]
            v += 35
            ba.textwidget(parent=self._root_widget,
                          position=(h - self._button_width / 2, v),
                          size=(self._button_width, self._button_height),
                          color=(1, 1, 1, 0.5),
                          scale=0.7,
                          h_align='center',
                          text=ba.Lstr(value=player_name))
        else:
            player_name = ''
        h, v, scale = positions[self._p_index]
        self._p_index += 1
        btn = ba.buttonwidget(parent=self._root_widget,
                              position=(h - self._button_width / 2, v),
                              size=(self._button_width, self._button_height),
                              scale=scale,
                              label=ba.Lstr(resource=self._r + '.resumeText'),
                              autoselect=self._use_autoselect,
                              on_activate_call=self._resume)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        # Add any custom options defined by the current game.
        for entry in custom_menu_entries:
            h, v, scale = positions[self._p_index]
            self._p_index += 1

            # Ask the entry whether we should resume when we call
            # it (defaults to true).
            resume = bool(entry.get('resume_on_call', True))

            if resume:
                call = ba.Call(self._resume_and_call, entry['call'])
            else:
                call = ba.Call(entry['call'], ba.WeakCall(self._resume))

            ba.buttonwidget(parent=self._root_widget,
                            position=(h - self._button_width / 2, v),
                            size=(self._button_width, self._button_height),
                            scale=scale,
                            on_activate_call=call,
                            label=entry['label'],
                            autoselect=self._use_autoselect)
        # Add a 'leave' button if the menu-owner has a player.
        if ((self._input_player or self._connected_to_remote_player)
                and not (self._is_demo or self._is_arcade)):
            h, v, scale = positions[self._p_index]
            self._p_index += 1
            btn = ba.buttonwidget(parent=self._root_widget,
                                  position=(h - self._button_width / 2, v),
                                  size=(self._button_width,
                                        self._button_height),
                                  scale=scale,
                                  on_activate_call=self._leave,
                                  label='',
                                  autoselect=self._use_autoselect)

            if (player_name != '' and player_name[0] != '<'
                    and player_name[-1] != '>'):
                txt = ba.Lstr(resource=self._r + '.justPlayerText',
                              subs=[('${NAME}', player_name)])
            else:
                txt = ba.Lstr(value=player_name)
            ba.textwidget(parent=self._root_widget,
                          position=(h, v + self._button_height *
                                    (0.64 if player_name != '' else 0.5)),
                          size=(0, 0),
                          text=ba.Lstr(resource=self._r + '.leaveGameText'),
                          scale=(0.83 if player_name != '' else 1.0),
                          color=(0.75, 1.0, 0.7),
                          h_align='center',
                          v_align='center',
                          draw_controller=btn,
                          maxwidth=self._button_width * 0.9)
            ba.textwidget(parent=self._root_widget,
                          position=(h, v + self._button_height * 0.27),
                          size=(0, 0),
                          text=txt,
                          color=(0.75, 1.0, 0.7),
                          h_align='center',
                          v_align='center',
                          draw_controller=btn,
                          scale=0.45,
                          maxwidth=self._button_width * 0.9)
        return h, v, scale
Exemplo n.º 29
0
    def _refresh(self) -> None:
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        from bastd.ui.confirm import QuitWindow
        from bastd.ui.store.button import StoreButton

        # Clear everything that was there.
        children = self._root_widget.get_children()
        for child in children:
            child.delete()

        self._tdelay = 0.0
        self._t_delay_inc = 0.0
        self._t_delay_play = 0.0
        self._button_width = 200.0
        self._button_height = 45.0

        self._r = 'mainMenu'

        app = ba.app
        self._have_quit_button = (app.ui.uiscale is ba.UIScale.LARGE
                                  or (app.platform == 'windows'
                                      and app.subplatform == 'oculus'))

        self._have_store_button = not self._in_game

        self._have_settings_button = (
            (not self._in_game or not app.toolbar_test)
            and not (self._is_demo or self._is_arcade or self._is_iircade))

        self._input_device = input_device = _ba.get_ui_input_device()
        self._input_player = input_device.player if input_device else None
        self._connected_to_remote_player = (
            input_device.is_connected_to_remote_player()
            if input_device else False)

        positions: List[Tuple[float, float, float]] = []
        self._p_index = 0

        if self._in_game:
            h, v, scale = self._refresh_in_game(positions)
        else:
            h, v, scale = self._refresh_not_in_game(positions)

        if self._have_settings_button:
            h, v, scale = positions[self._p_index]
            self._p_index += 1
            self._settings_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(h - self._button_width * 0.5 * scale, v),
                size=(self._button_width, self._button_height),
                scale=scale,
                autoselect=self._use_autoselect,
                label=ba.Lstr(resource=self._r + '.settingsText'),
                transition_delay=self._tdelay,
                on_activate_call=self._settings)

        # Scattered eggs on easter.
        if _ba.get_account_misc_read_val('easter',
                                         False) and not self._in_game:
            icon_size = 34
            ba.imagewidget(parent=self._root_widget,
                           position=(h - icon_size * 0.5 - 15,
                                     v + self._button_height * scale -
                                     icon_size * 0.24 + 1.5),
                           transition_delay=self._tdelay,
                           size=(icon_size, icon_size),
                           texture=ba.gettexture('egg3'),
                           tilt_scale=0.0)

        self._tdelay += self._t_delay_inc

        if self._in_game:
            h, v, scale = positions[self._p_index]
            self._p_index += 1

            # If we're in a replay, we have a 'Leave Replay' button.
            if _ba.is_in_replay():
                ba.buttonwidget(parent=self._root_widget,
                                position=(h - self._button_width * 0.5 * scale,
                                          v),
                                scale=scale,
                                size=(self._button_width, self._button_height),
                                autoselect=self._use_autoselect,
                                label=ba.Lstr(resource='replayEndText'),
                                on_activate_call=self._confirm_end_replay)
            elif _ba.get_foreground_host_session() is not None:
                ba.buttonwidget(
                    parent=self._root_widget,
                    position=(h - self._button_width * 0.5 * scale, v),
                    scale=scale,
                    size=(self._button_width, self._button_height),
                    autoselect=self._use_autoselect,
                    label=ba.Lstr(resource=self._r + '.endGameText'),
                    on_activate_call=self._confirm_end_game)
            # Assume we're in a client-session.
            else:
                ba.buttonwidget(
                    parent=self._root_widget,
                    position=(h - self._button_width * 0.5 * scale, v),
                    scale=scale,
                    size=(self._button_width, self._button_height),
                    autoselect=self._use_autoselect,
                    label=ba.Lstr(resource=self._r + '.leavePartyText'),
                    on_activate_call=self._confirm_leave_party)

        self._store_button: Optional[ba.Widget]
        if self._have_store_button:
            this_b_width = self._button_width
            h, v, scale = positions[self._p_index]
            self._p_index += 1

            sbtn = self._store_button_instance = StoreButton(
                parent=self._root_widget,
                position=(h - this_b_width * 0.5 * scale, v),
                size=(this_b_width, self._button_height),
                scale=scale,
                on_activate_call=ba.WeakCall(self._on_store_pressed),
                sale_scale=1.3,
                transition_delay=self._tdelay)
            self._store_button = store_button = sbtn.get_button()
            uiscale = ba.app.ui.uiscale
            icon_size = (55 if uiscale is ba.UIScale.SMALL else
                         55 if uiscale is ba.UIScale.MEDIUM else 70)
            ba.imagewidget(
                parent=self._root_widget,
                position=(h - icon_size * 0.5,
                          v + self._button_height * scale - icon_size * 0.23),
                transition_delay=self._tdelay,
                size=(icon_size, icon_size),
                texture=ba.gettexture(self._store_char_tex),
                tilt_scale=0.0,
                draw_controller=store_button)

            self._tdelay += self._t_delay_inc
        else:
            self._store_button = None

        self._quit_button: Optional[ba.Widget]
        if not self._in_game and self._have_quit_button:
            h, v, scale = positions[self._p_index]
            self._p_index += 1
            self._quit_button = quit_button = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=self._use_autoselect,
                position=(h - self._button_width * 0.5 * scale, v),
                size=(self._button_width, self._button_height),
                scale=scale,
                label=ba.Lstr(resource=self._r +
                              ('.quitText' if 'Mac' in
                               ba.app.user_agent_string else '.exitGameText')),
                on_activate_call=self._quit,
                transition_delay=self._tdelay)

            # Scattered eggs on easter.
            if _ba.get_account_misc_read_val('easter', False):
                icon_size = 30
                ba.imagewidget(parent=self._root_widget,
                               position=(h - icon_size * 0.5 + 25,
                                         v + self._button_height * scale -
                                         icon_size * 0.24 + 1.5),
                               transition_delay=self._tdelay,
                               size=(icon_size, icon_size),
                               texture=ba.gettexture('egg1'),
                               tilt_scale=0.0)

            ba.containerwidget(edit=self._root_widget,
                               cancel_button=quit_button)
            self._tdelay += self._t_delay_inc
        else:
            self._quit_button = None

            # If we're not in-game, have no quit button, and this is android,
            # we want back presses to quit our activity.
            if (not self._in_game and not self._have_quit_button
                    and ba.app.platform == 'android'):

                def _do_quit() -> None:
                    QuitWindow(swish=True, back=True)

                ba.containerwidget(edit=self._root_widget,
                                   on_cancel_call=_do_quit)

        # Add speed-up/slow-down buttons for replays.
        # (ideally this should be part of a fading-out playback bar like most
        # media players but this works for now).
        if _ba.is_in_replay():
            b_size = 50.0
            b_buffer = 10.0
            t_scale = 0.75
            uiscale = ba.app.ui.uiscale
            if uiscale is ba.UIScale.SMALL:
                b_size *= 0.6
                b_buffer *= 1.0
                v_offs = -40
                t_scale = 0.5
            elif uiscale is ba.UIScale.MEDIUM:
                v_offs = -70
            else:
                v_offs = -100
            self._replay_speed_text = ba.textwidget(
                parent=self._root_widget,
                text=ba.Lstr(resource='watchWindow.playbackSpeedText',
                             subs=[('${SPEED}', str(1.23))]),
                position=(h, v + v_offs + 7 * t_scale),
                h_align='center',
                v_align='center',
                size=(0, 0),
                scale=t_scale)

            # Update to current value.
            self._change_replay_speed(0)

            # Keep updating in a timer in case it gets changed elsewhere.
            self._change_replay_speed_timer = ba.Timer(
                0.25,
                ba.WeakCall(self._change_replay_speed, 0),
                timetype=ba.TimeType.REAL,
                repeat=True)
            btn = ba.buttonwidget(parent=self._root_widget,
                                  position=(h - b_size - b_buffer,
                                            v - b_size - b_buffer + v_offs),
                                  button_type='square',
                                  size=(b_size, b_size),
                                  label='',
                                  autoselect=True,
                                  on_activate_call=ba.Call(
                                      self._change_replay_speed, -1))
            ba.textwidget(
                parent=self._root_widget,
                draw_controller=btn,
                text='-',
                position=(h - b_size * 0.5 - b_buffer,
                          v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
                h_align='center',
                v_align='center',
                size=(0, 0),
                scale=3.0 * t_scale)
            btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(h + b_buffer, v - b_size - b_buffer + v_offs),
                button_type='square',
                size=(b_size, b_size),
                label='',
                autoselect=True,
                on_activate_call=ba.Call(self._change_replay_speed, 1))
            ba.textwidget(
                parent=self._root_widget,
                draw_controller=btn,
                text='+',
                position=(h + b_size * 0.5 + b_buffer,
                          v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
                h_align='center',
                v_align='center',
                size=(0, 0),
                scale=3.0 * t_scale)
Exemplo n.º 30
0
    def _refresh(self) -> None:
        # pylint: disable=too-many-locals
        from ba.internal import (PlayerProfilesChangedMessage,
                                 get_player_profile_colors,
                                 get_player_profile_icon)
        old_selection = self._selected_profile

        # Delete old.
        while self._profile_widgets:
            self._profile_widgets.pop().delete()
        try:
            self._profiles = ba.app.config['Player Profiles']
        except Exception:
            self._profiles = {}
        assert self._profiles is not None
        items = list(self._profiles.items())
        items.sort(key=lambda x: x[0].lower())
        index = 0
        account_name: Optional[str]
        if _ba.get_account_state() == 'signed_in':
            account_name = _ba.get_account_display_string()
        else:
            account_name = None
        widget_to_select = None
        for p_name, _ in items:
            if p_name == '__account__' and account_name is None:
                continue
            color, _highlight = get_player_profile_colors(p_name)
            scl = 1.1
            txtw = ba.textwidget(
                parent=self._columnwidget,
                position=(0, 32),
                size=((self._width - 40) / scl, 28),
                text=ba.Lstr(
                    value=account_name if p_name ==
                    '__account__' else get_player_profile_icon(p_name) +
                    p_name),
                h_align='left',
                v_align='center',
                on_select_call=ba.WeakCall(self._select, p_name, index),
                maxwidth=self._scroll_width * 0.92,
                corner_scale=scl,
                color=ba.safecolor(color, 0.4),
                always_highlight=True,
                on_activate_call=ba.Call(self._edit_button.activate),
                selectable=True)
            if index == 0:
                ba.widget(edit=txtw, up_widget=self._back_button)
            ba.widget(edit=txtw, show_buffer_top=40, show_buffer_bottom=40)
            self._profile_widgets.append(txtw)

            # Select/show this one if it was previously selected
            # (but defer till after this loop since our height is
            # still changing).
            if p_name == old_selection:
                widget_to_select = txtw

            index += 1

        if widget_to_select is not None:
            ba.columnwidget(edit=self._columnwidget,
                            selected_child=widget_to_select,
                            visible_child=widget_to_select)

        # If there's a team-chooser in existence, tell it the profile-list
        # has probably changed.
        session = _ba.get_foreground_host_session()
        if session is not None:
            session.handlemessage(PlayerProfilesChangedMessage())