mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-11-14 17:46:03 +00:00
1.6.5 before python3.9
This commit is contained in:
parent
7cb8323a5d
commit
162b04b6b5
296 changed files with 6445 additions and 491 deletions
4
dist/ba_data/python/ba/__init__.py
vendored
4
dist/ba_data/python/ba/__init__.py
vendored
|
|
@ -29,8 +29,8 @@ from ba._coopgame import CoopGameActivity
|
|||
from ba._coopsession import CoopSession
|
||||
from ba._dependency import (Dependency, DependencyComponent, DependencySet,
|
||||
AssetPackage)
|
||||
from ba._enums import (TimeType, Permission, TimeFormat, SpecialChar,
|
||||
InputType, UIScale)
|
||||
from ba._generated.enums import (TimeType, Permission, TimeFormat, SpecialChar,
|
||||
InputType, UIScale)
|
||||
from ba._error import (
|
||||
print_exception, print_error, ContextError, NotFoundError,
|
||||
PlayerNotFoundError, SessionPlayerNotFoundError, NodeNotFoundError,
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
dist/ba_data/python/ba/_account.py
vendored
6
dist/ba_data/python/ba/_account.py
vendored
|
|
@ -121,7 +121,7 @@ class AccountSubsystem:
|
|||
|
||||
def cache_tournament_info(self, info: Any) -> None:
|
||||
"""(internal)"""
|
||||
from ba._enums import TimeType, TimeFormat
|
||||
from ba._generated.enums import TimeType, TimeFormat
|
||||
for entry in info:
|
||||
cache_entry = self.tournament_info[entry['tournamentID']] = (
|
||||
copy.deepcopy(entry))
|
||||
|
|
@ -206,7 +206,7 @@ class AccountSubsystem:
|
|||
def show_post_purchase_message(self) -> None:
|
||||
"""(internal)"""
|
||||
from ba._language import Lstr
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
cur_time = _ba.time(TimeType.REAL)
|
||||
if (self.last_post_purchase_message_time is None
|
||||
or cur_time - self.last_post_purchase_message_time > 3.0):
|
||||
|
|
@ -237,7 +237,7 @@ class AccountSubsystem:
|
|||
def add_pending_promo_code(self, code: str) -> None:
|
||||
"""(internal)"""
|
||||
from ba._language import Lstr
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# If we're not signed in, queue up the code to run the next time we
|
||||
# are and issue a warning if we haven't signed in within the next
|
||||
|
|
|
|||
8
dist/ba_data/python/ba/_achievement.py
vendored
8
dist/ba_data/python/ba/_achievement.py
vendored
|
|
@ -388,7 +388,7 @@ class AchievementSubsystem:
|
|||
|
||||
def _test(self) -> None:
|
||||
"""For testing achievement animations."""
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
def testcall1() -> None:
|
||||
self.achievements[0].announce_completion()
|
||||
|
|
@ -489,7 +489,7 @@ class Achievement:
|
|||
|
||||
def announce_completion(self, sound: bool = True) -> None:
|
||||
"""Kick off an announcement for this achievement's completion."""
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
app = _ba.app
|
||||
|
||||
# Even though there are technically achievements when we're not
|
||||
|
|
@ -619,7 +619,7 @@ class Achievement:
|
|||
"""
|
||||
# pylint: disable=cyclic-import
|
||||
from ba._language import Lstr
|
||||
from ba._enums import SpecialChar
|
||||
from ba._generated.enums import SpecialChar
|
||||
from ba._coopsession import CoopSession
|
||||
from bastd.actor.image import Image
|
||||
from bastd.actor.text import Text
|
||||
|
|
@ -923,7 +923,7 @@ class Achievement:
|
|||
from ba._general import WeakCall
|
||||
from ba._language import Lstr
|
||||
from ba._messages import DieMessage
|
||||
from ba._enums import TimeType, SpecialChar
|
||||
from ba._generated.enums import TimeType, SpecialChar
|
||||
app = _ba.app
|
||||
app.ach.last_achievement_display_time = _ba.time(TimeType.REAL)
|
||||
|
||||
|
|
|
|||
7
dist/ba_data/python/ba/_activity.py
vendored
7
dist/ba_data/python/ba/_activity.py
vendored
|
|
@ -112,6 +112,11 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
|||
# transitions).
|
||||
inherits_tint = False
|
||||
|
||||
# Whether players should be allowed to join in the middle of this
|
||||
# activity. Note that Sessions may not allow mid-activity-joins even
|
||||
# if the activity says its ok.
|
||||
allow_mid_activity_joins: bool = True
|
||||
|
||||
# If the activity fades or transitions in, it should set the length of
|
||||
# time here so that previous activities will be kept alive for that
|
||||
# long (avoiding 'holes' in the screen)
|
||||
|
|
@ -275,7 +280,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
|||
|
||||
(internal)
|
||||
"""
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# Create a real-timer that watches a weak-ref of this activity
|
||||
# and reports any lingering references keeping it alive.
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_activitytypes.py
vendored
2
dist/ba_data/python/ba/_activitytypes.py
vendored
|
|
@ -8,7 +8,7 @@ from typing import TYPE_CHECKING
|
|||
import _ba
|
||||
from ba._activity import Activity
|
||||
from ba._music import setmusic, MusicType
|
||||
from ba._enums import InputType, UIScale
|
||||
from ba._generated.enums import InputType, UIScale
|
||||
# False-positive from pylint due to our class-generics-filter.
|
||||
from ba._player import EmptyPlayer # pylint: disable=W0611
|
||||
from ba._team import EmptyTeam # pylint: disable=W0611
|
||||
|
|
|
|||
6
dist/ba_data/python/ba/_actor.py
vendored
6
dist/ba_data/python/ba/_actor.py
vendored
|
|
@ -7,15 +7,15 @@ from __future__ import annotations
|
|||
import weakref
|
||||
from typing import TYPE_CHECKING, TypeVar, overload
|
||||
|
||||
import _ba
|
||||
from ba._messages import DieMessage, DeathType, OutOfBoundsMessage, UNHANDLED
|
||||
from ba._error import print_exception, ActivityNotFoundError
|
||||
import _ba
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Optional, Literal
|
||||
import ba
|
||||
|
||||
T = TypeVar('T', bound='Actor')
|
||||
TA = TypeVar('TA', bound='Actor')
|
||||
|
||||
|
||||
class Actor:
|
||||
|
|
@ -94,7 +94,7 @@ class Actor:
|
|||
|
||||
return UNHANDLED
|
||||
|
||||
def autoretain(self: T) -> T:
|
||||
def autoretain(self: TA) -> TA:
|
||||
"""Keep this Actor alive without needing to hold a reference to it.
|
||||
|
||||
This keeps the ba.Actor in existence by storing a reference to it
|
||||
|
|
|
|||
4
dist/ba_data/python/ba/_ads.py
vendored
4
dist/ba_data/python/ba/_ads.py
vendored
|
|
@ -33,7 +33,7 @@ class AdsSubsystem:
|
|||
def do_remove_in_game_ads_message(self) -> None:
|
||||
"""(internal)"""
|
||||
from ba._language import Lstr
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# Print this message once every 10 minutes at most.
|
||||
tval = _ba.time(TimeType.REAL)
|
||||
|
|
@ -70,7 +70,7 @@ class AdsSubsystem:
|
|||
# pylint: disable=too-many-statements
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-locals
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
app = _ba.app
|
||||
show = True
|
||||
|
||||
|
|
|
|||
7
dist/ba_data/python/ba/_app.py
vendored
7
dist/ba_data/python/ba/_app.py
vendored
|
|
@ -275,6 +275,7 @@ class App:
|
|||
self.pro_sale_start_val: Optional[int] = None
|
||||
|
||||
self.delegate: Optional[ba.AppDelegate] = None
|
||||
self._asyncio_timer: Optional[ba.Timer] = None
|
||||
|
||||
def on_app_launch(self) -> None:
|
||||
"""Runs after the app finishes bootstrapping.
|
||||
|
|
@ -290,9 +291,10 @@ class App:
|
|||
from bastd import appdelegate
|
||||
from bastd import maps as stdmaps
|
||||
from bastd.actor import spazappearance
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
import custom_hooks
|
||||
custom_hooks.on_app_launch()
|
||||
|
||||
cfg = self.config
|
||||
|
||||
self.delegate = appdelegate.AppDelegate()
|
||||
|
|
@ -582,7 +584,8 @@ class App:
|
|||
"""
|
||||
import urllib.request
|
||||
try:
|
||||
val = urllib.request.urlopen('https://example.com').read()
|
||||
with urllib.request.urlopen('https://example.com') as url:
|
||||
val = url.read()
|
||||
print('HTTPS TEST SUCCESS', len(val))
|
||||
except Exception as exc:
|
||||
print('HTTPS TEST FAIL:', exc)
|
||||
|
|
|
|||
6
dist/ba_data/python/ba/_appconfig.py
vendored
6
dist/ba_data/python/ba/_appconfig.py
vendored
|
|
@ -97,7 +97,7 @@ def read_config() -> Tuple[AppConfig, bool]:
|
|||
"""Read the game config."""
|
||||
import os
|
||||
import json
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
config_file_healthy = False
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ def read_config() -> Tuple[AppConfig, bool]:
|
|||
config_contents = ''
|
||||
try:
|
||||
if os.path.exists(config_file_path):
|
||||
with open(config_file_path) as infile:
|
||||
with open(config_file_path, encoding='utf-8') as infile:
|
||||
config_contents = infile.read()
|
||||
config = AppConfig(json.loads(config_contents))
|
||||
else:
|
||||
|
|
@ -140,7 +140,7 @@ def read_config() -> Tuple[AppConfig, bool]:
|
|||
prev_path = config_file_path + '.prev'
|
||||
try:
|
||||
if os.path.exists(prev_path):
|
||||
with open(prev_path) as infile:
|
||||
with open(prev_path, encoding='utf-8') as infile:
|
||||
config_contents = infile.read()
|
||||
config = AppConfig(json.loads(config_contents))
|
||||
else:
|
||||
|
|
|
|||
6
dist/ba_data/python/ba/_apputils.py
vendored
6
dist/ba_data/python/ba/_apputils.py
vendored
|
|
@ -57,7 +57,7 @@ def handle_log() -> None:
|
|||
after a short bit if desired.
|
||||
"""
|
||||
from ba._net import master_server_post
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
app = _ba.app
|
||||
app.log_have_new = True
|
||||
if not app.log_upload_timer_started:
|
||||
|
|
@ -124,7 +124,7 @@ def handle_leftover_log_file() -> None:
|
|||
from ba._net import master_server_post
|
||||
|
||||
if os.path.exists(_ba.get_log_file_path()):
|
||||
with open(_ba.get_log_file_path()) as infile:
|
||||
with open(_ba.get_log_file_path(), encoding='utf-8') as infile:
|
||||
info = json.loads(infile.read())
|
||||
infile.close()
|
||||
do_send = should_submit_debug_info()
|
||||
|
|
@ -225,7 +225,7 @@ def print_live_object_warnings(when: Any,
|
|||
def print_corrupt_file_error() -> None:
|
||||
"""Print an error if a corrupt file is found."""
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
_ba.timer(2.0,
|
||||
lambda: _ba.screenmessage(
|
||||
_ba.app.lang.get_resource('internal.corruptFileText').
|
||||
|
|
|
|||
27
dist/ba_data/python/ba/_assetmanager.py
vendored
27
dist/ba_data/python/ba/_assetmanager.py
vendored
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
import threading
|
||||
import urllib.request
|
||||
|
|
@ -14,21 +15,29 @@ import time
|
|||
import os
|
||||
import sys
|
||||
|
||||
from efro import entity
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from efro.dataclassio import (ioprepped, IOAttrs, dataclass_from_json,
|
||||
dataclass_to_json)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bacommon.assets import AssetPackageFlavor
|
||||
from typing import List
|
||||
|
||||
|
||||
class FileValue(entity.CompoundValue):
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class FileValue:
|
||||
"""State for an individual file."""
|
||||
|
||||
|
||||
class State(entity.Entity):
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class State:
|
||||
"""Holds all persistent state for the asset-manager."""
|
||||
|
||||
files = entity.CompoundDictField('files', str, FileValue())
|
||||
files: Annotated[Dict[str, FileValue],
|
||||
IOAttrs('files')] = field(default_factory=dict)
|
||||
|
||||
|
||||
class AssetManager:
|
||||
|
|
@ -101,8 +110,8 @@ class AssetManager:
|
|||
try:
|
||||
state_path = self.state_path
|
||||
if state_path.exists():
|
||||
with open(self.state_path) as infile:
|
||||
self._state = State.from_json_str(infile.read())
|
||||
with open(self.state_path, encoding='utf-8') as infile:
|
||||
self._state = dataclass_from_json(State, infile.read())
|
||||
return
|
||||
except Exception:
|
||||
logging.exception('Error loading existing AssetManager state')
|
||||
|
|
@ -113,8 +122,8 @@ class AssetManager:
|
|||
|
||||
print('ASSET-MANAGER SAVING STATE')
|
||||
try:
|
||||
with open(self.state_path, 'w') as outfile:
|
||||
outfile.write(self._state.to_json_str())
|
||||
with open(self.state_path, 'w', encoding='utf-8') as outfile:
|
||||
outfile.write(dataclass_to_json(self._state))
|
||||
except Exception:
|
||||
logging.exception('Error writing AssetManager state')
|
||||
|
||||
|
|
|
|||
71
dist/ba_data/python/ba/_asyncio.py
vendored
Normal file
71
dist/ba_data/python/ba/_asyncio.py
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Asyncio related functionality.
|
||||
|
||||
Exploring the idea of allowing Python coroutines to run gracefully
|
||||
besides our internal event loop. They could prove useful for networking
|
||||
operations or possibly game logic.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
import asyncio
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
import ba
|
||||
|
||||
# Our timer and event loop for the ballistica game thread.
|
||||
_asyncio_timer: Optional[ba.Timer] = None
|
||||
_asyncio_event_loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
|
||||
|
||||
def setup_asyncio() -> None:
|
||||
"""Setup asyncio functionality for our game thread."""
|
||||
# pylint: disable=global-statement
|
||||
|
||||
import _ba
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
assert _ba.in_game_thread()
|
||||
|
||||
# Create our event-loop. We don't expect there to be one
|
||||
# running on this thread before we do.
|
||||
try:
|
||||
asyncio.get_running_loop()
|
||||
print('Found running asyncio loop; unexpected.')
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
global _asyncio_event_loop # pylint: disable=invalid-name
|
||||
_asyncio_event_loop = asyncio.new_event_loop()
|
||||
|
||||
# Ideally we should integrate asyncio into our C++ Thread class's
|
||||
# low level event loop so that asyncio timers/sockets/etc. could
|
||||
# be true first-class citizens. For now, though, we can explicitly
|
||||
# pump an asyncio loop periodically which gets us a decent
|
||||
# approximation of that, which should be good enough for
|
||||
# all but extremely time sensitive uses.
|
||||
# See https://stackoverflow.com/questions/29782377/
|
||||
# is-it-possible-to-run-only-a-single-step-of-the-asyncio-event-loop
|
||||
def run_cycle() -> None:
|
||||
assert _asyncio_event_loop is not None
|
||||
_asyncio_event_loop.call_soon(_asyncio_event_loop.stop)
|
||||
_asyncio_event_loop.run_forever()
|
||||
|
||||
global _asyncio_timer # pylint: disable=invalid-name
|
||||
_asyncio_timer = _ba.Timer(1.0 / 30.0,
|
||||
run_cycle,
|
||||
timetype=TimeType.REAL,
|
||||
repeat=True)
|
||||
|
||||
async def aio_test() -> None:
|
||||
print('TEST AIO TASK STARTING')
|
||||
assert _asyncio_event_loop is not None
|
||||
assert asyncio.get_running_loop() is _asyncio_event_loop
|
||||
await asyncio.sleep(2.0)
|
||||
print('TEST AIO TASK ENDING')
|
||||
|
||||
if bool(False):
|
||||
_asyncio_event_loop.create_task(aio_test())
|
||||
8
dist/ba_data/python/ba/_benchmark.py
vendored
8
dist/ba_data/python/ba/_benchmark.py
vendored
|
|
@ -57,7 +57,7 @@ def run_stress_test(playlist_type: str = 'Random',
|
|||
"""Run a stress test."""
|
||||
from ba import modutils
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
_ba.screenmessage(
|
||||
'Beginning stress test.. use '
|
||||
"'End Game' to stop testing.",
|
||||
|
|
@ -93,7 +93,7 @@ def start_stress_test(args: Dict[str, Any]) -> None:
|
|||
from ba._general import Call
|
||||
from ba._dualteamsession import DualTeamSession
|
||||
from ba._freeforallsession import FreeForAllSession
|
||||
from ba._enums import TimeType, TimeFormat
|
||||
from ba._generated.enums import TimeType, TimeFormat
|
||||
appconfig = _ba.app.config
|
||||
playlist_type = args['playlist_type']
|
||||
if playlist_type == 'Random':
|
||||
|
|
@ -127,7 +127,7 @@ def start_stress_test(args: Dict[str, Any]) -> None:
|
|||
|
||||
def _reset_stress_test(args: Dict[str, Any]) -> None:
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
_ba.set_stress_testing(False, args['player_count'])
|
||||
_ba.screenmessage('Resetting stress test...')
|
||||
session = _ba.get_foreground_host_session()
|
||||
|
|
@ -144,7 +144,7 @@ def run_gpu_benchmark() -> None:
|
|||
def run_media_reload_benchmark() -> None:
|
||||
"""Kick off a benchmark to test media reloading speeds."""
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
_ba.reload_media()
|
||||
_ba.show_progress_bar()
|
||||
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_coopgame.py
vendored
2
dist/ba_data/python/ba/_coopgame.py
vendored
|
|
@ -70,7 +70,7 @@ class CoopGameActivity(GameActivity[PlayerType, TeamType]):
|
|||
from efro.util import asserttype
|
||||
from ba._gameutils import timestring, animate
|
||||
from ba._nodeactor import NodeActor
|
||||
from ba._enums import TimeFormat
|
||||
from ba._generated.enums import TimeFormat
|
||||
display_type = self.get_score_type()
|
||||
if scores is not None:
|
||||
|
||||
|
|
|
|||
65
dist/ba_data/python/ba/_coopsession.py
vendored
65
dist/ba_data/python/ba/_coopsession.py
vendored
|
|
@ -90,6 +90,16 @@ class CoopSession(Session):
|
|||
"""Get the game instance currently being played."""
|
||||
return self._current_game_instance
|
||||
|
||||
def should_allow_mid_activity_joins(self, activity: ba.Activity) -> bool:
|
||||
# pylint: disable=cyclic-import
|
||||
from ba._gameactivity import GameActivity
|
||||
|
||||
# Disallow any joins in the middle of the game.
|
||||
if isinstance(activity, GameActivity):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _update_on_deck_game_instances(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from ba._gameactivity import GameActivity
|
||||
|
|
@ -156,35 +166,44 @@ class CoopSession(Session):
|
|||
from ba._general import WeakCall
|
||||
super().on_player_leave(sessionplayer)
|
||||
|
||||
# If all our players leave we wanna quit out of the session.
|
||||
_ba.timer(2.0, WeakCall(self._end_session_if_empty))
|
||||
_ba.timer(2.0, WeakCall(self._handle_empty_activity))
|
||||
|
||||
def _end_session_if_empty(self) -> None:
|
||||
def _handle_empty_activity(self) -> None:
|
||||
"""Handle cases where all players have left the current activity."""
|
||||
|
||||
from ba._gameactivity import GameActivity
|
||||
activity = self.getactivity()
|
||||
if activity is None:
|
||||
return # Hmm what should we do in this case?
|
||||
|
||||
# If there's still players in the current activity, we're good.
|
||||
# If there are still players in the current activity, we're good.
|
||||
if activity.players:
|
||||
return
|
||||
|
||||
# If there's *no* players left in the current activity but there *is*
|
||||
# in the session, restart the activity to pull them into the game
|
||||
# (or quit if they're just in the lobby).
|
||||
# If there are *not* players in the current activity but there
|
||||
# *are* in the session:
|
||||
if not activity.players and self.sessionplayers:
|
||||
|
||||
# Special exception for tourney games; don't auto-restart these.
|
||||
if self.tournament_id is not None:
|
||||
self.end()
|
||||
else:
|
||||
# Don't restart joining activities; this probably means there's
|
||||
# someone with a chooser up in that case.
|
||||
if not activity.is_joining_activity:
|
||||
# If we're in a game, we should restart to pull in players
|
||||
# currently waiting in the session.
|
||||
if isinstance(activity, GameActivity):
|
||||
|
||||
# Never restart tourney games however; just end the session
|
||||
# if all players are gone.
|
||||
if self.tournament_id is not None:
|
||||
self.end()
|
||||
else:
|
||||
self.restart()
|
||||
|
||||
# Hmm; no players anywhere. lets just end the session.
|
||||
# Hmm; no players anywhere. Let's end the entire session if we're
|
||||
# running a GUI (or just the current game if we're running headless).
|
||||
else:
|
||||
self.end()
|
||||
if not _ba.app.headless_mode:
|
||||
self.end()
|
||||
else:
|
||||
if isinstance(activity, GameActivity):
|
||||
with _ba.Context(activity):
|
||||
activity.end_game()
|
||||
|
||||
def _on_tournament_restart_menu_press(
|
||||
self, resume_callback: Callable[[], Any]) -> None:
|
||||
|
|
@ -248,12 +267,14 @@ class CoopSession(Session):
|
|||
else:
|
||||
outcome = '' if results is None else results.get('outcome', '')
|
||||
|
||||
# If at any point we have no in-game players, quit out of the session
|
||||
# (this can happen if someone leaves in the tutorial for instance).
|
||||
active_players = [p for p in self.sessionplayers if p.in_game]
|
||||
if not active_players:
|
||||
self.end()
|
||||
return
|
||||
# If we're running with a gui and at any point we have no
|
||||
# in-game players, quit out of the session (this can happen if
|
||||
# someone leaves in the tutorial for instance).
|
||||
if not _ba.app.headless_mode:
|
||||
active_players = [p for p in self.sessionplayers if p.in_game]
|
||||
if not active_players:
|
||||
self.end()
|
||||
return
|
||||
|
||||
# If we're in a between-round activity or a restart-activity,
|
||||
# hop into a round.
|
||||
|
|
|
|||
6
dist/ba_data/python/ba/_gameactivity.py
vendored
6
dist/ba_data/python/ba/_gameactivity.py
vendored
|
|
@ -385,7 +385,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
|
|||
# pylint: disable=cyclic-import
|
||||
from bastd.ui.continues import ContinuesWindow
|
||||
from ba._coopsession import CoopSession
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
try:
|
||||
if _ba.get_account_misc_read_val('enableContinues', False):
|
||||
|
|
@ -653,7 +653,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
|
|||
def _show_tip(self) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
from ba._gameutils import animate, GameTip
|
||||
from ba._enums import SpecialChar
|
||||
from ba._generated.enums import SpecialChar
|
||||
|
||||
# If there's any tips left on the list, display one.
|
||||
if self.tips:
|
||||
|
|
@ -1009,7 +1009,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
|
|||
If the time-limit expires, end_game() will be called.
|
||||
"""
|
||||
from ba._nodeactor import NodeActor
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
if duration <= 0.0:
|
||||
return
|
||||
self._tournament_time_limit = int(duration)
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_gameresults.py
vendored
2
dist/ba_data/python/ba/_gameresults.py
vendored
|
|
@ -107,7 +107,7 @@ class GameResults:
|
|||
"""
|
||||
from ba._gameutils import timestring
|
||||
from ba._language import Lstr
|
||||
from ba._enums import TimeFormat
|
||||
from ba._generated.enums import TimeFormat
|
||||
from ba._score import ScoreType
|
||||
if not self._game_set:
|
||||
raise RuntimeError("Can't get team-score-str until game is set.")
|
||||
|
|
|
|||
3
dist/ba_data/python/ba/_gameutils.py
vendored
3
dist/ba_data/python/ba/_gameutils.py
vendored
|
|
@ -8,7 +8,7 @@ from dataclasses import dataclass
|
|||
from typing import TYPE_CHECKING
|
||||
|
||||
import _ba
|
||||
from ba._enums import TimeType, TimeFormat, SpecialChar, UIScale
|
||||
from ba._generated.enums import TimeType, TimeFormat, SpecialChar, UIScale
|
||||
from ba._error import ActivityNotFoundError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -301,6 +301,7 @@ def timestring(timeval: float,
|
|||
|
||||
# We add seconds if its non-zero *or* we haven't added anything else.
|
||||
if centi:
|
||||
# pylint: disable=consider-using-f-string
|
||||
sval = (timeval / 1000.0 % 60.0)
|
||||
if sval >= 0.005 or not bits:
|
||||
bits.append('${S}')
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_general.py
vendored
2
dist/ba_data/python/ba/_general.py
vendored
|
|
@ -13,7 +13,7 @@ from typing import TYPE_CHECKING, TypeVar, Protocol
|
|||
from efro.terminal import Clr
|
||||
import _ba
|
||||
from ba._error import print_error, print_exception
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from types import FrameType
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_generated/__init__.py
vendored
Normal file
2
dist/ba_data/python/ba/_generated/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
BIN
dist/ba_data/python/ba/_generated/__pycache__/__init__.cpython-38.opt-1.pyc
vendored
Normal file
BIN
dist/ba_data/python/ba/_generated/__pycache__/__init__.cpython-38.opt-1.pyc
vendored
Normal file
Binary file not shown.
BIN
dist/ba_data/python/ba/_generated/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
BIN
dist/ba_data/python/ba/_generated/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
dist/ba_data/python/ba/_generated/__pycache__/enums.cpython-38.opt-1.pyc
vendored
Normal file
BIN
dist/ba_data/python/ba/_generated/__pycache__/enums.cpython-38.opt-1.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
198
dist/ba_data/python/ba/_generated/enums.py
vendored
Normal file
198
dist/ba_data/python/ba/_generated/enums.py
vendored
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
"""Enum vals generated by batools.pythonenumsmodule; do not edit by hand."""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class InputType(Enum):
|
||||
"""Types of input a controller can send to the game.
|
||||
|
||||
Category: Enums
|
||||
|
||||
"""
|
||||
UP_DOWN = 2
|
||||
LEFT_RIGHT = 3
|
||||
JUMP_PRESS = 4
|
||||
JUMP_RELEASE = 5
|
||||
PUNCH_PRESS = 6
|
||||
PUNCH_RELEASE = 7
|
||||
BOMB_PRESS = 8
|
||||
BOMB_RELEASE = 9
|
||||
PICK_UP_PRESS = 10
|
||||
PICK_UP_RELEASE = 11
|
||||
RUN = 12
|
||||
FLY_PRESS = 13
|
||||
FLY_RELEASE = 14
|
||||
START_PRESS = 15
|
||||
START_RELEASE = 16
|
||||
HOLD_POSITION_PRESS = 17
|
||||
HOLD_POSITION_RELEASE = 18
|
||||
LEFT_PRESS = 19
|
||||
LEFT_RELEASE = 20
|
||||
RIGHT_PRESS = 21
|
||||
RIGHT_RELEASE = 22
|
||||
UP_PRESS = 23
|
||||
UP_RELEASE = 24
|
||||
DOWN_PRESS = 25
|
||||
DOWN_RELEASE = 26
|
||||
|
||||
|
||||
class UIScale(Enum):
|
||||
"""The overall scale the UI is being rendered for. Note that this is
|
||||
independent of pixel resolution. For example, a phone and a desktop PC
|
||||
might render the game at similar pixel resolutions but the size they
|
||||
display content at will vary significantly.
|
||||
|
||||
Category: Enums
|
||||
|
||||
'large' is used for devices such as desktop PCs where fine details can
|
||||
be clearly seen. UI elements are generally smaller on the screen
|
||||
and more content can be seen at once.
|
||||
|
||||
'medium' is used for devices such as tablets, TVs, or VR headsets.
|
||||
This mode strikes a balance between clean readability and amount of
|
||||
content visible.
|
||||
|
||||
'small' is used primarily for phones or other small devices where
|
||||
content needs to be presented as large and clear in order to remain
|
||||
readable from an average distance.
|
||||
"""
|
||||
LARGE = 0
|
||||
MEDIUM = 1
|
||||
SMALL = 2
|
||||
|
||||
|
||||
class TimeType(Enum):
|
||||
"""Specifies the type of time for various operations to target/use.
|
||||
|
||||
Category: Enums
|
||||
|
||||
'sim' time is the local simulation time for an activity or session.
|
||||
It can proceed at different rates depending on game speed, stops
|
||||
for pauses, etc.
|
||||
|
||||
'base' is the baseline time for an activity or session. It proceeds
|
||||
consistently regardless of game speed or pausing, but may stop during
|
||||
occurrences such as network outages.
|
||||
|
||||
'real' time is mostly based on clock time, with a few exceptions. It may
|
||||
not advance while the app is backgrounded for instance. (the engine
|
||||
attempts to prevent single large time jumps from occurring)
|
||||
"""
|
||||
SIM = 0
|
||||
BASE = 1
|
||||
REAL = 2
|
||||
|
||||
|
||||
class TimeFormat(Enum):
|
||||
"""Specifies the format time values are provided in.
|
||||
|
||||
Category: Enums
|
||||
"""
|
||||
SECONDS = 0
|
||||
MILLISECONDS = 1
|
||||
|
||||
|
||||
class Permission(Enum):
|
||||
"""Permissions that can be requested from the OS.
|
||||
|
||||
Category: Enums
|
||||
"""
|
||||
STORAGE = 0
|
||||
|
||||
|
||||
class SpecialChar(Enum):
|
||||
"""Special characters the game can print.
|
||||
|
||||
Category: Enums
|
||||
"""
|
||||
DOWN_ARROW = 0
|
||||
UP_ARROW = 1
|
||||
LEFT_ARROW = 2
|
||||
RIGHT_ARROW = 3
|
||||
TOP_BUTTON = 4
|
||||
LEFT_BUTTON = 5
|
||||
RIGHT_BUTTON = 6
|
||||
BOTTOM_BUTTON = 7
|
||||
DELETE = 8
|
||||
SHIFT = 9
|
||||
BACK = 10
|
||||
LOGO_FLAT = 11
|
||||
REWIND_BUTTON = 12
|
||||
PLAY_PAUSE_BUTTON = 13
|
||||
FAST_FORWARD_BUTTON = 14
|
||||
DPAD_CENTER_BUTTON = 15
|
||||
OUYA_BUTTON_O = 16
|
||||
OUYA_BUTTON_U = 17
|
||||
OUYA_BUTTON_Y = 18
|
||||
OUYA_BUTTON_A = 19
|
||||
OUYA_LOGO = 20
|
||||
LOGO = 21
|
||||
TICKET = 22
|
||||
GOOGLE_PLAY_GAMES_LOGO = 23
|
||||
GAME_CENTER_LOGO = 24
|
||||
DICE_BUTTON1 = 25
|
||||
DICE_BUTTON2 = 26
|
||||
DICE_BUTTON3 = 27
|
||||
DICE_BUTTON4 = 28
|
||||
GAME_CIRCLE_LOGO = 29
|
||||
PARTY_ICON = 30
|
||||
TEST_ACCOUNT = 31
|
||||
TICKET_BACKING = 32
|
||||
TROPHY1 = 33
|
||||
TROPHY2 = 34
|
||||
TROPHY3 = 35
|
||||
TROPHY0A = 36
|
||||
TROPHY0B = 37
|
||||
TROPHY4 = 38
|
||||
LOCAL_ACCOUNT = 39
|
||||
ALIBABA_LOGO = 40
|
||||
FLAG_UNITED_STATES = 41
|
||||
FLAG_MEXICO = 42
|
||||
FLAG_GERMANY = 43
|
||||
FLAG_BRAZIL = 44
|
||||
FLAG_RUSSIA = 45
|
||||
FLAG_CHINA = 46
|
||||
FLAG_UNITED_KINGDOM = 47
|
||||
FLAG_CANADA = 48
|
||||
FLAG_INDIA = 49
|
||||
FLAG_JAPAN = 50
|
||||
FLAG_FRANCE = 51
|
||||
FLAG_INDONESIA = 52
|
||||
FLAG_ITALY = 53
|
||||
FLAG_SOUTH_KOREA = 54
|
||||
FLAG_NETHERLANDS = 55
|
||||
FEDORA = 56
|
||||
HAL = 57
|
||||
CROWN = 58
|
||||
YIN_YANG = 59
|
||||
EYE_BALL = 60
|
||||
SKULL = 61
|
||||
HEART = 62
|
||||
DRAGON = 63
|
||||
HELMET = 64
|
||||
MUSHROOM = 65
|
||||
NINJA_STAR = 66
|
||||
VIKING_HELMET = 67
|
||||
MOON = 68
|
||||
SPIDER = 69
|
||||
FIREBALL = 70
|
||||
FLAG_UNITED_ARAB_EMIRATES = 71
|
||||
FLAG_QATAR = 72
|
||||
FLAG_EGYPT = 73
|
||||
FLAG_KUWAIT = 74
|
||||
FLAG_ALGERIA = 75
|
||||
FLAG_SAUDI_ARABIA = 76
|
||||
FLAG_MALAYSIA = 77
|
||||
FLAG_CZECH_REPUBLIC = 78
|
||||
FLAG_AUSTRALIA = 79
|
||||
FLAG_SINGAPORE = 80
|
||||
OCULUS_LOGO = 81
|
||||
STEAM_LOGO = 82
|
||||
NVIDIA_LOGO = 83
|
||||
FLAG_IRAN = 84
|
||||
FLAG_POLAND = 85
|
||||
FLAG_ARGENTINA = 86
|
||||
FLAG_PHILIPPINES = 87
|
||||
FLAG_CHILE = 88
|
||||
MIKIROG = 89
|
||||
52
dist/ba_data/python/ba/_hooks.py
vendored
52
dist/ba_data/python/ba/_hooks.py
vendored
|
|
@ -22,6 +22,19 @@ if TYPE_CHECKING:
|
|||
import ba
|
||||
|
||||
|
||||
def finish_bootstrapping() -> None:
|
||||
"""Do final bootstrapping related bits."""
|
||||
from ba._asyncio import setup_asyncio
|
||||
assert _ba.in_game_thread()
|
||||
|
||||
# Kick off our asyncio event handling, allowing us to use coroutines
|
||||
# in our game thread alongside our internal event handling.
|
||||
setup_asyncio()
|
||||
|
||||
# Ok, bootstrapping is done; time to get the show started.
|
||||
_ba.app.on_app_launch()
|
||||
|
||||
|
||||
def reset_to_main_menu() -> None:
|
||||
"""Reset the game to the main menu gracefully."""
|
||||
_ba.app.return_to_main_menu_session_gracefully()
|
||||
|
|
@ -316,9 +329,46 @@ def filter_chat_message(msg: str, client_id: int) -> Optional[str]:
|
|||
Should filter and return the string to be displayed, or return None
|
||||
to ignore the message.
|
||||
"""
|
||||
|
||||
return chooks.filter_chat_message(msg,client_id)
|
||||
|
||||
def get_not_allowed_to_kick() -> str:
|
||||
""" account_ids who cant start kick vote
|
||||
return comma (,) seperated account ids as string.
|
||||
"""
|
||||
return "pb-IF4TVWwZUQ==,pb-IF4T=="
|
||||
|
||||
def kick_vote_started(by:str,to:str) -> None:
|
||||
"""
|
||||
get account ids of who started kick vote for whom ,
|
||||
do what ever u want logging to files , whatever.
|
||||
"""
|
||||
print(by+">"+to)
|
||||
|
||||
def get_server_name() -> str:
|
||||
""" return what u want show for name of your host Id
|
||||
"""
|
||||
return "BCS"
|
||||
|
||||
def get_host_name() -> str:
|
||||
""" return device id of your host , to be view by id revealer
|
||||
"""
|
||||
return "bySmoothy"
|
||||
|
||||
def is_open_kick_vote() -> bool:
|
||||
""" return True if want to use transparent kick vote system , to make kick vote starter name public .
|
||||
or return False if want to use old default kick vote sys.
|
||||
"""
|
||||
return True
|
||||
|
||||
def on_kicked(account_id:str) -> None:
|
||||
""" oh damm ..this player kicked by votes , no one likes him :( , 2 min silence sleep(1000*60*2)
|
||||
"""
|
||||
print(account_id+" kicked ...sad")
|
||||
|
||||
def on_kick_vote_end() -> None:
|
||||
""" kick vote terminated , either player left the server , or time over
|
||||
"""
|
||||
print("kick vote end")
|
||||
|
||||
def local_chat_message(msg: str) -> None:
|
||||
if (_ba.app.ui.party_window is not None
|
||||
|
|
|
|||
8
dist/ba_data/python/ba/_language.py
vendored
8
dist/ba_data/python/ba/_language.py
vendored
|
|
@ -37,7 +37,7 @@ class LanguageSubsystem:
|
|||
# We don't yet support full unicode display on windows or linux :-(.
|
||||
if (language in {
|
||||
'Chinese', 'ChineseTraditional', 'Persian', 'Korean', 'Arabic',
|
||||
'Hindi', 'Vietnamese'
|
||||
'Hindi', 'Vietnamese', 'Thai'
|
||||
} and not _ba.can_display_full_unicode()):
|
||||
return False
|
||||
return True
|
||||
|
|
@ -79,6 +79,7 @@ class LanguageSubsystem:
|
|||
'ar': 'Arabic',
|
||||
'zh': 'Chinese',
|
||||
'tr': 'Turkish',
|
||||
'th': 'Thai',
|
||||
'id': 'Indonesian',
|
||||
'sr': 'Serbian',
|
||||
'uk': 'Ukrainian',
|
||||
|
|
@ -161,7 +162,8 @@ class LanguageSubsystem:
|
|||
else:
|
||||
switched = False
|
||||
|
||||
with open('ba_data/data/languages/english.json') as infile:
|
||||
with open('ba_data/data/languages/english.json',
|
||||
encoding='utf-8') as infile:
|
||||
lenglishvalues = json.loads(infile.read())
|
||||
|
||||
# None implies default.
|
||||
|
|
@ -173,7 +175,7 @@ class LanguageSubsystem:
|
|||
else:
|
||||
lmodfile = 'ba_data/data/languages/' + language.lower(
|
||||
) + '.json'
|
||||
with open(lmodfile) as infile:
|
||||
with open(lmodfile, encoding='utf-8') as infile:
|
||||
lmodvalues = json.loads(infile.read())
|
||||
except Exception:
|
||||
from ba import _error
|
||||
|
|
|
|||
4
dist/ba_data/python/ba/_level.py
vendored
4
dist/ba_data/python/ba/_level.py
vendored
|
|
@ -36,6 +36,10 @@ class Level:
|
|||
self._index: Optional[int] = None
|
||||
self._score_version_string: Optional[str] = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
cls = type(self)
|
||||
return f"<{cls.__module__}.{cls.__name__} '{self._name}'>"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""The unique name for this Level."""
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_lobby.py
vendored
2
dist/ba_data/python/ba/_lobby.py
vendored
|
|
@ -12,7 +12,7 @@ import _ba
|
|||
from ba._error import print_exception, print_error, NotFoundError
|
||||
from ba._gameutils import animate, animate_array
|
||||
from ba._language import Lstr
|
||||
from ba._enums import SpecialChar, InputType
|
||||
from ba._generated.enums import SpecialChar, InputType
|
||||
from ba._profile import get_player_profile_colors
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_map.py
vendored
2
dist/ba_data/python/ba/_map.py
vendored
|
|
@ -218,7 +218,7 @@ class Map(Actor):
|
|||
self.hg=ba.NodeActor(
|
||||
_ba.newnode('text',
|
||||
attrs={
|
||||
'text': "Smoothy Build\n v1.2",
|
||||
'text': "BCS Build\n v1.3",
|
||||
|
||||
'flatness': 1.0,
|
||||
'h_align': 'center',
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_meta.py
vendored
2
dist/ba_data/python/ba/_meta.py
vendored
|
|
@ -278,7 +278,7 @@ class DirectoryScan:
|
|||
else:
|
||||
fpath = pathlib.Path(moduledir, subpath, '__init__.py')
|
||||
ispackage = True
|
||||
with fpath.open() as infile:
|
||||
with fpath.open(encoding='utf-8') as infile:
|
||||
flines = infile.readlines()
|
||||
meta_lines = {
|
||||
lnum: l[1:].split()
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_net.py
vendored
2
dist/ba_data/python/ba/_net.py
vendored
|
|
@ -102,7 +102,7 @@ class MasterServerCallThread(threading.Thread):
|
|||
import urllib.error
|
||||
import json
|
||||
|
||||
from efro.net import is_urllib_network_error
|
||||
from efro.error import is_urllib_network_error
|
||||
from ba import _general
|
||||
try:
|
||||
self._data = _general.utf8_all(self._data)
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_profile.py
vendored
2
dist/ba_data/python/ba/_profile.py
vendored
|
|
@ -30,7 +30,7 @@ def get_player_profile_icon(profilename: str) -> str:
|
|||
|
||||
(non-account profiles only)
|
||||
"""
|
||||
from ba._enums import SpecialChar
|
||||
from ba._generated.enums import SpecialChar
|
||||
|
||||
appconfig = _ba.app.config
|
||||
icon: str
|
||||
|
|
|
|||
13
dist/ba_data/python/ba/_servermode.py
vendored
13
dist/ba_data/python/ba/_servermode.py
vendored
|
|
@ -13,9 +13,10 @@ from bacommon.servermanager import (ServerCommand, StartServerModeCommand,
|
|||
ChatMessageCommand, ScreenMessageCommand,
|
||||
ClientListCommand, KickCommand)
|
||||
import _ba
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
from ba._freeforallsession import FreeForAllSession
|
||||
from ba._dualteamsession import DualTeamSession
|
||||
from ba._coopsession import CoopSession
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional, Dict, Any, Type
|
||||
|
|
@ -289,11 +290,14 @@ class ServerController:
|
|||
return FreeForAllSession
|
||||
if self._config.session_type == 'teams':
|
||||
return DualTeamSession
|
||||
if self._config.session_type == 'coop':
|
||||
return CoopSession
|
||||
raise RuntimeError(
|
||||
f'Invalid session_type: "{self._config.session_type}"')
|
||||
|
||||
def _launch_server_session(self) -> None:
|
||||
"""Kick off a host-session based on the current server config."""
|
||||
# pylint: disable=too-many-branches
|
||||
app = _ba.app
|
||||
appcfg = app.config
|
||||
sessiontype = self._get_session_type()
|
||||
|
|
@ -311,6 +315,8 @@ class ServerController:
|
|||
ptypename = 'Free-for-All'
|
||||
elif sessiontype is DualTeamSession:
|
||||
ptypename = 'Team Tournament'
|
||||
elif sessiontype is CoopSession:
|
||||
ptypename = 'Coop'
|
||||
else:
|
||||
raise RuntimeError(f'Unknown session type {sessiontype}')
|
||||
|
||||
|
|
@ -340,6 +346,11 @@ class ServerController:
|
|||
appcfg['Team Tournament Playlist Selection'] = self._playlist_name
|
||||
appcfg['Team Tournament Playlist Randomize'] = (
|
||||
self._config.playlist_shuffle)
|
||||
elif sessiontype is CoopSession:
|
||||
app.coop_session_args = {
|
||||
'campaign': self._config.coop_campaign,
|
||||
'level': self._config.coop_level,
|
||||
}
|
||||
else:
|
||||
raise RuntimeError(f'Unknown session type {sessiontype}')
|
||||
|
||||
|
|
|
|||
30
dist/ba_data/python/ba/_session.py
vendored
30
dist/ba_data/python/ba/_session.py
vendored
|
|
@ -63,10 +63,6 @@ class Session:
|
|||
team instead of their own profile colors. This only applies if
|
||||
use_teams is enabled.
|
||||
|
||||
allow_mid_activity_joins
|
||||
Whether players should be allowed to join in the middle of
|
||||
activities.
|
||||
|
||||
customdata
|
||||
A shared dictionary for objects to use as storage on this session.
|
||||
Ensure that keys here are unique to avoid collisions.
|
||||
|
|
@ -74,7 +70,6 @@ class Session:
|
|||
"""
|
||||
use_teams: bool = False
|
||||
use_team_colors: bool = True
|
||||
allow_mid_activity_joins: bool = True
|
||||
|
||||
# Note: even though these are instance vars, we annotate them at the
|
||||
# class level so that docs generation can access their types.
|
||||
|
|
@ -210,18 +205,26 @@ class Session:
|
|||
raise NodeNotFoundError()
|
||||
return node
|
||||
|
||||
def should_allow_mid_activity_joins(self, activity: ba.Activity) -> bool:
|
||||
"""Ask ourself if we should allow joins during an Activity.
|
||||
|
||||
Note that for a join to be allowed, both the Session and Activity
|
||||
have to be ok with it (via this function and the
|
||||
Activity.allow_mid_activity_joins property.
|
||||
"""
|
||||
del activity # Unused.
|
||||
return True
|
||||
|
||||
def on_player_request(self, player: ba.SessionPlayer) -> bool:
|
||||
"""Called when a new ba.Player wants to join the Session.
|
||||
|
||||
This should return True or False to accept/reject.
|
||||
"""
|
||||
from tools import whitelist
|
||||
whitelist.handle_player_request(player)
|
||||
|
||||
# Limit player counts *unless* we're in a stress test.
|
||||
if _ba.app.stress_test_reset_timer is None:
|
||||
|
||||
if len(self.sessionplayers) >= self.max_players:
|
||||
|
||||
# Print a rejection message *only* to the client trying to
|
||||
# join (prevents spamming everyone else in the game).
|
||||
_ba.playsound(_ba.getsound('error'))
|
||||
|
|
@ -278,7 +281,7 @@ class Session:
|
|||
assert isinstance(player, (Player, type(None)))
|
||||
|
||||
# Remove them from any current Activity.
|
||||
if activity is not None:
|
||||
if player is not None and activity is not None:
|
||||
if player in activity.players:
|
||||
activity.remove_player(sessionplayer)
|
||||
else:
|
||||
|
|
@ -335,7 +338,7 @@ class Session:
|
|||
def _launch_end_session_activity(self) -> None:
|
||||
"""(internal)"""
|
||||
from ba._activitytypes import EndSessionActivity
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
with _ba.Context(self):
|
||||
curtime = _ba.time(TimeType.REAL)
|
||||
if self._ending:
|
||||
|
|
@ -368,7 +371,7 @@ class Session:
|
|||
will replace the old.
|
||||
"""
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# Only pay attention if this is coming from our current activity.
|
||||
if activity is not self._activity_retained:
|
||||
|
|
@ -432,7 +435,7 @@ class Session:
|
|||
(on_transition_in, etc) to get it. (so you can't do
|
||||
session.setactivity(foo) and then ba.newnode() to add a node to foo)
|
||||
"""
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# Make sure we don't get called recursively.
|
||||
_rlock = self._SetActivityScopedLock(self)
|
||||
|
|
@ -658,7 +661,8 @@ class Session:
|
|||
# However, if we're not allowing mid-game joins, don't actually pass;
|
||||
# just announce the arrival and say they'll partake next round.
|
||||
if pass_to_activity:
|
||||
if not self.allow_mid_activity_joins:
|
||||
if not (activity.allow_mid_activity_joins
|
||||
and self.should_allow_mid_activity_joins(activity)):
|
||||
pass_to_activity = False
|
||||
with _ba.Context(self):
|
||||
_ba.screenmessage(
|
||||
|
|
|
|||
4
dist/ba_data/python/ba/_store.py
vendored
4
dist/ba_data/python/ba/_store.py
vendored
|
|
@ -61,7 +61,7 @@ def get_store_items() -> Dict[str, Dict]:
|
|||
(internal)
|
||||
"""
|
||||
# pylint: disable=cyclic-import
|
||||
from ba._enums import SpecialChar
|
||||
from ba._generated.enums import SpecialChar
|
||||
from bastd import maps
|
||||
if _ba.app.store_items is None:
|
||||
from bastd.game import ninjafight
|
||||
|
|
@ -440,7 +440,7 @@ def get_available_sale_time(tab: str) -> Optional[int]:
|
|||
# pylint: disable=too-many-locals
|
||||
try:
|
||||
import datetime
|
||||
from ba._enums import TimeType, TimeFormat
|
||||
from ba._generated.enums import TimeType, TimeFormat
|
||||
app = _ba.app
|
||||
sale_times: List[Optional[int]] = []
|
||||
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/_tournament.py
vendored
2
dist/ba_data/python/ba/_tournament.py
vendored
|
|
@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|||
def get_tournament_prize_strings(entry: Dict[str, Any]) -> List[str]:
|
||||
"""Given a tournament entry, return strings for its prize levels."""
|
||||
# pylint: disable=too-many-locals
|
||||
from ba._enums import SpecialChar
|
||||
from ba._generated.enums import SpecialChar
|
||||
from ba._gameutils import get_trophy_string
|
||||
range1 = entry.get('prizeRange1')
|
||||
range2 = entry.get('prizeRange2')
|
||||
|
|
|
|||
6
dist/ba_data/python/ba/_ui.py
vendored
6
dist/ba_data/python/ba/_ui.py
vendored
|
|
@ -7,7 +7,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING
|
||||
|
||||
import _ba
|
||||
from ba._enums import UIScale
|
||||
from ba._generated.enums import UIScale
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional, Dict, Any, Callable, List, Type
|
||||
|
|
@ -70,7 +70,7 @@ class UISubsystem:
|
|||
def on_app_launch(self) -> None:
|
||||
"""Should be run on app launch."""
|
||||
from ba.ui import UIController, ui_upkeep
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
|
||||
# IMPORTANT: If tweaking UI stuff, make sure it behaves for small,
|
||||
# medium, and large UI modes. (doesn't run off screen, etc).
|
||||
|
|
@ -107,7 +107,7 @@ class UISubsystem:
|
|||
def set_main_menu_window(self, window: ba.Widget) -> None:
|
||||
"""Set the current 'main' window, replacing any existing."""
|
||||
existing = self._main_menu_window
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
from inspect import currentframe, getframeinfo
|
||||
|
||||
# Let's grab the location where we were called from to report
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/macmusicapp.py
vendored
2
dist/ba_data/python/ba/macmusicapp.py
vendored
|
|
@ -69,7 +69,7 @@ class _MacMusicAppThread(threading.Thread):
|
|||
"""Run the Music.app thread."""
|
||||
from ba._general import Call
|
||||
from ba._language import Lstr
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
_ba.set_thread_name('BA_MacMusicAppThread')
|
||||
_ba.mac_music_app_init()
|
||||
|
||||
|
|
|
|||
4
dist/ba_data/python/ba/modutils.py
vendored
4
dist/ba_data/python/ba/modutils.py
vendored
|
|
@ -40,7 +40,7 @@ def get_human_readable_user_scripts_path() -> str:
|
|||
def _request_storage_permission() -> bool:
|
||||
"""If needed, requests storage permission from the user (& return true)."""
|
||||
from ba._language import Lstr
|
||||
from ba._enums import Permission
|
||||
from ba._generated.enums import Permission
|
||||
if not _ba.have_permission(Permission.STORAGE):
|
||||
_ba.playsound(_ba.getsound('error'))
|
||||
_ba.screenmessage(Lstr(resource='storagePermissionAccessText'),
|
||||
|
|
@ -73,7 +73,7 @@ def show_user_scripts() -> None:
|
|||
usd: Optional[str] = app.python_directory_user
|
||||
if usd is not None and os.path.isdir(usd):
|
||||
file_name = usd + '/about_this_folder.txt'
|
||||
with open(file_name, 'w') as outfile:
|
||||
with open(file_name, 'w', encoding='utf-8') as outfile:
|
||||
outfile.write('You can drop files in here to mod the game.'
|
||||
' See settings/advanced'
|
||||
' in the game for more info.')
|
||||
|
|
|
|||
2
dist/ba_data/python/ba/ui/__init__.py
vendored
2
dist/ba_data/python/ba/ui/__init__.py
vendored
|
|
@ -10,7 +10,7 @@ from dataclasses import dataclass
|
|||
from typing import TYPE_CHECKING, cast, Type
|
||||
|
||||
import _ba
|
||||
from ba._enums import TimeType
|
||||
from ba._generated.enums import TimeType
|
||||
from ba._general import print_active_refs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue