|
28 | 28 | import ctypes |
29 | 29 | import hashlib |
30 | 30 | import uuid |
| 31 | +from Crypto.Cipher import AES |
| 32 | +from Crypto.Util.Padding import pad, unpad |
31 | 33 | # from PyQt5.QtWidgets import QApplication |
32 | 34 | from country_name import country_name |
33 | 35 | import metaminesweeper_checksum |
@@ -321,6 +323,7 @@ def onGameEnd(self, new_game_state): |
321 | 323 | # 不论如何都必然生成数据 |
322 | 324 | self.dump_evf_file_data() |
323 | 325 | # 发信号给插件,游戏结束了 |
| 326 | + board = self.label.ms_board.board |
324 | 327 | event = GameEndEvent( |
325 | 328 | game_state = ['ready', 'study', 'show', 'playing', 'joking', 'fail', |
326 | 329 | 'win', 'jofail', 'jowin', 'display', 'showdisplay'].index(new_game_state), |
@@ -356,14 +359,61 @@ def onGameEnd(self, new_game_state): |
356 | 359 | op = self.label.ms_board.op, |
357 | 360 | isl = self.label.ms_board.isl, |
358 | 361 | pluck = self.label.ms_board.pluck, |
359 | | - board = self.label.ms_board.board, |
| 362 | + board = board if isinstance(board, list) else board.into_vec_vec(), |
360 | 363 | raw_data = self.label.ms_board.raw_data |
361 | 364 | ) |
362 | 365 | GameServerBridge.instance().send_event(event) |
363 | 366 |
|
364 | | - # 强制保存Metasweeper.dat文件 |
365 | | - ... |
366 | | - |
| 367 | + # 强制保存stats.dat文件 |
| 368 | + record = utils.StatsRecord( |
| 369 | + game_state=event.game_state, |
| 370 | + nf=event.nf, |
| 371 | + row=event.row, |
| 372 | + column=event.column, |
| 373 | + mine_num=event.mine_num, |
| 374 | + rtime=event.rtime, |
| 375 | + left=event.left, |
| 376 | + right=event.right, |
| 377 | + double=event.double, |
| 378 | + level=event.level, |
| 379 | + cl=event.cl, |
| 380 | + ce=event.ce, |
| 381 | + rce=event.rce, |
| 382 | + lce=event.lce, |
| 383 | + dce=event.dce, |
| 384 | + bbbv=event.bbbv, |
| 385 | + bbbv_solved=event.bbbv_solved, |
| 386 | + zini=event.zini, |
| 387 | + flag=event.flag, |
| 388 | + path=event.path, |
| 389 | + start_time=event.start_time, |
| 390 | + end_time=event.end_time, |
| 391 | + mode=event.mode, |
| 392 | + software=event.software, |
| 393 | + player_identifier=event.player_identifier, |
| 394 | + race_identifier=event.race_identifier, |
| 395 | + uniqueness_identifier=event.uniqueness_identifier, |
| 396 | + is_official=event.is_official, |
| 397 | + is_fair=event.is_fair, |
| 398 | + op=event.op, |
| 399 | + isl=event.isl, |
| 400 | + pluck=event.pluck, |
| 401 | + board=event.board |
| 402 | + ) |
| 403 | + binary_data = msgspec.msgpack.encode(record) |
| 404 | + # 简单的AES加密 |
| 405 | + key = bytes([2,135,180,102,125,204,245,102,253,59,217,7,114,61,231,62]) # 16字节的密钥 |
| 406 | + cipher = AES.new(key, AES.MODE_ECB) |
| 407 | + padded_data = pad(binary_data, AES.block_size) |
| 408 | + encrypted_data = cipher.encrypt(padded_data) |
| 409 | + dat_file_path = self.setting_path / 'stats.dat' |
| 410 | + # 把二进制加密数据 编码成 base64 字符串(bytes) |
| 411 | + b64_data = base64.b64encode(encrypted_data) |
| 412 | + is_empty = not os.path.exists(dat_file_path) or os.path.getsize(dat_file_path) == 0 |
| 413 | + with open(dat_file_path, 'ab') as f: |
| 414 | + if not is_empty: |
| 415 | + f.write(b"\n") |
| 416 | + f.write(b64_data) |
367 | 417 |
|
368 | 418 |
|
369 | 419 | # 根据策略保存录像文件到磁盘 |
|
0 commit comments