2023-07-29 13:18:21 +05:30
# Made by your friend: Freaku
2022-07-15 14:55:58 +05:30
2025-06-26 11:46:12 +05:30
__version__ = ' 1.7.44+ '
2024-08-14 18:43:14 +05:30
# Starting versioning of terminal.py henceforth,
# since many users complained problems which was actually caused due to them using an older version of us.
2022-02-06 11:45:13 +05:30
2022-03-16 08:57:34 +05:30
# Defines a simple plugin that allows you to:
2022-09-27 16:40:27 +05:30
### See any errors of your mods (if present) in folder BombSquad/console/logs.txt
2024-08-14 18:43:14 +05:30
### Export logs (current & logs generated in previous launch too)
2022-09-27 16:40:27 +05:30
### Get config contents
2023-08-26 22:44:06 +05:30
### Create/Delete system scripts
2022-09-27 16:40:27 +05:30
### Get 3D co-ordinate points in any Map!
2023-08-26 22:28:03 +05:30
### Get internal packages
2022-02-06 11:45:13 +05:30
2022-03-16 08:57:34 +05:30
2022-07-15 14:55:58 +05:30
# NOTE: Please perform the activities to log, if its a gamemode pls open and play it and then see logs. If its a window please touch buttons and then see logs
# and so on according to the mod you're working...
2022-03-16 08:57:34 +05:30
2022-07-15 14:55:58 +05:30
#Join BCS:
2022-03-16 08:57:34 +05:30
# https://discord.gg/ucyaesh
2022-07-15 14:55:58 +05:30
#My GitHub:
# https://github.com/Freaku17/BombSquad-Mods-byFreaku
2022-03-16 08:57:34 +05:30
2022-02-06 11:45:13 +05:30
########## INDEX ##########
'''
- Must READ
- For beginners
2022-03-16 08:57:34 +05:30
'''
2022-02-06 11:45:13 +05:30
# ----- MUST READ -----
'''
2022-03-16 08:57:34 +05:30
# I hope you know Python Programming Language and have seen Bombsquad's API, avaiable at
2022-02-06 11:45:13 +05:30
# https://ballistica.net/wiki
# else... its still fine :)
2022-03-16 08:57:34 +05:30
# Python is easiest language, hardly will take 1 week to learn (See YouTube tutorials)
2022-02-06 11:45:13 +05:30
# This mod is *genuinely* for Mobile Modders,
# in PC you can directly get these Terminal Errors in console.
# but sadly on mobile there's no way to view console.
2022-09-27 16:40:27 +05:30
# We can alternatively, use https://tools.ballistica.net/devices
# but it only works on V2 accounts (and if you link your GooglePlay and V2, and login with GooglePlay... it won't work)
2022-02-06 11:45:13 +05:30
# This is helpful for new Modders (who don't use PC)
# Also I'll ***HIGHLY*** suggest to not use this when other mods are installed
# As a TONS of other mods includes errors (which aren't fixed)
# Happy coding! 🔥
'''
# ----- For beginners -----
'''
2023-08-26 22:44:06 +05:30
# Use system_scripts in Plugins
2022-03-16 08:57:34 +05:30
# and a Code Editor app (on Play Store)
2022-02-06 11:45:13 +05:30
2022-09-27 16:40:27 +05:30
# Then start playing (editing) those internal .py files
# Incase you face a black screen on launch (you made an error while editing those sys files)
# Delete the sys folder of folder Bombsquad/sys/{version} and re-open game
2022-03-16 08:57:34 +05:30
'''
2022-02-06 11:45:13 +05:30
2022-09-27 16:40:27 +05:30
# Sometimes you need someone for help
2022-07-15 14:55:58 +05:30
# I would suggest to join BCS: A lovely discord server (link at top)
2022-02-06 11:45:13 +05:30
2022-07-15 14:55:58 +05:30
# Aimed 4 Android modders!
2022-02-06 11:45:13 +05:30
2025-02-08 01:39:31 +05:30
# ba_meta require api 9
2022-03-16 08:57:34 +05:30
2023-08-26 22:28:03 +05:30
import _babase
import babase
import baenv
import os
2023-07-15 18:15:48 +05:30
import bascenev1 as bs
2023-08-26 22:28:03 +05:30
import bauiv1 as bui
2025-02-08 01:39:31 +05:30
from efro . logging import LogLevel
2023-08-26 22:28:03 +05:30
from bauiv1lib . fileselector import FileSelectorWindow
2024-08-14 18:43:14 +05:30
from bauiv1lib . confirm import ConfirmWindow
2024-02-05 01:39:03 +05:30
folder = _babase . app . env . python_directory_user + " /console/ "
2022-09-27 16:40:27 +05:30
log_post = folder + ' logs.txt '
2024-08-14 18:43:14 +05:30
previous_log_post = folder + ' logs (previous game launch).txt '
2022-09-27 16:40:27 +05:30
config_post = folder + ' config.txt '
2022-02-06 11:45:13 +05:30
def make_folder ( ) :
2024-08-14 18:43:14 +05:30
os . makedirs ( folder , exist_ok = True )
2022-02-06 11:45:13 +05:30
2022-09-27 16:40:27 +05:30
def make_config ( entry ) :
with open ( config_post , ' w+ ' ) as e :
e . write ( entry )
2022-03-16 08:57:34 +05:30
e . close ( )
2022-09-27 16:40:27 +05:30
def dump_cache_logs ( ) :
# Dumps all cache logs (including DEBUG ones)
2023-07-29 13:18:21 +05:30
for entry in baenv . _EnvGlobals . get ( ) . config . log_handler . get_cached ( ) . entries :
2022-09-27 16:40:27 +05:30
write_logs ( entry . message )
def make_logs ( entry ) :
if entry . level . value > = LogLevel . WARNING . value or entry . name in ( ' stdout ' , ' stderr ' ) :
write_logs ( entry . message )
def write_logs ( log ) :
print ( log , file = open ( log_post , ' a+ ' , encoding = ' utf-8 ' ) )
2022-03-16 08:57:34 +05:30
2023-03-05 10:00:49 +05:30
def make_sys_wordaround ( path ) :
2023-01-15 14:58:17 +05:30
# With continued increasing restrictions of Android,
# it is not possible to "view" in-game folders copied to an external path.
# Luckily we are still able to write files.
# So as a "workaround" we create a zip of in-game folders and unzip them :D
from shutil import make_archive , unpack_archive , rmtree
2024-02-05 01:39:03 +05:30
sys_zip = make_archive ( folder + ' sys_zip ' , ' zip ' , _babase . app . env . python_directory_app )
2023-01-15 14:58:17 +05:30
unpack_archive ( sys_zip , path )
2023-08-26 22:28:03 +05:30
os . remove ( sys_zip )
2023-01-15 14:58:17 +05:30
# We also need to delete all `__pycache__` folders
for root , dirs , files in os . walk ( path ) :
if ' __pycache__ ' in dirs :
pycache_folder = os . path . join ( root , ' __pycache__ ' )
rmtree ( pycache_folder )
2023-08-26 22:28:03 +05:30
if babase . app . classic . platform == ' android ' :
if ' /0/ ' in path :
path = path . split ( ' /0/ ' ) [ 1 ]
bui . screenmessage ( f ' Scripts created at { path } ' , color = ( 0 , 1 , 0 ) )
bui . screenmessage ( ' Restart BombSquad to use them ' , color = ( 0 , 1 , 0 ) )
2023-01-15 14:58:17 +05:30
2022-03-16 08:57:34 +05:30
def yeet_sys ( ) :
2023-08-26 22:28:03 +05:30
import babase . modutils as utils
utils . delete_user_system_scripts ( )
2022-07-15 14:55:58 +05:30
2023-08-26 22:28:03 +05:30
def copy_internal_packages ( path ) :
copy_dir = folder + path . split ( ' // ' ) [ 1 ]
from shutil import make_archive , unpack_archive , rmtree
content_zip = make_archive ( folder + ' content_zip ' , ' zip ' , path )
unpack_archive ( content_zip , copy_dir )
os . remove ( content_zip )
bui . screenmessage ( ' Copying completed! ' )
2022-07-15 14:55:58 +05:30
2024-08-14 18:43:14 +05:30
class reConfirmWindow ( ConfirmWindow ) :
def __init__ ( self , * args , path , * * kwargs ) :
super ( ) . __init__ ( * args , * * kwargs )
self . _path = path
def _ok ( self ) - > None :
if not self . root_widget :
return
bui . containerwidget (
edit = self . root_widget ,
transition = (
' out_left '
if self . _transition_out is None
else self . _transition_out
) ,
)
if self . _action is not None :
self . _action ( self . _path , create_subfolder = True )
def _cancel ( self ) - > None :
super ( ) . _cancel ( )
if self . _action is not None :
self . _action ( self . _path , create_subfolder = False )
2022-07-15 14:55:58 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2023-07-15 18:15:48 +05:30
class get_logs ( babase . Plugin ) :
2022-07-15 14:55:58 +05:30
def __init__ ( self ) :
2022-02-06 11:45:13 +05:30
make_folder ( )
2024-08-14 18:43:14 +05:30
if os . path . exists ( log_post ) :
os . rename ( log_post , previous_log_post )
2022-09-27 16:40:27 +05:30
open ( log_post , ' w+ ' ) . close ( )
dump_cache_logs ( )
2023-07-29 13:18:21 +05:30
baenv . _EnvGlobals . get ( ) . config . log_handler . add_callback ( make_logs )
2022-03-16 08:57:34 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2023-07-15 18:15:48 +05:30
class get_config ( babase . Plugin ) :
2022-07-15 14:55:58 +05:30
def __init__ ( self ) :
2022-09-27 16:40:27 +05:30
make_folder ( )
2024-02-05 01:39:03 +05:30
configs = babase . app . env . config_file_path
2022-09-27 16:40:27 +05:30
with open ( configs ) as f :
make_config ( f . read ( ) )
f . close ( )
2022-03-16 08:57:34 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2023-08-26 22:28:03 +05:30
class system_scripts ( babase . Plugin ) :
def has_settings_ui ( self ) :
return True
def show_settings_ui ( self , source_widget ) :
2024-08-14 18:43:14 +05:30
env = _babase . app . env
path = env . python_directory_user + ' /sys/ ' + env . engine_version + ' _ ' + str ( env . engine_build_number )
2023-08-26 22:28:03 +05:30
if not os . path . exists ( path ) :
# Old method:
# import babase.modutils as utils
# utils.create_user_system_scripts()
make_sys_wordaround ( path )
else :
yeet_sys ( )
2022-03-16 08:57:34 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2023-08-26 22:28:03 +05:30
class internal_packages ( babase . Plugin ) :
def has_settings_ui ( self ) :
return True
def show_settings_ui ( self , source_widget ) :
if babase . app . classic . platform != ' android ' :
bui . screenmessage ( ' Only for mobile users! ' )
return
internal_packages_path = ' /data/data/net.froemling.bombsquad/ '
2025-02-08 01:39:31 +05:30
babase . app . ui_v1 . get_main_window ( ) . main_window_replace (
FileSelectorWindow ( internal_packages_path ,
2023-08-26 22:28:03 +05:30
callback = self . start_copy_internal_packages ,
show_base_path = True ,
allow_folders = True )
2025-02-08 01:39:31 +05:30
)
2023-08-26 22:28:03 +05:30
def start_copy_internal_packages ( self , path ) :
if path :
2025-02-08 01:39:31 +05:30
babase . app . ui_v1 . get_main_window ( ) . main_window_back ( )
2023-08-26 22:28:03 +05:30
bui . screenmessage ( ' Copying to ' + ( folder if ' /0/ ' not in folder else folder . split ( ' /0/ ' ) [ 1 ] ) )
# To avoid freezing the game, we execute this in another thread
import threading
threading . Thread ( target = copy_internal_packages , args = ( path , ) ) . start ( )
2022-07-15 14:55:58 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2024-08-14 18:43:14 +05:30
class export_logs ( babase . Plugin ) :
def has_settings_ui ( self ) :
return True
def show_settings_ui ( self , source_widget ) :
default_directory = _babase . app . env . python_directory_user
if babase . app . classic . platform == ' android ' :
default_directory = ' /storage/emulated/0/Download/ '
reConfirmWindow ( height = 120 , width = 400 , text_scale = 5.5 ,
text = ' Create a separate BombSquad folder \n inside ' + default_directory + ' ? ' ,
ok_text = ' Yes, save to folder \n Download/BombSquad/ ' ,
cancel_text = ' No, save directly to \n folder Download/ ' ,
action = self . start_export_logs ,
path = default_directory )
return
2025-02-08 14:34:32 +05:30
babase . app . ui_v1 . get_main_window ( ) . main_window_replace (
FileSelectorWindow ( default_directory ,
2024-08-14 18:43:14 +05:30
callback = self . start_export_logs ,
show_base_path = True ,
allow_folders = True )
2025-02-08 14:34:32 +05:30
)
2024-08-14 18:43:14 +05:30
def start_export_logs ( self , path : str , create_subfolder : bool = False ) :
2025-02-08 14:34:32 +05:30
if path :
if babase . app . classic . platform != ' android ' :
babase . app . ui_v1 . get_main_window ( ) . main_window_back ( )
if create_subfolder :
path = path + ' BombSquad/ '
os . makedirs ( path , exist_ok = True )
if os . path . exists ( log_post ) :
with open ( path + ' /logs.txt ' , ' w+ ' ) as e :
e . write ( open ( log_post ) . read ( ) )
e . close ( )
bui . screenmessage ( ' logs.txt saved ' )
if os . path . exists ( previous_log_post ) :
with open ( path + ' /logs (previous game launch).txt ' , ' w+ ' ) as e :
e . write ( open ( previous_log_post ) . read ( ) )
e . close ( )
bui . screenmessage ( ' logs (previous game launch).txt saved ' )
2024-08-14 18:43:14 +05:30
2025-06-26 11:46:12 +05:30
# ba_meta export babase.Plugin
2024-08-14 18:43:14 +05:30
class version ( babase . Plugin ) :
def has_settings_ui ( self ) :
return True
def show_settings_ui ( self , source_widget ) :
bui . screenmessage ( ' Tested for bs version: ' + __version__ )
bui . screenmessage ( " If you ' re facing any errors, \n Update the plugin: https://github.com/Freaku17/BombSquad-Mods-byFreaku " )
return
2022-07-15 14:55:58 +05:30
2023-07-15 18:15:48 +05:30
class Player ( bs . Player [ ' Team ' ] ) :
2022-07-15 14:55:58 +05:30
""" Our player type for this game. """
2023-07-15 18:15:48 +05:30
class Team ( bs . Team [ Player ] ) :
2022-07-15 14:55:58 +05:30
""" Our team type for this game. """
2023-07-15 18:15:48 +05:30
# ba_meta export bascenev1.GameActivity
class Terminal_get3Dpoint ( bs . TeamGameActivity [ Player , Team ] ) :
2022-07-15 14:55:58 +05:30
name = ' 3D co-ordinate point '
2023-07-15 18:15:48 +05:30
available_settings = [ bs . BoolSetting ( ' Boxes ' , default = False ) , bs . BoolSetting ( ' Points ' , default = False ) ]
2022-07-15 14:55:58 +05:30
description = ' Get 3D co-ordinate point of ANY map! '
def __init__ ( self , settings : dict ) :
super ( ) . __init__ ( settings )
self . _boxes = settings . get ( ' Boxes ' , False )
self . _points = settings . get ( ' Points ' , False )
@classmethod
def supports_session_type ( cls , sessiontype ) :
2023-07-15 18:15:48 +05:30
return ( issubclass ( sessiontype , bs . DualTeamSession ) or issubclass ( sessiontype , bs . FreeForAllSession ) )
2022-07-15 14:55:58 +05:30
@classmethod
def get_supported_maps ( cls , sessiontype ) :
# Support every single map registered to the game...
maps = [ ]
2023-07-15 18:15:48 +05:30
for map in babase . app . classic . maps :
2022-07-15 14:55:58 +05:30
maps . append ( map )
return maps
def on_begin ( self ) :
super ( ) . on_begin ( )
if self . _boxes :
self . spawn_boxes ( )
if self . _points :
self . spawn_points ( )
def spawn_boxes ( self ) :
for box in self . map . defs . boxes :
box_pt = self . map . defs . boxes [ box ]
2023-07-15 18:15:48 +05:30
box_locator = bs . newnode ( ' locator ' , attrs = { ' shape ' : ' box ' , ' position ' : ( box_pt [ 0 ] , box_pt [ 1 ] , box_pt [ 2 ] ) , ' color ' : ( 1 , 1 , 0 ) , ' opacity ' : 1 , ' draw_beauty ' : True , ' additive ' : False , ' size ' : ( box_pt [ 6 ] , box_pt [ 7 ] , box_pt [ 8 ] ) } )
mnode = bs . newnode ( ' math ' , owner = box_locator , attrs = { ' input1 ' : ( 0 , 0 , 0 ) , ' operation ' : ' add ' } )
2022-07-15 14:55:58 +05:30
box_locator . connectattr ( ' position ' , mnode , ' input2 ' )
2023-07-15 18:15:48 +05:30
box_text = bs . newnode ( ' text ' , owner = box_locator , attrs = { ' text ' : box , ' in_world ' : True , ' shadow ' : 0 , ' flatness ' : 0 , ' color ' : ( 1 , 1 , 1 ) , ' scale ' : 0.01 , ' h_align ' : ' center ' } )
2022-07-15 14:55:58 +05:30
mnode . connectattr ( ' output ' , box_text , ' position ' )
def spawn_points ( self ) :
for point in self . map . defs . points :
display_pt = self . map . defs . points [ point ]
if len ( display_pt ) == 6 :
2023-07-15 18:15:48 +05:30
point_locator = bs . newnode ( ' locator ' , attrs = { ' shape ' : ' box ' , ' position ' : ( display_pt [ 0 ] , display_pt [ 1 ] , display_pt [ 2 ] ) , ' color ' : ( 1 , 1 , 0 ) , ' opacity ' : 1 , ' draw_beauty ' : True , ' additive ' : False , ' size ' : ( display_pt [ 3 ] , display_pt [ 4 ] , display_pt [ 5 ] ) } )
2022-07-15 14:55:58 +05:30
elif len ( display_pt ) == 3 :
2023-07-15 18:15:48 +05:30
point_locator = bs . newnode ( ' locator ' , attrs = { ' shape ' : ' circle ' , ' position ' : ( display_pt [ 0 ] , display_pt [ 1 ] , display_pt [ 2 ] ) , ' color ' : ( 1 , 1 , 0 ) , ' opacity ' : 1 , ' draw_beauty ' : True , ' additive ' : False , ' drawShadow ' : False , ' size ' : ( 0.4 , 0.4 , 0.4 ) } )
2022-07-15 14:55:58 +05:30
else :
print ( ' Invalid entry of; ' , point , ' values given: ' , display_pt )
continue
2023-07-15 18:15:48 +05:30
mnode = bs . newnode ( ' math ' , owner = point_locator , attrs = { ' input1 ' : ( 0 , 0 , 0 ) , ' operation ' : ' add ' } )
2022-07-15 14:55:58 +05:30
point_locator . connectattr ( ' position ' , mnode , ' input2 ' )
2023-07-15 18:15:48 +05:30
point_text = bs . newnode ( ' text ' , owner = point_locator , attrs = { ' text ' : point , ' in_world ' : True , ' shadow ' : 1.0 , ' flatness ' : 1.0 , ' color ' : ( 0 , 0 , 0 ) , ' scale ' : 0.01 , ' h_align ' : ' center ' } )
2022-07-15 14:55:58 +05:30
mnode . connectattr ( ' output ' , point_text , ' position ' )
def end_game ( self ) :
2023-07-15 18:15:48 +05:30
results = bs . GameResults ( )
2022-07-15 14:55:58 +05:30
for team in self . teams :
results . set_team_score ( team , team . score )
self . end ( results = results )
def handlemessage ( self , msg ) :
2023-07-15 18:15:48 +05:30
if isinstance ( msg , bs . _messages . PlayerDiedMessage ) :
2022-07-15 14:55:58 +05:30
self . respawn_player ( msg . getplayer ( self . playertype ) , 1 )
else :
return super ( ) . handlemessage ( msg )
2023-08-26 22:44:06 +05:30
return None