bombsquad-plugin-manager/plugins/utilities/share_replay.py

410 lines
14 KiB
Python
Raw Normal View History

2024-01-20 22:21:09 +03:00
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
2022-12-20 16:41:44 +05:30
"""
Plugin by LoupGarou a.k.a Loup/Soup
Discord ʟօʊքɢǟʀօʊ#3063
Share replays easily with your friends or have a backup
Exported replays are stored in replays folder which is inside mods folder
You can start sharing replays by opening the watch window and going to share replay tab
Feel free to let me know if you use this plugin,i love to hear that :)
Message me in discord if you find some bug
Use this code for your experiments or plugin but please dont rename this plugin and distribute with your name,don't do that,its bad'
"""
2024-01-20 22:21:09 +03:00
# ba_meta require api 8
2022-11-07 00:26:16 +05:30
from __future__ import annotations
from typing import TYPE_CHECKING, cast
if TYPE_CHECKING:
from typing import Any, Sequence, Callable, List, Dict, Tuple, Optional, Union
2022-11-07 19:58:27 +00:00
2022-12-20 11:14:11 +00:00
from os import listdir, mkdir, path, sep, remove
2022-11-07 19:58:27 +00:00
from shutil import copy, copytree
2022-11-06 21:24:27 +00:00
2024-01-20 22:21:09 +03:00
import babase
import bauiv1 as bui
import bascenev1 as bs
import _babase
from enum import Enum
2024-01-20 22:21:09 +03:00
from bauiv1lib.tabs import TabRow
from bauiv1lib.confirm import ConfirmWindow
from bauiv1lib.watch import WatchWindow
from bauiv1lib.popup import PopupWindow
2022-11-07 00:26:16 +05:30
2022-11-07 19:58:27 +00:00
2022-12-20 16:41:44 +05:30
title = "SHARE REPLAY"
2024-01-20 22:21:09 +03:00
internal_dir = _babase.get_replays_dir()+sep
external_dir = path.join(_babase.env()["python_directory_user"], "replays"+sep)
uiscale = bui.app.ui_v1.uiscale
2022-12-20 16:41:44 +05:30
# colors
pink = (1, 0.2, 0.8)
green = (0.4, 1, 0.4)
red = (1, 0, 0)
blue = (0.26, 0.65, 0.94)
blue_highlight = (0.4, 0.7, 1)
b_color = (0.6, 0.53, 0.63)
b_textcolor = (0.75, 0.7, 0.8)
2022-11-19 03:15:25 +00:00
2022-12-20 11:14:11 +00:00
2024-01-20 22:21:09 +03:00
def Print(*args, color=None):
2022-11-07 19:58:27 +00:00
out = ""
2022-11-07 00:26:16 +05:30
for arg in args:
2022-11-07 19:58:27 +00:00
a = str(arg)
2022-11-07 00:26:16 +05:30
out += a
2024-01-20 22:21:09 +03:00
bui.screenmessage(out, color=color)
2022-11-07 19:58:27 +00:00
2022-11-19 03:15:25 +00:00
2022-11-07 00:26:16 +05:30
def cprint(*args):
2022-11-07 19:58:27 +00:00
out = ""
2022-11-07 00:26:16 +05:30
for arg in args:
2022-11-07 19:58:27 +00:00
a = str(arg)
2022-11-07 00:26:16 +05:30
out += a
2024-01-20 22:21:09 +03:00
bs.chatmessage(out)
2022-11-06 21:24:27 +00:00
2022-11-19 03:15:25 +00:00
2022-11-08 01:27:06 +05:30
if not path.exists(external_dir):
2022-11-07 00:26:16 +05:30
mkdir(external_dir)
2022-11-07 19:58:27 +00:00
Print("You are ready to share replays", color=pink)
2022-12-20 16:41:44 +05:30
def override(cls: ClassType) -> Callable[[MethodType], MethodType]:
def decorator(newfunc: MethodType) -> MethodType:
funcname = newfunc.__code__.co_name
if hasattr(cls, funcname):
oldfunc = getattr(cls, funcname)
setattr(cls, f'_old_{funcname}', oldfunc)
setattr(cls, funcname, newfunc)
return newfunc
return decorator
class CommonUtilities:
def sync_confirmation(self):
ConfirmWindow(text="WARNING:\nreplays with same name in mods folder\n will be overwritten",
action=self.sync, cancel_is_selected=True)
def sync(self):
internal_list = listdir(internal_dir)
external_list = listdir(external_dir)
for i in internal_list:
copy(internal_dir+sep+i, external_dir+sep+i)
for i in external_list:
if i in internal_list:
pass
else:
copy(external_dir+sep+i, internal_dir+sep+i)
Print("Synced all replays", color=pink)
2022-12-20 11:14:11 +00:00
def _copy(self, selected_replay, tab_id):
2022-12-20 16:41:44 +05:30
if selected_replay is None:
Print("Select a replay", color=red)
return
2022-12-20 11:14:11 +00:00
elif tab_id == MyTabId.INTERNAL:
2022-12-20 16:41:44 +05:30
copy(internal_dir+selected_replay, external_dir+selected_replay)
2024-01-20 22:21:09 +03:00
Print(selected_replay[0:-4]+" exported", color=pink)
2022-12-20 11:14:11 +00:00
else:
2022-12-20 16:41:44 +05:30
copy(external_dir+selected_replay, internal_dir+selected_replay)
2024-01-20 22:21:09 +03:00
Print(selected_replay[0:-4]+" imported", color=green)
2022-12-20 11:14:11 +00:00
def delete_replay(self, selected_replay, tab_id, cls_inst):
2022-12-20 16:41:44 +05:30
if selected_replay is None:
Print("Select a replay", color=red)
2022-12-20 11:14:11 +00:00
return
2022-12-20 16:41:44 +05:30
def do_it():
2022-12-20 11:14:11 +00:00
if tab_id == MyTabId.INTERNAL:
remove(internal_dir+selected_replay)
elif tab_id == MyTabId.EXTERNAL:
remove(external_dir+selected_replay)
cls_inst.on_tab_select(tab_id) # updating the tab
2024-01-20 22:21:09 +03:00
Print(selected_replay[0:-4]+" was deleted", color=red)
2022-12-20 16:41:44 +05:30
ConfirmWindow(text=f"Delete \"{selected_replay.split('.')[0]}\" \nfrom {'internal directory' if tab_id==MyTabId.INTERNAL else 'external directory'}?",
2022-12-20 11:14:11 +00:00
action=do_it, cancel_is_selected=True)
2022-12-20 16:41:44 +05:30
CommonUtils = CommonUtilities()
class MyTabId(Enum):
INTERNAL = "internal"
EXTERNAL = "external"
SHARE_REPLAYS = "share_replay"
2022-12-20 11:14:11 +00:00
2022-11-07 00:26:16 +05:30
class Help(PopupWindow):
def __init__(self):
2022-12-20 16:41:44 +05:30
self.width = 1200
2022-12-20 11:14:11 +00:00
self.height = 250
2024-01-20 22:21:09 +03:00
self.root_widget = bui.Window(bui.containerwidget(
2022-12-20 11:14:11 +00:00
size=(self.width, self.height), on_outside_click_call=self.close, transition="in_right")).get_root_widget()
2022-11-07 19:58:27 +00:00
2024-01-20 22:21:09 +03:00
bui.containerwidget(edit=self.root_widget, on_outside_click_call=self.close)
bui.textwidget(parent=self.root_widget, position=(0, self.height * 0.7), corner_scale=1.2, color=green,
2022-12-20 16:41:44 +05:30
text=f"»Replays are exported to\n {external_dir}\n»Copy replays to the above folder to be able to import them into the game\n»I would love to hear from you,meet me on discord\n -LoupGarou(author)")
2022-11-07 19:58:27 +00:00
2022-11-07 00:26:16 +05:30
def close(self):
2024-01-20 22:21:09 +03:00
bui.getsound('swish').play()
bui.containerwidget(edit=self.root_widget, transition="out_right",)
2022-11-07 00:26:16 +05:30
2022-12-20 16:41:44 +05:30
class ShareTabUi(WatchWindow):
def __init__(self, root_widget=None):
self.tab_id = MyTabId.INTERNAL
self.selected_replay = None
2022-12-20 16:41:44 +05:30
if root_widget is None:
2024-01-20 22:21:09 +03:00
self.root = bui.Window(bui.containerwidget(
2022-12-20 16:41:44 +05:30
size=(1000, 600), on_outside_click_call=self.close, transition="in_right")).get_root_widget()
2022-12-20 16:41:44 +05:30
else:
self.root = root_widget
2022-12-20 11:14:11 +00:00
2022-12-20 16:41:44 +05:30
self.draw_ui()
2022-11-19 03:15:25 +00:00
def on_select_text(self, widget, name):
existing_widgets = self.scroll2.get_children()
2022-11-19 01:50:31 +05:30
for i in existing_widgets:
2024-01-20 22:21:09 +03:00
bui.textwidget(edit=i, color=(1, 1, 1))
bui.textwidget(edit=widget, color=(1.0, 1, 0.4))
2022-12-20 16:41:44 +05:30
self.selected_replay = name
2022-11-19 03:15:25 +00:00
def on_tab_select(self, tab_id):
2022-12-20 16:41:44 +05:30
self.selected_replay = None
self.tab_id = tab_id
2022-12-20 16:41:44 +05:30
t_scale = 1.6
2022-12-20 11:14:11 +00:00
2022-12-20 16:41:44 +05:30
if tab_id == MyTabId.INTERNAL:
2022-11-19 03:15:25 +00:00
dir_list = listdir(internal_dir)
2024-01-20 22:21:09 +03:00
bui.buttonwidget(edit=self.share_button, label="Export\nReplay")
2022-12-20 11:14:11 +00:00
else:
2022-11-19 03:15:25 +00:00
dir_list = listdir(external_dir)
2024-01-20 22:21:09 +03:00
bui.buttonwidget(edit=self.share_button, label="Import\nReplay")
2022-12-20 11:14:11 +00:00
self.tab_row.update_appearance(tab_id)
2022-11-19 03:15:25 +00:00
dir_list = sorted(dir_list)
existing_widgets = self.scroll2.get_children()
2022-12-20 11:14:11 +00:00
if existing_widgets: # deleting textwidgets from old tab
2022-11-19 03:15:25 +00:00
for i in existing_widgets:
i.delete()
2022-12-20 11:14:11 +00:00
height = 900
for i in dir_list: # making textwidgets for all replays
2022-12-20 16:41:44 +05:30
height -= 50
2022-11-19 03:15:25 +00:00
a = i
2024-01-20 22:21:09 +03:00
i = bui.textwidget(
2022-11-19 03:15:25 +00:00
parent=self.scroll2,
2022-12-20 16:41:44 +05:30
size=(self._my_replays_scroll_width/t_scale, 30),
2022-11-19 03:15:25 +00:00
text=i.split(".")[0],
2022-12-20 16:41:44 +05:30
position=(20, height),
2022-11-19 03:15:25 +00:00
selectable=True,
max_chars=40,
2022-12-20 16:41:44 +05:30
corner_scale=t_scale,
click_activate=True,
always_highlight=True,)
2024-01-20 22:21:09 +03:00
bui.textwidget(edit=i, on_activate_call=babase.Call(self.on_select_text, i, a))
2022-12-20 16:41:44 +05:30
2022-12-20 11:14:11 +00:00
def draw_ui(self):
self._r = 'watchWindow'
2024-01-20 22:21:09 +03:00
x_inset = 100 if uiscale is babase.UIScale.SMALL else 0
2022-12-20 11:14:11 +00:00
scroll_buffer_h = 130 + 2 * x_inset
2024-01-20 22:21:09 +03:00
self._width = 1240 if uiscale is babase.UIScale.SMALL else 1040
2022-12-20 11:14:11 +00:00
self._height = (
578
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.SMALL
2022-12-20 11:14:11 +00:00
else 670
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.MEDIUM
2022-12-20 11:14:11 +00:00
else 800)
self._scroll_width = self._width - scroll_buffer_h
self._scroll_height = self._height - 180
#
c_width = self._scroll_width
c_height = self._scroll_height - 20
sub_scroll_height = c_height - 63
self._my_replays_scroll_width = sub_scroll_width = (
2024-01-20 22:21:09 +03:00
680 if uiscale is babase.UIScale.SMALL else 640
2022-12-20 11:14:11 +00:00
)
v = c_height - 30
2024-01-20 22:21:09 +03:00
b_width = 140 if uiscale is babase.UIScale.SMALL else 178
2022-12-20 11:14:11 +00:00
b_height = (
107
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.SMALL
2022-12-20 11:14:11 +00:00
else 142
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.MEDIUM
2022-12-20 11:14:11 +00:00
else 190
)
b_space_extra = (
0
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.SMALL
2022-12-20 11:14:11 +00:00
else -2
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.MEDIUM
2022-12-20 11:14:11 +00:00
else -5
)
b_color = (0.6, 0.53, 0.63)
b_textcolor = (0.75, 0.7, 0.8)
btnv = (c_height - (48
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.SMALL
2022-12-20 11:14:11 +00:00
else 45
2024-01-20 22:21:09 +03:00
if uiscale is babase.UIScale.MEDIUM
2022-12-20 11:14:11 +00:00
else 40) - b_height)
2024-01-20 22:21:09 +03:00
btnh = 40 if uiscale is babase.UIScale.SMALL else 40
smlh = 190 if uiscale is babase.UIScale.SMALL else 225
tscl = 1.0 if uiscale is babase.UIScale.SMALL else 1.2
2022-12-20 11:14:11 +00:00
stab_width = 500
stab_height = 300
stab_h = smlh
v -= sub_scroll_height + 23
2024-01-20 22:21:09 +03:00
scroll = bui.scrollwidget(
2022-12-20 11:14:11 +00:00
parent=self.root,
position=(smlh, v),
size=(sub_scroll_width, sub_scroll_height),
)
2024-01-20 22:21:09 +03:00
self.scroll2 = bui.columnwidget(parent=scroll,
2022-12-20 11:14:11 +00:00
size=(sub_scroll_width, sub_scroll_height))
tabdefs = [(MyTabId.INTERNAL, 'INTERNAL'), (MyTabId.EXTERNAL, "EXTERNAL")]
self.tab_row = TabRow(self.root, tabdefs, pos=(stab_h, sub_scroll_height),
size=(stab_width, stab_height), on_select_call=self.on_tab_select)
helpbtn_space = 20
helpbtn_v = stab_h+stab_width+helpbtn_space+120
helpbtn_h = sub_scroll_height+helpbtn_space
2024-01-20 22:21:09 +03:00
bui.buttonwidget(
2022-12-20 11:14:11 +00:00
parent=self.root,
position=(helpbtn_v, helpbtn_h),
size=(35, 35),
button_type="square",
label="?",
text_scale=1.5,
color=b_color,
textcolor=b_textcolor,
on_activate_call=Help)
def call_copy(): return CommonUtils._copy(self.selected_replay, self.tab_id)
2024-01-20 22:21:09 +03:00
self.share_button = bui.buttonwidget(
2022-12-20 11:14:11 +00:00
parent=self.root,
size=(b_width, b_height),
position=(btnh, btnv),
button_type="square",
label="Export\nReplay",
text_scale=tscl,
color=b_color,
textcolor=b_textcolor,
on_activate_call=call_copy)
btnv -= b_height + b_space_extra
2024-01-20 22:21:09 +03:00
sync_button = bui.buttonwidget(
2022-12-20 11:14:11 +00:00
parent=self.root,
size=(b_width, b_height),
position=(btnh, btnv),
button_type="square",
label="Sync\nReplay",
text_scale=tscl,
color=b_color,
textcolor=b_textcolor,
on_activate_call=CommonUtils.sync_confirmation)
btnv -= b_height + b_space_extra
def call_delete(): return CommonUtils.delete_replay(self.selected_replay, self.tab_id, self)
2024-01-20 22:21:09 +03:00
delete_replay_button = bui.buttonwidget(
2022-12-20 11:14:11 +00:00
parent=self.root,
size=(b_width, b_height),
position=(btnh, btnv),
button_type="square",
2024-01-20 22:21:09 +03:00
label=babase.Lstr(resource=self._r + '.deleteReplayButtonText'),
2022-12-20 11:14:11 +00:00
text_scale=tscl,
color=b_color,
textcolor=b_textcolor,
on_activate_call=call_delete)
self.on_tab_select(MyTabId.INTERNAL)
2022-11-19 03:15:25 +00:00
2022-11-07 00:26:16 +05:30
def close(self):
2024-01-20 22:21:09 +03:00
bui.getsound('swish').play()
bui.containerwidget(edit=self.root, transition="out_right",)
2022-11-07 19:58:27 +00:00
2022-11-19 03:15:25 +00:00
2022-11-07 00:26:16 +05:30
# ++++++++++++++++for keyboard navigation++++++++++++++++
2024-01-20 22:21:09 +03:00
# bui.widget(edit=self.enable_button, up_widget=decrease_button, down_widget=self.lower_text,left_widget=save_button, right_widget=save_button)
2022-11-07 00:26:16 +05:30
2022-12-20 16:41:44 +05:30
# ----------------------------------------------------------------------------------------------------
class ShareTab(WatchWindow):
2022-11-07 00:26:16 +05:30
2022-12-20 16:41:44 +05:30
@override(WatchWindow)
def __init__(self,
transition: str | None = 'in_right',
2024-01-20 22:21:09 +03:00
origin_widget: bui.Widget | None = None,
2022-12-20 16:41:44 +05:30
oldmethod=None):
self.my_tab_container = None
self._old___init__(transition, origin_widget)
2022-11-07 19:58:27 +00:00
2022-12-20 16:41:44 +05:30
self._tab_row.tabs[self.TabID.MY_REPLAYS].button.delete() # deleting old tab button
2022-11-06 21:24:27 +00:00
2022-12-20 16:41:44 +05:30
tabdefs = [(self.TabID.MY_REPLAYS,
2024-01-20 22:21:09 +03:00
babase.Lstr(resource=self._r + '.myReplaysText'),),
2022-12-20 16:41:44 +05:30
(MyTabId.SHARE_REPLAYS, "Share Replays"),]
2024-01-20 22:21:09 +03:00
uiscale = bui.app.ui_v1.uiscale
x_inset = 100 if uiscale is babase.UIScale.SMALL else 0
2022-12-20 16:41:44 +05:30
tab_buffer_h = 750 + 2 * x_inset
self._tab_row = TabRow(
self._root_widget,
tabdefs,
pos=((tab_buffer_h / 1.5) * 0.5, self._height - 130),
size=((self._width - tab_buffer_h)*2, 50),
on_select_call=self._set_tab)
self._tab_row.update_appearance(self.TabID.MY_REPLAYS)
@override(WatchWindow)
def _set_tab(self, tab_id, oldfunc=None):
self._old__set_tab(tab_id)
if self.my_tab_container:
self.my_tab_container.delete()
if tab_id == MyTabId.SHARE_REPLAYS:
scroll_left = (self._width - self._scroll_width) * 0.5
scroll_bottom = self._height - self._scroll_height - 79 - 48
c_width = self._scroll_width
c_height = self._scroll_height - 20
sub_scroll_height = c_height - 63
self._my_replays_scroll_width = sub_scroll_width = (
2024-01-20 22:21:09 +03:00
680 if uiscale is babase.UIScale.SMALL else 640
2022-12-20 16:41:44 +05:30
)
2024-01-20 22:21:09 +03:00
self.my_tab_container = bui.containerwidget(
2022-12-20 16:41:44 +05:30
parent=self._root_widget,
position=(scroll_left,
scroll_bottom + (self._scroll_height - c_height) * 0.5,),
size=(c_width, c_height),
background=False,
selection_loops_to_parent=True,
)
ShareTabUi(self.my_tab_container)
2022-11-07 19:58:27 +00:00
2022-11-07 00:26:16 +05:30
# ba_meta export plugin
2024-01-20 22:21:09 +03:00
class Loup(babase.Plugin):
2022-11-07 00:26:16 +05:30
def on_app_running(self):
2022-12-20 16:41:44 +05:30
WatchWindow.__init__ = ShareTab.__init__
2022-11-07 19:58:27 +00:00
2022-11-07 00:26:16 +05:30
def has_settings_ui(self):
return True
2022-11-07 19:58:27 +00:00
def show_settings_ui(self, button):
2022-12-20 11:14:11 +00:00
Print("Open share replay tab in replay window to share your replays", color=blue)