baplus

Closed-source bits of ballistica.

This code concerns sensitive things like accounts and master-server communication so the native C++ parts of it remain closed. Native precompiled static libraries of this portion are provided for those who want to compile the rest of the engine, and a fully open-source engine can also be built by removing this 'plus' feature-set.

 1# Released under the MIT License. See LICENSE for details.
 2#
 3"""Closed-source bits of ballistica.
 4
 5This code concerns sensitive things like accounts and master-server
 6communication so the native C++ parts of it remain closed. Native
 7precompiled static libraries of this portion are provided for those who
 8want to compile the rest of the engine, and a fully open-source engine
 9can also be built by removing this 'plus' feature-set.
10"""
11
12from __future__ import annotations
13
14# Note: there's not much here.
15# All comms with this feature-set should go through app.plus.
16
17import logging
18
19from baplus._subsystem import PlusSubsystem
20
21__all__ = [
22    'PlusSubsystem',
23]
24
25# Sanity check: we want to keep ballistica's dependencies and
26# bootstrapping order clearly defined; let's check a few particular
27# modules to make sure they never directly or indirectly import us
28# before their own execs complete.
29if __debug__:
30    for _mdl in 'babase', '_babase':
31        if not hasattr(__import__(_mdl), '_REACHED_END_OF_MODULE'):
32            logging.warning(
33                '%s was imported before %s finished importing;'
34                ' should not happen.',
35                __name__,
36                _mdl,
37            )
class PlusSubsystem(babase._appsubsystem.AppSubsystem):
 18class PlusSubsystem(AppSubsystem):
 19    """Subsystem for plus functionality in the app.
 20
 21    The single shared instance of this app can be accessed at
 22    babase.app.plus. Note that it is possible for this to be None if the
 23    plus package is not present, and code should handle that case
 24    gracefully.
 25    """
 26
 27    # pylint: disable=too-many-public-methods
 28
 29    # Note: this is basically just a wrapper around _baplus for
 30    # type-checking purposes. Maybe there's some smart way we could skip
 31    # the overhead of this wrapper at runtime.
 32
 33    accounts: AccountV2Subsystem
 34    cloud: CloudSubsystem
 35
 36    def on_app_loading(self) -> None:
 37        _baplus.on_app_loading()
 38        self.accounts.on_app_loading()
 39
 40    # noinspection PyUnresolvedReferences
 41    @staticmethod
 42    def add_v1_account_transaction(
 43        transaction: dict, callback: Callable | None = None
 44    ) -> None:
 45        """(internal)"""
 46        return _baplus.add_v1_account_transaction(transaction, callback)
 47
 48    @staticmethod
 49    def game_service_has_leaderboard(game: str, config: str) -> bool:
 50        """(internal)
 51
 52        Given a game and config string, returns whether there is a leaderboard
 53        for it on the game service.
 54        """
 55        return _baplus.game_service_has_leaderboard(game, config)
 56
 57    @staticmethod
 58    def get_master_server_address(source: int = -1, version: int = 1) -> str:
 59        """(internal)
 60
 61        Return the address of the master server.
 62        """
 63        return _baplus.get_master_server_address(source, version)
 64
 65    @staticmethod
 66    def get_news_show() -> str:
 67        """(internal)"""
 68        return _baplus.get_news_show()
 69
 70    @staticmethod
 71    def get_price(item: str) -> str | None:
 72        """(internal)"""
 73        return _baplus.get_price(item)
 74
 75    @staticmethod
 76    def get_purchased(item: str) -> bool:
 77        """(internal)"""
 78        return _baplus.get_purchased(item)
 79
 80    @staticmethod
 81    def get_purchases_state() -> int:
 82        """(internal)"""
 83        return _baplus.get_purchases_state()
 84
 85    @staticmethod
 86    def get_v1_account_display_string(full: bool = True) -> str:
 87        """(internal)"""
 88        return _baplus.get_v1_account_display_string(full)
 89
 90    @staticmethod
 91    def get_v1_account_misc_read_val(name: str, default_value: Any) -> Any:
 92        """(internal)"""
 93        return _baplus.get_v1_account_misc_read_val(name, default_value)
 94
 95    @staticmethod
 96    def get_v1_account_misc_read_val_2(name: str, default_value: Any) -> Any:
 97        """(internal)"""
 98        return _baplus.get_v1_account_misc_read_val_2(name, default_value)
 99
