Updated share_replay to v1.3.0

This commit is contained in:
* 2022-12-20 16:41:44 +05:30
parent 0374524f3c
commit 6e9d698b59
2 changed files with 323 additions and 180 deletions

View file

@ -1,10 +1,24 @@
"""
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'
"""
# ba_meta require api 7
from __future__ import annotations
from typing import TYPE_CHECKING, cast
if TYPE_CHECKING:
from typing import Any, Sequence, Callable, List, Dict, Tuple, Optional, Union
from os import listdir, mkdir, path, sep
from os import listdir, mkdir, path, sep,remove
from shutil import copy, copytree
import ba
@ -12,12 +26,23 @@ import _ba
from enum import Enum
from bastd.ui.tabs import TabRow
from bastd.ui.confirm import ConfirmWindow
from bastd.ui.watch import WatchWindow as ww
from bastd.ui.watch import WatchWindow
from bastd.ui.popup import PopupWindow
# mod by ʟօʊքɢǟʀօʊ
# export replays to mods folder and share with your friends or have a backup
title = "SHARE REPLAY"
internal_dir = _ba.get_replays_dir()+sep
external_dir = path.join(_ba.env()["python_directory_user"], "replays"+sep)
uiscale = ba.app.ui.uiscale
# 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)
def Print(*args, color=None, top=None):
out = ""
@ -35,174 +60,31 @@ def cprint(*args):
_ba.chatmessage(out)
title = "SHARE REPLAY"
internal_dir = _ba.get_replays_dir()+sep
external_dir = path.join(_ba.env()["python_directory_user"], "replays"+sep)
# 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)
if not path.exists(external_dir):
mkdir(external_dir)
Print("You are ready to share replays", color=pink)
class Help(PopupWindow):
def __init__(self):
uiscale = ba.app.ui.uiscale
self.width = 1000
self.height = 300
PopupWindow.__init__(self,
position=(0.0, 0.0),
size=(self.width, self.height),
scale=1.2,)
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)
ba.containerwidget(edit=self.root_widget, on_outside_click_call=self.close)
ba.textwidget(parent=self.root_widget, position=(0, self.height * 0.6),
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 live to hear from you,meet me on discord\n -LoupGarou(author)")
setattr(cls, funcname, newfunc)
return newfunc
def close(self):
ba.playsound(ba.getsound('swish'))
ba.containerwidget(edit=self.root_widget, transition="out_right",)
return decorator
class SettingWindow():
def __init__(self):
self.draw_ui()
ba.containerwidget(edit=self.root, cancel_button=self.close_button)
self.selected_name = None
# setting tab when window opens
self.on_tab_select(self.TabId.INTERNAL)
self.tab_id = self.TabId.INTERNAL
class TabId(Enum):
INTERNAL = "internal"
EXTERNAL = "external"
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 on_select_text(self, widget, name):
existing_widgets = self.scroll2.get_children()
for i in existing_widgets:
ba.textwidget(edit=i, color=(1, 1, 1))
ba.textwidget(edit=widget, color=(1, 1, 0))
self.selected_name = name
def on_tab_select(self, tab_id):
self.tab_id = tab_id
if tab_id == self.TabId.INTERNAL:
dir_list = listdir(internal_dir)
ba.buttonwidget(edit=self.share_button, label="EXPORT", icon=ba.gettexture("upButton"),)
else:
dir_list = listdir(external_dir)
ba.buttonwidget(edit=self.share_button, label="IMPORT",
icon=ba.gettexture("downButton"),)
self.tab_row.update_appearance(tab_id)
dir_list = sorted(dir_list)
existing_widgets = self.scroll2.get_children()
if existing_widgets:
for i in existing_widgets:
i.delete()
height = 900
# making textwidgets for all replays
for i in dir_list:
height -= 40
a = i
i = ba.textwidget(
parent=self.scroll2,
size=(500, 50),
text=i.split(".")[0],
position=(10, height),
selectable=True,
max_chars=40,
corner_scale=1.3,
click_activate=True,)
ba.textwidget(edit=i, on_activate_call=ba.Call(self.on_select_text, i, a))
def draw_ui(self):
self.uiscale = ba.app.ui.uiscale
self.root = ba.Window(ba.containerwidget(
size=(900, 670), on_outside_click_call=self.close, transition="in_right")).get_root_widget()
self.close_button = ba.buttonwidget(
parent=self.root,
position=(90, 560),
button_type='backSmall',
size=(60, 60),
label=ba.charstr(ba.SpecialChar.BACK),
scale=1.5,
on_activate_call=self.close)
ba.textwidget(
parent=self.root,
size=(200, 100),
position=(350, 550),
scale=2,
selectable=False,
h_align="center",
v_align="center",
text=title,
color=green)
ba.buttonwidget(
parent=self.root,
position=(650, 580),
size=(35, 35),
texture=ba.gettexture("achievementEmpty"),
label="",
on_activate_call=Help)
tabdefs = [(self.TabId.INTERNAL, 'INTERNAL'), (self.TabId.EXTERNAL, "EXTERNAL")]
self.tab_row = TabRow(self.root, tabdefs, pos=(150, 500-5),
size=(500, 300), on_select_call=self.on_tab_select)
self.share_button = ba.buttonwidget(
parent=self.root,
position=(720, 400),
size=(110, 50),
scale=1.5,
button_type="square",
label="EXPORT",
text_scale=2,
icon=ba.gettexture("upButton"),
on_activate_call=self.share)
sync_button = ba.buttonwidget(
parent=self.root,
position=(720, 300),
size=(110, 50),
scale=1.5,
button_type="square",
label="SYNC",
text_scale=2,
icon=ba.gettexture("ouyaYButton"),
on_activate_call=self.sync_confirmation)
scroll = ba.scrollwidget(
parent=self.root,
size=(600, 400),
position=(100, 100),)
self.scroll2 = ba.columnwidget(parent=scroll, size=(
500, 900))
def share(self):
if self.selected_name is None:
Print("Select a replay", color=red)
return
if self.tab_id == self.TabId.INTERNAL:
self.export()
else:
self.importx()
# image={"texture":ba.gettexture("bombColor"),"tint_texture":None,"tint_color":None,"tint2_color":None})
def sync(self):
internal_list = listdir(internal_dir)
external_list = listdir(external_dir)
@ -215,13 +97,233 @@ class SettingWindow():
copy(external_dir+sep+i, internal_dir+sep+i)
Print("Synced all replays", color=pink)
def export(self):
copy(internal_dir+self.selected_name, external_dir+self.selected_name)
Print(self.selected_name[0:-4]+" exported", top=True, color=pink)
def _copy(self, selected_replay,tab_id):
if selected_replay is None:
Print("Select a replay", color=red)
return
elif tab_id==MyTabId.INTERNAL:
copy(internal_dir+selected_replay, external_dir+selected_replay)
Print(selected_replay[0:-4]+" exported", top=True, color=pink)
else:
copy(external_dir+selected_replay, internal_dir+selected_replay)
Print(selected_replay[0:-4]+" imported", top=True, color=green)
def delete_replay(self,selected_replay,tab_id,cls_inst):
if selected_replay is None:
Print("Select a replay", color=red)
return
def do_it():
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
Print(selected_replay[0:-4]+" was deleted", top=True, color=red)
ConfirmWindow(text=f"Delete \"{selected_replay.split('.')[0]}\" \nfrom {'internal directory' if tab_id==MyTabId.INTERNAL else 'external directory'}?",
action=do_it, cancel_is_selected=True)
CommonUtils = CommonUtilities()
def importx(self):
copy(external_dir+self.selected_name, internal_dir+self.selected_name)
Print(self.selected_name[0:-4]+" imported", top=True, color=green)
class MyTabId(Enum):
INTERNAL = "internal"
EXTERNAL = "external"
SHARE_REPLAYS = "share_replay"
class Help(PopupWindow):
def __init__(self):
self.width = 1200
self.height = 250
self.root_widget = ba.Window(ba.containerwidget(
size=(self.width, self.height), on_outside_click_call=self.close, transition="in_right")).get_root_widget()
ba.containerwidget(edit=self.root_widget, on_outside_click_call=self.close)
ba.textwidget(parent=self.root_widget, position=(0, self.height * 0.7),corner_scale=1.2 ,color=green,
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)")
def close(self):
ba.playsound(ba.getsound('swish'))
ba.containerwidget(edit=self.root_widget, transition="out_right",)
class ShareTabUi(WatchWindow):
def __init__(self, root_widget=None):
self.tab_id = MyTabId.INTERNAL
self.selected_replay = None
if root_widget is None:
self.root = ba.Window(ba.containerwidget(
size=(1000, 600), on_outside_click_call=self.close, transition="in_right")).get_root_widget()
else:
self.root = root_widget
self.draw_ui()
def on_select_text(self, widget, name):
existing_widgets = self.scroll2.get_children()
for i in existing_widgets:
ba.textwidget(edit=i, color=(1, 1, 1))
ba.textwidget(edit=widget, color=(1.0, 1, 0.4))
self.selected_replay = name
def on_tab_select(self, tab_id):
self.selected_replay = None
self.tab_id = tab_id
t_scale = 1.6
if tab_id == MyTabId.INTERNAL:
dir_list = listdir(internal_dir)
ba.buttonwidget(edit=self.share_button, label="Export\nReplay")
else:
dir_list = listdir(external_dir)
ba.buttonwidget(edit=self.share_button, label="Import\nReplay")
self.tab_row.update_appearance(tab_id)
dir_list = sorted(dir_list)
existing_widgets = self.scroll2.get_children()
if existing_widgets:# deleting textwidgets from old tab
for i in existing_widgets:
i.delete()
height = 900
for i in dir_list:# making textwidgets for all replays
height -= 50
a = i
i = ba.textwidget(
parent=self.scroll2,
size=(self._my_replays_scroll_width/t_scale, 30),
text=i.split(".")[0],
position=(20, height),
selectable=True,
max_chars=40,
corner_scale=t_scale,
click_activate=True,
always_highlight=True,)
ba.textwidget(edit=i, on_activate_call=ba.Call(self.on_select_text, i, a))
def draw_ui(self):
self._r = 'watchWindow'
x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
scroll_buffer_h = 130 + 2 * x_inset
self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
self._height = (
578
if uiscale is ba.UIScale.SMALL
else 670
if uiscale is ba.UIScale.MEDIUM
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 = (
680 if uiscale is ba.UIScale.SMALL else 640
)
v = c_height - 30
b_width = 140 if uiscale is ba.UIScale.SMALL else 178
b_height = (
107
if uiscale is ba.UIScale.SMALL
else 142
if uiscale is ba.UIScale.MEDIUM
else 190
)
b_space_extra = (
0
if uiscale is ba.UIScale.SMALL
else -2
if uiscale is ba.UIScale.MEDIUM
else -5
)
b_color = (0.6, 0.53, 0.63)
b_textcolor = (0.75, 0.7, 0.8)
btnv = (c_height- (48
if uiscale is ba.UIScale.SMALL
else 45
if uiscale is ba.UIScale.MEDIUM
else 40) - b_height)
btnh = 40 if uiscale is ba.UIScale.SMALL else 40
smlh = 190 if uiscale is ba.UIScale.SMALL else 225
tscl = 1.0 if uiscale is ba.UIScale.SMALL else 1.2
stab_width=500
stab_height=300
stab_h=smlh
v -= sub_scroll_height + 23
scroll = ba.scrollwidget(
parent=self.root,
position=(smlh, v),
size=(sub_scroll_width, sub_scroll_height),
)
self.scroll2 = ba.columnwidget(parent=scroll,
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
ba.buttonwidget(
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)
call_copy=lambda:CommonUtils._copy(self.selected_replay,self.tab_id)
self.share_button = ba.buttonwidget(
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
sync_button = ba.buttonwidget(
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
call_delete = lambda:CommonUtils.delete_replay(self.selected_replay,self.tab_id,self)
delete_replay_button = ba.buttonwidget(
parent=self.root,
size=(b_width, b_height),
position=(btnh, btnv),
button_type="square",
label=ba.Lstr(resource=self._r + '.deleteReplayButtonText'),
text_scale=tscl,
color=b_color,
textcolor=b_textcolor,
on_activate_call=call_delete)
self.on_tab_select(MyTabId.INTERNAL)
def close(self):
ba.playsound(ba.getsound('swish'))
@ -232,33 +334,73 @@ class SettingWindow():
#ba.widget(edit=self.enable_button, up_widget=decrease_button, down_widget=self.lower_text,left_widget=save_button, right_widget=save_button)
# --------------------------------------------------------------------------------------------------
# ----------------------------------------------------------------------------------------------------
ww.__old_init__ = ww.__init__
class ShareTab(WatchWindow):
@override(WatchWindow)
def __init__(self,
transition: str | None = 'in_right',
origin_widget: ba.Widget | None = None,
oldmethod=None):
self.my_tab_container = None
self._old___init__(transition, origin_widget)
def new_init(self, transition="in_right", origin_widget=None):
self.__old_init__(transition, origin_widget)
self._share_button = ba.buttonwidget(
parent=self._root_widget,
position=(self._width*0.70, self._height*0.80),
size=(220, 60),
scale=1.0,
color=green,
icon=ba.gettexture('usersButton'),
iconscale=1.5,
label=title,
on_activate_call=SettingWindow)
self._tab_row.tabs[self.TabID.MY_REPLAYS].button.delete() # deleting old tab button
tabdefs = [(self.TabID.MY_REPLAYS,
ba.Lstr(resource=self._r + '.myReplaysText'),),
(MyTabId.SHARE_REPLAYS, "Share Replays"),]
uiscale = ba.app.ui.uiscale
x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
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 = (
680 if uiscale is ba.UIScale.SMALL else 640
)
self.my_tab_container = ba.containerwidget(
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)
# ba_meta export plugin
class Loup(ba.Plugin):
def on_app_running(self):
ww.__init__ = new_init
WatchWindow.__init__ = ShareTab.__init__
def has_settings_ui(self):
return True
def show_settings_ui(self, button):
SettingWindow()
Print("Open share replay tab in replay window to share your replays",color=blue)