Skip to content

Commit cf609f4

Browse files
committed
feat:游戏结束事件施工中
1 parent 383dfaa commit cf609f4

3 files changed

Lines changed: 116 additions & 43 deletions

File tree

src/mineSweeperGUI.py

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# from PyQt5.QtWidgets import QApplication, QFileDialog, QWidget
88
import gameDefinedParameter
99
from plugin_sdk.server_bridge import GameServerBridge
10-
from shared_types.events import VideoSaveEvent, BoardUpdateEvent, GameStatusChangeEvent
10+
from shared_types.events import GameEndEvent, BoardUpdateEvent, GameStatusChangeEvent
1111
import superGUI
1212
import gameAbout
1313
import gameSettings
@@ -224,7 +224,7 @@ def game_state(self, game_state: str):
224224

225225
match self._game_state:
226226
case "playing":
227-
self.try_append_evfs(game_state)
227+
self.onGameEnd(game_state)
228228
if game_state not in ("playing", "show", "joking"):
229229
self.timer_10ms.stop()
230230
self.unlimit_cursor()
@@ -280,6 +280,7 @@ def game_state(self, game_state: str):
280280
GameServerBridge.instance().send_event(event)
281281
self._send_board_update_event()
282282

283+
283284
@property
284285
def row(self):
285286
return self._row
@@ -313,6 +314,65 @@ def minenum(self, minenum):
313314
})
314315
self._minenum = minenum
315316

317+
318+
# 生命周期函数,正式的游戏结束时调用。由游戏状态的变更触发,当且仅当由playing变为其他状态
319+
# 处理数据相关。不处理前端显示
320+
def onGameEnd(self, new_game_state):
321+
# 不论如何都必然生成数据
322+
self.dump_evf_file_data()
323+
# 发信号给插件,游戏结束了
324+
event = GameEndEvent(
325+
game_state = ['ready', 'study', 'show', 'playing', 'joking', 'fail',
326+
'win', 'jofail', 'jowin', 'display', 'showdisplay'].index(new_game_state),
327+
nf = self.label.ms_board.rce == 0,
328+
row = self.label.ms_board.row,
329+
column = self.label.ms_board.column,
330+
mine_num = self.label.ms_board.mine_num,
331+
rtime = self.label.ms_board.rtime,
332+
left = self.label.ms_board.left,
333+
right = self.label.ms_board.right,
334+
double = self.label.ms_board.double,
335+
# 游戏难度(级别)。3是初级;4是中级;5是高级;6是自定义。
336+
level = self.label.ms_board.level,
337+
cl = self.label.ms_board.cl,
338+
ce = self.label.ms_board.ce,
339+
rce = self.label.ms_board.rce,
340+
lce = self.label.ms_board.lce,
341+
dce = self.label.ms_board.dce,
342+
bbbv = self.label.ms_board.bbbv,
343+
bbbv_solved = self.label.ms_board.bbbv_solved,
344+
zini = self.label.ms_board.zini,
345+
flag = self.label.ms_board.flag,
346+
path = self.label.ms_board.path,
347+
start_time = self.label.ms_board.start_time,
348+
end_time = self.label.ms_board.end_time,
349+
mode = self.label.ms_board.mode,
350+
software = self.label.ms_board.software,
351+
player_identifier = self.label.ms_board.player_identifier,
352+
race_identifier = self.label.ms_board.race_identifier,
353+
uniqueness_identifier = self.label.ms_board.uniqueness_identifier,
354+
is_official = self.label.ms_board.is_official,
355+
is_fair = self.label.ms_board.is_fair,
356+
op = self.label.ms_board.op,
357+
isl = self.label.ms_board.isl,
358+
pluck = self.label.ms_board.pluck,
359+
board = self.label.ms_board.board,
360+
raw_data = self.label.ms_board.raw_data
361+
)
362+
GameServerBridge.instance().send_event(event)
363+
364+
# 强制保存Metasweeper.dat文件
365+
...
366+
367+
368+
369+
# 根据策略保存录像文件到磁盘
370+
if self.autosave_video and self.checksum_module_ok() and\
371+
new_game_state in "win":
372+
self.save_evf_file()
373+
self.try_append_evfs(new_game_state)
374+
375+
316376
def layMine(self, i, j):
317377