100    @staticmethod
101    def get_v1_account_misc_val(name: str, default_value: Any) -> Any:
102        """(internal)"""
103        return _baplus.get_v1_account_misc_val(name, default_value)
104
105    @staticmethod
106    def get_v1_account_name() -> str:
107        """(internal)"""
108        return _baplus.get_v1_account_name()
109
110    @staticmethod
111    def get_v1_account_public_login_id() -> str | None:
112        """(internal)"""
113        return _baplus.get_v1_account_public_login_id()
114
115    @staticmethod
116    def get_v1_account_state() -> str:
117        """(internal)"""
118        return _baplus.get_v1_account_state()
119
120    @staticmethod
121    def get_v1_account_state_num() -> int:
122        """(internal)"""
123        return _baplus.get_v1_account_state_num()
124
125    @staticmethod
126    def get_v1_account_ticket_count() -> int:
127        """(internal)
128
129        Returns the number of tickets for the current account.
130        """
131        return _baplus.get_v1_account_ticket_count()
132
133    @staticmethod
134    def get_v1_account_type() -> str:
135        """(internal)"""
136        return _baplus.get_v1_account_type()
137
138    @staticmethod
139    def get_v2_fleet() -> str:
140        """(internal)"""
141        return _baplus.get_v2_fleet()
142
143    @staticmethod
144    def have_outstanding_v1_account_transactions() -> bool:
145        """(internal)"""
146        return _baplus.have_outstanding_v1_account_transactions()
147
148    @staticmethod
149    def in_game_purchase(item: str, price: int) -> None:
150        """(internal)"""
151        return _baplus.in_game_purchase(item, price)
152
153    @staticmethod
154    def is_blessed() -> bool:
155        """(internal)"""
156        return _baplus.is_blessed()
157
158    @staticmethod
159    def mark_config_dirty() -> None:
160        """(internal)
161
162        Category: General Utility Functions
163        """
164        return _baplus.mark_config_dirty()
165
166    @staticmethod
167    def power_ranking_query(callback: Callable, season: Any = None) -> None:
168        """(internal)"""
169        return _baplus.power_ranking_query(callback, season)
170
171    @staticmethod
172    def purchase(item: str) -> None:
173        """(internal)"""
174        return _baplus.purchase(item)
175
176    @staticmethod
177    def report_achievement(
178        achievement: str, pass_to_account: bool = True
179    ) -> None:
180        """(internal)"""
181        return _baplus.report_achievement(achievement, pass_to_account)
182
183    @staticmethod
184    def reset_achievements() -> None:
185        """(internal)"""
186        return _baplus.reset_achievements()
187
188    @staticmethod
189    def restore_purchases() -> None:
190        """(internal)"""
191        return _baplus.restore_purchases()
192
193    @staticmethod
194    def run_v1_account_transactions() -> None:
195        """(internal)"""
196        return _baplus.run_v1_account_transactions()
197
198    @staticmethod
199    def sign_in_v1(account_type: str) -> None:
200        """(internal)
201
202        Category: General Utility Functions
203        """
204        return _baplus.sign_in_v1(account_type)
205
206    @staticmethod
207    def sign_out_v1(v2_embedded: bool = False) -> None:
208        """(internal)
209
210        Category: General Utility Functions
211        """
212        return _baplus.sign_out_v1(v2_embedded)
213
214    @staticmethod
215    def submit_score(
216        game: str,
217        config: str,
218        name: Any,
219        score: int | None,
220        callback: Callable,
221        order: str = 'increasing',
222        tournament_id: str | None = None,
223        score_type: str = 'points',
224        campaign: str | None = None,
225        level: str | None = None,
226    ) -> None:
227        """(internal)
228
229        Submit a score to the server; callback will be called with the results.
230        As a courtesy, please don't send fake scores to the server. I'd prefer
231        to devote my time to improving the game instead of trying to make the
232        score server more mischief-proof.
233        """
234        return _baplus.submit_score(
235            game,
236            config,
237            name,
238            score,
239            callback,
240            order,
241            tournament_id,
242            score_type,
243            campaign,
244            level,
245        )
246
247    @staticmethod
248    def tournament_query(
249        callback: Callable[[dict | None], None], args: dict
250    ) -> None:
251        """(internal)"""
252        return _baplus.tournament_query(callback, args)

Subsystem for plus functionality in the app.

The single shared instance of this app can be accessed at babase.app.plus. Note that it is possible for this to be None if the plus package is not present, and code should handle that case gracefully.

accounts: babase._accountv2.AccountV2Subsystem
cloud: babase._cloud.CloudSubsystem
def on_app_loading(self) -> None:
36    def on_app_loading(self) -> None:
37        _baplus.on_app_loading()
38        self.accounts.on_app_loading()

Called when the app reaches the loading state.

Note that subsystems created after the app switches to the loading state will not receive this callback. Subsystems created by plugins are an example of this.

Inherited Members
babase._appsubsystem.AppSubsystem
on_app_running
on_app_pause
on_app_resume
on_app_shutdown
on_app_shutdown_complete
do_apply_app_config