1- // api/accounts/sync.ts
21import { Request } from 'express' ;
2+ import path from 'path' ;
3+ import fs from 'fs/promises' ;
34import { RowDataPacket } from 'mysql2/promise' ;
45import db from '../../serverconf/db' ;
56import GeneratePass from '../lib/generatePass' ;
67import ExploitPatch from '../lib/exploitPatch' ;
78import ConsoleApi from '../../modules/console-api' ;
9+ import { settings } from '../../serverconf/settings' ;
810
911/**
10- * Syncs a GD account save data from database
11- * @param userNameStr - Username
12- * @param accountIDStr - Account ID
13- * @param passwordStr - Password
14- * @param gjp2Str - GJP2 hash
15- * @param req - Express request
16- * @returns Save data if successful , "-1" if failed , "-2" if invalid password
12+ * Синхронизирует данные сохранения аккаунта GD из базы данных или файла
13+ * @param userNameStr - Имя пользователя
14+ * @param accountIDStr - ID аккаунта
15+ * @param passwordStr - Пароль
16+ * @param gjp2Str - GJP2 хеш
17+ * @param req - Express запрос
18+ * @returns Данные сохранения если успешно , "-1" если ошибка , "-2" если неверный пароль
1719 */
1820const syncAccount = async (
1921 userNameStr ?: string ,
@@ -26,20 +28,31 @@ const syncAccount = async (
2628 // Логируем запрос
2729 ConsoleApi . Log ( "main" , `Sync request received for account ${ accountIDStr || userNameStr } ` ) ;
2830
31+ // Базовая валидация входных данных
32+ if ( ! userNameStr && ! accountIDStr ) {
33+ ConsoleApi . Error ( "main" , `Failed to sync account: missing required parameters` ) ;
34+ return "-1" ;
35+ }
36+
2937 const password = passwordStr || "" ;
3038 let accountID = accountIDStr || "" ;
3139
3240 // Получить ID аккаунта по имени пользователя, если не предоставлен
3341 if ( ! accountID ) {
34- const userName = await ExploitPatch . remove ( userNameStr ) ;
35- const [ rows ] = await db . execute < RowDataPacket [ ] > (
36- "SELECT accountID FROM accounts WHERE userName = ?" ,
37- [ userName ]
38- ) ;
39- accountID = rows . length ? rows [ 0 ] . accountID . toString ( ) : null ;
40-
41- if ( ! accountID ) {
42- ConsoleApi . Log ( "main" , `Failed to sync account: account not found` ) ;
42+ try {
43+ const userName = await ExploitPatch . remove ( userNameStr ) ;
44+ const [ rows ] = await db . execute < RowDataPacket [ ] > (
45+ "SELECT accountID FROM accounts WHERE userName = ?" ,
46+ [ userName ]
47+ ) ;
48+ accountID = rows . length ? rows [ 0 ] . accountID . toString ( ) : null ;
49+
50+ if ( ! accountID ) {
51+ ConsoleApi . Log ( "main" , `Failed to sync account: account not found` ) ;
52+ return "-1" ;
53+ }
54+ } catch ( err ) {
55+ ConsoleApi . Error ( "main" , `Error getting account ID: ${ err } ` ) ;
4356 return "-1" ;
4457 }
4558 } else {
@@ -48,45 +61,98 @@ const syncAccount = async (
4861
4962 // Проверить учетные данные
5063 let pass = 0 ;
51- if ( passwordStr ) {
52- pass = await GeneratePass . isValid ( accountID , passwordStr , req ) ;
53- } else if ( gjp2Str ) {
54- pass = await GeneratePass . isGJP2Valid ( accountID , gjp2Str , req ) ;
64+ try {
65+ if ( passwordStr ) {
66+ pass = await GeneratePass . isValid ( accountID , passwordStr , req ) ;
67+ } else if ( gjp2Str ) {
68+ pass = await GeneratePass . isGJP2Valid ( accountID , gjp2Str , req ) ;
69+ }
70+
71+ if ( pass !== 1 ) {
72+ ConsoleApi . Log ( "main" , `Failed to sync account: ${ accountID } - authentication failed` ) ;
73+ return "-2" ;
74+ }
75+ } catch ( err ) {
76+ ConsoleApi . Error ( "main" , `Error in authentication: ${ err } ` ) ;
77+ return "-1" ;
5578 }
5679
57- if ( pass === 1 ) {
58- // Получить данные сохранения из БД
59- const [ rows ] = await db . execute < RowDataPacket [ ] > (
60- "SELECT saveData FROM accounts WHERE accountID = ?" ,
61- [ accountID ]
62- ) ;
80+ // Получить данные сохранения
81+ let saveData : string = "" ;
82+
83+ // Сначала проверим наличие файла последнего бэкапа на диске
84+ try {
85+ const backupDir = path . join ( __dirname , '..' , '..' , 'data' , 'backups' , ` ${ accountID } ` ) ;
6386
64- if ( rows . length === 0 || ! rows [ 0 ] . saveData ) {
65- ConsoleApi . Log ( "main" , `Failed to sync account ${ accountID } : no save data found` ) ;
66- return "-1" ;
87+ // Проверяем существование директории
88+ try {
89+ await fs . access ( backupDir ) ;
90+ } catch ( err ) {
91+ // Директория не существует, используем данные из БД
92+ throw new Error ( "Backup directory does not exist" ) ;
6793 }
6894
69- const saveData = rows [ 0 ] . saveData ;
95+ // Получаем список файлов бэкапов
96+ const files = await fs . readdir ( backupDir ) ;
97+
98+ // Фильтруем только файлы формата backup_*.dat
99+ const backupFiles = files
100+ . filter ( file => file . match ( / ^ b a c k u p _ \d + \. d a t $ / ) )
101+ . map ( file => ( {
102+ name : file ,
103+ path : path . join ( backupDir , file ) ,
104+ time : parseInt ( file . replace ( 'backup_' , '' ) . replace ( '.dat' , '' ) )
105+ } ) )
106+ . sort ( ( a , b ) => b . time - a . time ) ; // Сортируем по времени (самые новые первые)
70107
71- // Обновить время последней синхронизации
108+ // Если есть бэкапы, используем самый свежий
109+ if ( backupFiles . length > 0 ) {
110+ saveData = await fs . readFile ( backupFiles [ 0 ] . path , 'utf8' ) ;
111+ } else {
112+ throw new Error ( "No backup files found" ) ;
113+ }
114+ } catch ( err ) {
115+ // Если возникла ошибка с файлами, используем данные из БД
116+ ConsoleApi . Log ( "main" , `No backup files found on disk, using DB: ${ err } ` ) ;
117+
118+ try {
119+ const [ rows ] = await db . execute < RowDataPacket [ ] > (
120+ "SELECT saveData FROM accounts WHERE accountID = ?" ,
121+ [ accountID ]
122+ ) ;
123+
124+ if ( rows . length === 0 || ! rows [ 0 ] . saveData ) {
125+ ConsoleApi . Log ( "main" , `Failed to sync account ${ accountID } : no save data found` ) ;
126+ return "-1" ;
127+ }
128+
129+ saveData = rows [ 0 ] . saveData ;
130+ } catch ( dbErr ) {
131+ ConsoleApi . Error ( "main" , `Error getting save data from DB: ${ dbErr } ` ) ;
132+ return "-1" ;
133+ }
134+ }
135+
136+ // Обновить время последней синхронизации
137+ try {
72138 await db . execute (
73139 "UPDATE accounts SET lastSync = ? WHERE accountID = ?" ,
74140 [ Math . floor ( Date . now ( ) / 1000 ) , accountID ]
75141 ) ;
76-
77- ConsoleApi . Log ( "main" , `Synced account: ${ accountID } ` ) ;
78-
79- // Возвращаем данные в нужном формате
80- return `${ saveData } ;21;30;a;a` ;
81- } else {
82- ConsoleApi . Log ( "main" , `Failed to sync account: ${ accountID } - authentication failed` ) ;
83- return "-2" ;
142+ } catch ( err ) {
143+ ConsoleApi . Error ( "main" , `Error updating lastSync time: ${ err } ` ) ;
144+ // Продолжаем выполнение, так как основная задача - вернуть данные сохранения
84145 }
146+
147+ ConsoleApi . Log ( "main" , `Synced account: ${ accountID } ` ) ;
148+
149+ // Возвращаем данные в нужном формате
150+ return `${ saveData } ;21;30;a;a` ;
85151 } catch ( error ) {
86152 ConsoleApi . Warn ( "main" , `Check the data for damage at net.fimastgd.forevercore.api.accounts.sync` ) ;
87153 ConsoleApi . Error ( "main" , `Unhandled server exception with user sync account: ${ error } ` ) ;
88154 return "-1" ;
89155 }
90156} ;
91157
92- export default syncAccount ;
158+ export default syncAccount ;
0 commit comments