Cześć, jako, że sobie zrobiłem zintegrowany patcher w bince to tego już nie potrzebuje, może akurat ktoś wykorzysta u siebie. Kod trochę poprawiony aby to jakoś działało. (parę rzeczy nie działało lub średnio działało)
Informacje:
Log z pracy zapisywany jest do syserr.txt
Design: TMP4
Oryginalny kod: Sanchez
Zmienne w globals.cs do ustawienia na swoje
+ generator patchlist.txt na www
"$excludeDirs = ['upload', 'shop'])" << po prostu nie chciałem za każdym razem aktualizować, można usunąć/zmienić
"clientPath" trzeba zmienić na lokalizacje swoich plików
<?php
/**
* Generate patchlist.txt for Metin2Patcher
*/
require_once dirname(dirname(__DIR__)) . '/config.php';
requireAdmin();
// Handle AJAX requests
if (isset($_POST['action'])) {
header('Content-Type: application/json');
switch ($_POST['action']) {
case 'generate':
$clientPath = '/patch/to/your/files';
$outputPath = $clientPath . '/patchlist.txt';
try {
$files = scanDirectory($clientPath);
$patchlist = generatePatchlist($files, $clientPath);
// Backup old patchlist if exists
if (file_exists($outputPath)) {
copy($outputPath, $outputPath . '.bak.' . date('YmdHis'));
}
file_put_contents($outputPath, $patchlist);
echo json_encode([
'success' => true,
'message' => 'Patchlist generated successfully',
'files_count' => count($files),
'file_path' => $outputPath
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => 'Error: ' . $e->getMessage()
]);
}
exit;
case 'preview':
$clientPath = '/patch/to/your/files';
try {
$files = scanDirectory($clientPath);
$entries = [];
foreach (array_slice($files, 0, 10) as $file) {
$relativePath = str_replace($clientPath . '/', '', $file);
$hash = hash_file('crc32b', $file);
$size = filesize($file);
$entries[] = [
'path' => $relativePath,
'hash' => $hash,
'size' => $size
];
}
echo json_encode([
'success' => true,
'total' => count($files),
'preview' => $entries
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => 'Error: ' . $e->getMessage()
]);
}
exit;
}
}
/**
* Recursively scan directory for files
*/
function scanDirectory($path, $excludeDirs = ['upload', 'shop']) {
$files = [];
$items = scandir($path);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$fullPath = $path . '/' . $item;
if (is_dir($fullPath)) {
// Skip excluded directories
if (in_array($item, $excludeDirs)) continue;
// Recursively scan subdirectory
$files = array_merge($files, scanDirectory($fullPath, $excludeDirs));
} else {
// Skip patchlist files themselves
if (strpos($item, 'patchlist') === 0) continue;
$files[] = $fullPath;
}
}
return $files;
}
/**
* Generate patchlist content
*/
function generatePatchlist($files, $basePath) {
$lines = [];
foreach ($files as $file) {
// Get relative path from base
$relativePath = str_replace($basePath . '/', '', $file);
// Calculate CRC32 hash
$hash = hash_file('crc32b', $file);
// Get file size
$size = filesize($file);
// Format: path hash size
$lines[] = "$relativePath $hash $size";
}
return implode("\n", $lines);
}
?>