318378
xx = self.row
@@ -629,24 +689,24 @@ def gameFinished(self):
629689
self.score_board_manager.show(self.label.ms_board, index_type=2)
630690
self.enable_screenshot()
631691
self.unlimit_cursor()
632-
ms_board = self.label.ms_board
633-
status = utils.GameBoardState(ms_board.game_board_state)
634-
if status == utils.GameBoardState.Win:
635-
self.dump_evf_file_data()
636-
event = VideoSaveEvent()
637-
data = msgspec.structs.asdict(event)
638-
for key in data:
639-
if hasattr(ms_board, key):
640-
if key == "raw_data":
641-
data[key] = base64.b64encode(
642-
ms_board.raw_data).decode("utf-8")
643-
continue
644-
data[key] = getattr(ms_board, key)
645-
event = VideoSaveEvent(**data)
646-
GameServerBridge.instance().send_event(event)
692+
# ms_board = self.label.ms_board
693+
# status = utils.GameBoardState(ms_board.game_board_state)
694+
# if status == utils.GameBoardState.Win:
695+
# self.dump_evf_file_data()
696+
# event = VideoSaveEvent()
697+
# data = msgspec.structs.asdict(event)
698+
# for key in data:
699+
# if hasattr(ms_board, key):
700+
# if key == "raw_data":
701+
# data[key] = base64.b64encode(
702+
# ms_board.raw_data).decode("utf-8")
703+
# continue
704+
# data[key] = getattr(ms_board, key)
705+
# event = VideoSaveEvent(**data)
706+
# GameServerBridge.instance().send_event(event)
647707

648708
# 发送棋盘更新事件,让插件知道最终状态
649-
self._send_board_update_event()
709+
# self._send_board_update_event()
650710

651711
def gameWin(self): # 成功后改脸和状态变量,停时间
652712
self.timer_10ms.stop()
@@ -660,9 +720,9 @@ def gameWin(self): # 成功后改脸和状态变量,停时间
660720
raise RuntimeError
661721
self.set_face(17)
662722

663-
if self.autosave_video and self.checksum_module_ok():
664-
self.dump_evf_file_data()
665-
self.save_evf_file()
723+
# if self.autosave_video and self.checksum_module_ok():
724+
# self.dump_evf_file_data()
725+
# self.save_evf_file()
666726

667727
self.gameFinished()
668728

@@ -736,11 +796,17 @@ def dump_evf_file_data(self):
736796
# 将evf数据存成evf文件
737797
# 调试的时候不会自动存录像,见checksum_module_ok
738798
# 菜单保存的回调。以及游戏结束自动保存。
739-
def save_evf_file(self):
799+
# 返回保存的文件绝对路径
800+
def save_evf_file(self) -> str:
740801
if not os.path.exists(self.replay_path):
741802
os.mkdir(self.replay_path)
742803

743-
self.label.ms_board.save_to_evf_file(self.cal_evf_filename())
804+
file_name = self.cal_evf_filename()
805+
# 加上后缀和重复标识数字
806+
real_file_name = self.label.ms_board.save_to_evf_file(file_name)
807+
absolute_path = os.path.abspath(os.path.join(self.replay_path, real_file_name))
808+
return absolute_path
809+
744810

745811
# 拼接evf录像的文件名,无后缀
746812
def cal_evf_filename(self, absolute=True) -> str:

src/shared_types/events.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,53 +58,59 @@ class ButtonClickEvent(BaseEvent, tag="button_click"):
5858
button = 0
5959

6060

61-
class VideoSaveEvent(BaseEvent, tag="video_save"):
62-
"""录像保存事件"""
61+
class GameEndEvent(BaseEvent, tag="game_end"):
62+
"""
63+
游戏结束事件。发生在游戏胜利、失败、重开、游戏关闭、游戏设置关闭、切换游戏状态关闭、
64+
游戏状态变为非正式等情况。
65+
playing状态切换为其他状态时触发此消息。自定义难度、各种模式均会触发。
66+
"""
6367

64-
game_board_state: int = 0
65-
rtime: float = 0
68+
# 游戏的新状态(旧状态必为playing),'ready'、'study'、'show'、'playing'、'joking'、
69+
# 'fail'、'win'、'jofail'、'jowin'、'display'、'showdisplay'分别记作0-10
70+
game_state: int = 0
71+
# False-flag, True-nf
72+
nf: bool = False
73+
row: int = 16
74+
column: int = 30
75+
mine_num: int = 99
76+
rtime: float = 0.0
6677
left: int = 126
6778
right: int = 11
6879
double: int = 14
69-
left_s: float = 2.5583756345177666
70-
right_s: float = 0.2233502538071066
71-
double_s: float = 0.28426395939086296
80+
# 游戏难度(级别)。3是初级;4是中级;5是高级;6是自定义。
7281
level: int = 5
7382
cl: int = 151
74-
cl_s: float = 3.065989847715736
7583
ce: int = 144
76-
ce_s: float = 2.9238578680203045
7784
rce: int = 11
7885
lce: int = 119
7986
dce: int = 14
8087
bbbv: int = 127
8188
bbbv_solved: int = 127
82-
bbbv_s: float = 2.5786802030456855
89+
zini: int = 105
8390
flag: int = 11
8491
path: float = 6082.352554578606
85-
etime: float = 1666124184868000
92+
# 时间戳,微秒
8693
start_time: int = 1666124135606000
8794
end_time: int = 1666124184868000
95+
# 标准0、win74、经典无猜5、强无猜6、弱无猜7、准无猜8、强可猜9、弱可猜10
8896
mode: int = 0
89-
software: str = "Arbiter"
90-
player_identifier: str = "Wang Jianing G01825"
91-
race_identifier: str = ""
97+
software: str = "元 3.2.2"
98+
player_identifier: str = "Wang Jianing"
99+
race_identifier: str = "G1234"
92100
uniqueness_identifier: str = ""
93-
stnb: float = 0
94-
corr: float = 0
95-
thrp: float = 0
96-
ioe: float = 0
97101
is_official: bool = False
98102
is_fair: bool = False
99103
op: int = 0
100104
isl: int = 0
101105
pluck: float = 0
102-
raw_data: str = ""
106+
board: List[List[int]] = []
107+
# evf4版本的二进制数据
108+
raw_data: bytes = b""
103109

104110

105111
EVENT_TYPES = [
106112
BoardUpdateEvent,
107113
GameStatusChangeEvent,
108114
ButtonClickEvent,
109-
VideoSaveEvent,
115+
GameEndEvent,
110116
]

src/superGUI.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ def read_or_create_game_setting(self):
509509
self.race_identifier = self.game_setting.get_or_set_value("DEFAULT/race_identifier", "", str)
510510
self.unique_identifier = self.game_setting.get_or_set_value("DEFAULT/unique_identifier", "", str)
511511
self.country = self.game_setting.get_or_set_value("DEFAULT/country", "", str)
512+
# 是否自动保存录像。开启时,自动保存所有扫完的、正式的录像。假如要其他保存策略,应使用插件来完成。
512513
self.autosave_video = self.game_setting.get_or_set_value("DEFAULT/autosave_video", True, bool)
513514
self.autosave_video_set = self.game_setting.get_or_set_value("DEFAULT/autosave_video_set", False, bool)
514515
self.filter_forever = self.game_setting.get_or_set_value("DEFAULT/filter_forever", False, bool)

0 commit comments

Comments
 (0)