- Katılım
- 22 Nis 2024
- Konular
- 35
- Mesajlar
- 275
- Çözüm
- 7
- Online süresi
- 9d 11h
- Reaksiyon Skoru
- 351
- Altın Konu
- 0
- Başarım Puanı
- 97
- MmoLira
- 2,360
- DevLira
- 54
ROHAN2 WORLD 1-120 TR TİPİ OFFICIAL YOHARA, BALATHOR VE AMON! 80. GÜNÜNDE! +10.000 ONLİNE! HİLE VE BOT %100 ENGELLİ HEMEN TIKLA!
Forum'da paylaşılan kadar görüntü odaklı değil ama gayet işlevsel iş görür nitelik de
local-bsd üzerinde Ngix-PHP8-PHP-FPM Kullanıyorum Farklı yerler de denemedim.
Gerekli oldukça güncellerim.
Kurulum için destek yok.
mob_proto.txt,mob_names.txt ve mobproto.php aynı klasörde olmak zorunda
pkg install -y nginx php82 php82-mysqli php82-mbstring php82-gd php82-curl php82-zlib php82-zip php82-xml php82-fpm php82-filter php82-iconv
sysrc nginx_enable="YES"
sysrc php_fpm_enable="YES"
service php-fpm start
service nginx start
/usr/local/etc/nginx/nginx.conf
local-bsd üzerinde Ngix-PHP8-PHP-FPM Kullanıyorum Farklı yerler de denemedim.
Gerekli oldukça güncellerim.
Kurulum için destek yok.
mob_proto.txt,mob_names.txt ve mobproto.php aynı klasörde olmak zorunda
pkg install -y nginx php82 php82-mysqli php82-mbstring php82-gd php82-curl php82-zlib php82-zip php82-xml php82-fpm php82-filter php82-iconv
sysrc nginx_enable="YES"
sysrc php_fpm_enable="YES"
service php-fpm start
service nginx start
/usr/local/etc/nginx/nginx.conf
Kod:
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name localhost;
root /usr/local/www/nginx;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
[CODE lang="php" title="mobproto.php"]<?php
error_reporting(E_ERROR | E_PARSE);
$proto_file = 'mob_proto.txt';
$names_file = 'mob_names.txt';
$limit = 50;
$sayfa = isset($_GET['p']) ? max(1, (int)$_GET['p']) : 1;
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
$offset = ($sayfa - 1) * $limit;
$cols_list = explode("\t", "Vnum Name Rank Type BattleType Level Size AiFlags MountCapacity RaceFlags ImmuneFlags Empire Folder OnClick St Dx Ht Iq MinDamage MaxDamage MaxHp RegenCycle RegenPercent MinGold MaxGold Exp Def AttackSpeed MoveSpeed AggressiveHpPct AggressiveSight AttackRange DropItemGroup ResurrectionVnum EnchantCurse EnchantSlow EnchantPoison EnchantStun EnchantCritical EnchantPenetrate ResistSword ResistTwoHanded ResistDagger ResistBell ResistFan ResistBow ResistFire ResistElect ResistMagic ResistWind ResistPoison DamMultiply SummonVnum DrainSp MobColor PolymorphItem SkillLevel0 SkillVnum0 SkillLevel1 SkillVnum1 SkillLevel2 SkillVnum2 SkillLevel3 SkillVnum3 SkillLevel4 SkillVnum4 SpBerserk SpStoneSkin SpGodSpeed SpDeathBlow SpRevive");
$mob_names = [];
if (file_exists($names_file)) {
foreach (file($names_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
$parts = explode("\t", $line);
if (count($parts) >= 2) $mob_names[trim($parts[0])] = trim($parts[1]);
}
}
// 1. KAYIT İŞLEMİ (GÜNCELLEME)
if (isset($_POST['confirm_bulk_save'])) {
$updates = json_decode($_POST['bulk_data'], true);
if ($updates) {
$full = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$header_line = $full[0]; unset($full[0]);
$proto_dict = [];
foreach($full as $line) {
$p = explode("\t", $line);
$proto_dict[trim($p[0])] = $line;
}
foreach ($updates as $vnum => $new_row_array) {
$proto_dict[$vnum] = implode("\t", array_map('trim', $new_row_array));
if(isset($new_row_array[1])) $mob_names[$vnum] = $new_row_array[1];
}
$out = [$header_line];
foreach($proto_dict as $line) $out[] = $line;
file_put_contents($proto_file, implode("\n", $out) . "\n");
$n_out = [];
foreach($mob_names as $nv => $nn) $n_out[] = $nv . "\t" . $nn;
file_put_contents($names_file, implode("\n", $n_out) . "\n");
header("Location: ".$_SERVER['PHP_SELF']."?p=$sayfa&search=".urlencode($search)); exit;
}
}
// 2. YENİ MOB EKLE
if (isset($_POST['tam_ekle'])) {
$yeni_data = $_POST['yeni'];
$yeni_vnum = trim($yeni_data[0]);
if(!empty($yeni_vnum)) {
$proto_lines = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$exists = false;
foreach($proto_lines as $l) { if(trim(explode("\t", $l)[0]) == $yeni_vnum) { $exists = true; break; } }
if ($exists) { $error_msg = "HATA: $yeni_vnum mevcut!"; }
else {
$proto_lines[] = implode("\t", array_map('trim', $yeni_data));
file_put_contents($proto_file, implode("\n", $proto_lines) . "\n");
$n_lines = file($names_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$n_lines[] = $yeni_vnum . "\t" . trim($yeni_data[1]);
file_put_contents($names_file, implode("\n", $n_lines) . "\n");
header("Location: ".$_SERVER['PHP_SELF']."?search=".$yeni_vnum); exit;
}
}
}
// 3. MOB SİL
if (isset($_GET['sil'])) {
$target = trim($_GET['sil']);
foreach([$proto_file, $names_file] as $f) {
$lines = file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$new = []; foreach($lines as $l) if(trim(explode("\t", $l)[0]) != $target) $new[] = $l;
file_put_contents($f, implode("\n", $new) . "\n");
}
header("Location: ".$_SERVER['PHP_SELF']."?p=$sayfa&search=$search"); exit;
}
// Verileri Hazırla
$proto_all = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$header_row = $proto_all[0];
unset($proto_all[0]);
// --- SON 5 MOB BÖLÜMÜ ---
$last_5_raw = array_slice($proto_all, -5);
$recent_list = [];
foreach(array_reverse($last_5_raw) as $line) {
$p = explode("\t", $line);
$v = trim($p[0]);
$recent_list[] = ['vnum' => $v, 'name' => $mob_names[$v] ?? (isset($p[1]) ? trim($p[1]) : 'NONAME')];
}
// ------------------------
$filtered = [];
foreach ($proto_all as $line) {
$parts = explode("\t", $line); $v = trim($parts[0]);
$n = $mob_names[$v] ?? (isset($parts[1]) ? trim($parts[1]) : 'NONAME');
if ($search === '' || stripos($v, $search) !== false || stripos($n, $search) !== false) {
$clean = [];
for($i=0; $i<count($cols_list); $i++) {
$val = isset($parts[$i]) ? trim($parts[$i]) : "0";
if($i==1) $val = $n;
$clean[] = $val;
}
$filtered[] = $clean;
}
}
$total_pages = max(1, ceil(count($filtered) / $limit));
$current_data = array_slice($filtered, $offset, $limit);
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>MOB PROTO DÜZENLEYİCİ</title>
<style>
:root { --accent: #e74c3c; --bg: #0d1117; --panel:#e74c3c2; --bor#0d11170363d; --ho#161b221262d; --suc#30363d238636; }
#21262dbody { backgr#238636ar(--bg); color: #c9d1d9; font-family: sans-serif#c9d1d9n: 0; overflow: hidden; height: 100vh; }
header { background: #010409; height: 60px; display: #010409lign-items: center; padding: 0 20px; gap: 15px; border-bottom: 2px solid var(--accent); }
.recent-bar { background: #010409; padding: 5px 20px; bord#010409om: 1px solid var(--border); display: flex; gap: 10px; align-items: center; font-size: 11px; overflow-x: auto; white-space: nowrap; }
.recent-item { color: #7ee787; text-decoration: none; #7ee787: 2px 8px; background: var(--panel); border-radius: 4px; border: 1px solid var(--border); }
.recent-item:hover { border-color: var(--accent); }
.viewport { height: calc(100vh - 95px); width: 100%; overflow: auto; }
table { border-collapse: separate; border-spacing: 0; width: max-content; }
th { background: #1c2128; padding: 10px; border-b#1c21281px solid var(--border); border-right: 1px solid var(--border); position: sticky; top: 0; z-index: 100; font-size: 11px; }
tbody tr:hover td { background: var(--hover) !important; }
.sticky-col { position: sticky; background: #0d1117; z-index: 80; }
#0d1117l { left: 0; width: 40px; text-align: center; }
.col-vnum { left: 40px; width: 80px; color: var(--accent); font-weight: bold; border-right: 2px solid var(--accent); }
.col-name { left: 120px; width: 160px; color: #7ee787; border-right: 2px solid#7ee787accent); }
td { border-bottom: 1px solid var(--border); border-right: 1px solid var(--border); }
input.cell { background: transparent; border: 1px solid transparent; color: #fff; padding: 8px; width: 100%;#fffline: none; font-size: 12px; }
input.cell:focus { background: rgba(31, 111, 235, 0.2) !important; border: 1px solid #1f6feb !important; }
in#1f6febnged { background: rgba(35, 134, 54, 0.3) !important; border: 1px solid var(--success) !important; }
.btn { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; color: white; font-size: 12px; text-decoration: none; display: inline-flex; align-items: center; }
.btn-save { background: #238636; } .btn-add { background#238636-accent); } .btn-nav { background: #30363d; }
.modal { disp#30363dne; position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 9999; padding: 40px; }
.modal-content { background: var(--panel); padding: 25px; border-radius: 8px; max-width: 900px; margin: auto; border: 1px solid var(--accent); max-height: 80vh; overflow-y: auto; }
.diff-row { border-bottom: 1px solid var(--border); padding: 8px; font-family: monospace; font-size: 12px; line-height: 1.5; }
</style>
</head>
<body>
<?php if(isset($error_msg)): ?><script>alert("<?=str_replace('"', '\"', $error_msg)?>");</script><?php endif; ?>
<header>
<a href="<?=$_SERVER['PHP_SELF']?>" class="btn" style="background:none; font-size:16px; padding:0; color:var(--accent); font-weight:bold;">
MOB PROTO</a><form method="GET" style="display:flex; align-items:center;">
<input type="text" name="search" style="background: #0d1117; border: 1px solid var(--bo#0d1117color: white; padding: 5px 10px; border-radius: 4px; outline: none;" placeholder="Vnum veya İsim..." value="<?=htmlspecialchars($search)?>">
</form>
<div style="display:flex; gap:5px; font-size:11px;">
<a href="?p=<?=max(1, $sayfa-1)?>&search=<?=$search?>" class="btn btn-nav">«</a>
<span style="margin-top:7px; min-width:40px; text-align:center;"><?=$sayfa?> / <?=$total_pages?></span>
<a href="?p=<?=min($total_pages, $sayfa+1)?>&search=<?=$search?>" class="btn btn-nav">»</a>
</div>
<button onclick="document.getElementById('addModal').style.display='block'" class="btn btn-add">+ YENİ MOB</button>
<button onclick="saveCheck()" class="btn btn-save">DEĞİŞİKLİKLERİ KAYDET</button>
<div style="margin-left:auto; color:var(--accent); font-weight:bold; font-size:12px;">ORHAN BULUT</div>
</header>
<div class="recent-bar">
<b style="color:var(--accent)">SON EKLENENLER:</b>
<?php foreach($recent_list as $rm): ?>
<a href="?search=<?=$rm['vnum']?>" class="recent-item">[<?=$rm['vnum']?>] <?=$rm['name']?></a>
<?php endforeach; ?>
</div>
<div class="viewport">
<table>
<thead>
<tr>
<th class="sticky-col col-sil">SİL</th>
<?php foreach($cols_list as $k => $b): ?>
<th class="<?=($k==0?'sticky-col col-vnum'
$k==1?'sticky-col col-name':''))?>"><?=$b?></th><?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($current_data as $row): $v = $row[0]; $name = $row[1]; ?>
<tr>
<td class="sticky-col col-sil"><a href="?sil=<?=$v?>&p=<?=$sayfa?>&search=<?=$search?>" style="color:var(--accent); text-decoration:none;" onclick="return confirm('<?=$v?> silinecek?')">×</a></td>
<?php foreach ($row as $i => $val): $cl = ($i==0?'sticky-col col-vnum'
$i==1?'sticky-col col-name':'')); ?><td class="<?=$cl?>"><input type="text" class="cell" data-vnum="<?=$v?>" data-name="<?=htmlspecialchars($name)?>" data-orig="<?=htmlspecialchars($val)?>" data-idx="<?=$i?>" value="<?=htmlspecialchars($val)?>" oninput="track(this)"></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div id="saveModal" class="modal">
<div class="modal-content">
<h2 style="color:var(--accent); margin-top:0;">Değişiklik Özeti</h2>
<div id="diffArea" style="background:#000; padding:10px; border-radius:4px; margin-bottom:20px; border:1px solid var(--border);"></div>
<form method="POST">
<input type="hidden" name="bulk_data" id="bulk_data_input">
<button type="submit" name="confirm_bulk_save" class="btn btn-save" style="width:100%; padding:12px;">ONAYLA VE KAYDET</button>
<button type="button" onclick="document.getElementById('saveModal').style.display='none'" class="btn btn-nav" style="width:100%; margin-top:10px;">İPTAL</button>
</form>
</div>
</div>
<div id="addModal" class="modal">
<div class="modal-content" style="max-width:1000px;">
<h2 style="color:var(--accent); margin-top:0;">Yeni Mob Ekle</h2>
<form method="POST">
<div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap:10px;">
<?php foreach($cols_list as $i => $name): ?>
<div><label style="font-size:10px; color:#8b949e;"><?=$name?></label><br>
<input type="text" name="yeni[<?=$i?>]" value="<?=$i>1?'0':''?>" style="width:100%; background:#000; color:#fff; border:1px solid var(--border); padding:5px;"></div>
<?php endforeach; ?>
</div>
<button type="submit" name="tam_ekle" class="btn btn-save" style="width:100%; margin-top:20px; padding:12px;">MOB'U EKLE</button>
<button type="button" onclick="document.getElementById('addModal').style.display='none'" class="btn btn-nav" style="width:100%; margin-top:10px;">VAZGEÇ</button>
</form>
</div>
</div>
<script>
const COL_NAMES = <?=json_encode($cols_list)?>;
function track(el) {
if (el.value.trim() !== el.getAttribute('data-orig').trim()) el.classList.add('changed');
else el.classList.remove('changed');
}
function saveCheck() {
let diffs = ""; let updates = {}; let found = false;
document.querySelectorAll('input.cell').forEach(inp => {
let cur = inp.value.trim();
let ori = inp.getAttribute('data-orig').trim();
if (cur !== ori) {
found = true;
let v = inp.getAttribute('data-vnum');
if (!updates[v]) {
updates[v] = [];
document.querySelectorAll(`input.cell[data-vnum="${v}"]`).forEach(i => updates[v][i.getAttribute('data-idx')] = i.value.trim());
}
diffs += `<div class="diff-row"><span style="color:var(--accent)">[${v}]</span> <b>${inp.getAttribute('data-name')}</b> <br> <span style="color:#8b949e">${COL_NAMES[inp.getAttribute('data-idx')]}</span>: <span style="color:#e74c3c">${ori}</span> → <span style="color:#2ecc71">${cur}</span></div>`;
}
});
if (!found) { alert("Değişiklik yok."); return; }
document.getElementById('diffArea').innerHTML = diffs;
document.getElementById('bulk_data_input').value = JSON.stringify(updates);
document.getElementById('saveModal').style.display = 'block';
}
</script>
</body>
</html>[/CODE]
- Katılım
- 1 Tem 2019
- Konular
- 1,893
- Mesajlar
- 5,201
- Çözüm
- 134
- Online süresi
- 1mo 8d
- Reaksiyon Skoru
- 4,001
- Altın Konu
- 140
- Başarım Puanı
- 339
- MmoLira
- 39,500
- DevLira
- 150
PAYLAŞIM İÇİN TEŞEKKÜRLER ELİNE SAĞLIK .
- Katılım
- 20 Kas 2025
- Konular
- 131
- Mesajlar
- 843
- Çözüm
- 4
- Online süresi
- 14d 15h
- Reaksiyon Skoru
- 878
- Altın Konu
- 19
- Başarım Puanı
- 163
- Yaş
- 32
- MmoLira
- 9,297
- DevLira
- 3
Paylaşım için teşekkürler, emeğine sağlık.Forum'da paylaşılan kadar görüntü odaklı değil ama gayet işlevsel iş görür nitelik de
local-bsd üzerinde Ngix-PHP8-PHP-FPM Kullanıyorum Farklı yerler de denemedim.
Gerekli oldukça güncellerim.
Kurulum için destek yok.
mob_proto.txt,mob_names.txt ve mobproto.php aynı klasörde olmak zorunda
pkg install -y nginx php82 php82-mysqli php82-mbstring php82-gd php82-curl php82-zlib php82-zip php82-xml php82-fpm php82-filter php82-iconv
sysrc nginx_enable="YES"
sysrc php_fpm_enable="YES"
service php-fpm start
service nginx start
/usr/local/etc/nginx/nginx.conf
Kod:worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; server { listen 80; server_name localhost; root /usr/local/www/nginx; index index.php index.html; location / { try_files $uri $uri/ =404; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } }
Ekli dosyayı görüntüle 165629
Ekli dosyayı görüntüle 165630
Ekli dosyayı görüntüle 165631
Ekli dosyayı görüntüle 165632
Ekli dosyayı görüntüle 165633
[CODE lang="php" title="mobproto.php"]<?php
error_reporting(E_ERROR | E_PARSE);
$proto_file = 'mob_proto.txt';
$names_file = 'mob_names.txt';
$limit = 50;
$sayfa = isset($_GET['p']) ? max(1, (int)$_GET['p']) : 1;
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
$offset = ($sayfa - 1) * $limit;
$cols_list = explode("\t", "Vnum Name Rank Type BattleType Level Size AiFlags MountCapacity RaceFlags ImmuneFlags Empire Folder OnClick St Dx Ht Iq MinDamage MaxDamage MaxHp RegenCycle RegenPercent MinGold MaxGold Exp Def AttackSpeed MoveSpeed AggressiveHpPct AggressiveSight AttackRange DropItemGroup ResurrectionVnum EnchantCurse EnchantSlow EnchantPoison EnchantStun EnchantCritical EnchantPenetrate ResistSword ResistTwoHanded ResistDagger ResistBell ResistFan ResistBow ResistFire ResistElect ResistMagic ResistWind ResistPoison DamMultiply SummonVnum DrainSp MobColor PolymorphItem SkillLevel0 SkillVnum0 SkillLevel1 SkillVnum1 SkillLevel2 SkillVnum2 SkillLevel3 SkillVnum3 SkillLevel4 SkillVnum4 SpBerserk SpStoneSkin SpGodSpeed SpDeathBlow SpRevive");
$mob_names = [];
if (file_exists($names_file)) {
foreach (file($names_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
$parts = explode("\t", $line);
if (count($parts) >= 2) $mob_names[trim($parts[0])] = trim($parts[1]);
}
}
// 1. KAYIT İŞLEMİ (GÜNCELLEME)
if (isset($_POST['confirm_bulk_save'])) {
$updates = json_decode($_POST['bulk_data'], true);
if ($updates) {
$full = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$header_line = $full[0]; unset($full[0]);
$proto_dict = [];
foreach($full as $line) {
$p = explode("\t", $line);
$proto_dict[trim($p[0])] = $line;
}
foreach ($updates as $vnum => $new_row_array) {
$proto_dict[$vnum] = implode("\t", array_map('trim', $new_row_array));
if(isset($new_row_array[1])) $mob_names[$vnum] = $new_row_array[1];
}
$out = [$header_line];
foreach($proto_dict as $line) $out[] = $line;
file_put_contents($proto_file, implode("\n", $out) . "\n");
$n_out = [];
foreach($mob_names as $nv => $nn) $n_out[] = $nv . "\t" . $nn;
file_put_contents($names_file, implode("\n", $n_out) . "\n");
header("Location: ".$_SERVER['PHP_SELF']."?p=$sayfa&search=".urlencode($search)); exit;
}
}
// 2. YENİ MOB EKLE
if (isset($_POST['tam_ekle'])) {
$yeni_data = $_POST['yeni'];
$yeni_vnum = trim($yeni_data[0]);
if(!empty($yeni_vnum)) {
$proto_lines = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$exists = false;
foreach($proto_lines as $l) { if(trim(explode("\t", $l)[0]) == $yeni_vnum) { $exists = true; break; } }
if ($exists) { $error_msg = "HATA: $yeni_vnum mevcut!"; }
else {
$proto_lines[] = implode("\t", array_map('trim', $yeni_data));
file_put_contents($proto_file, implode("\n", $proto_lines) . "\n");
$n_lines = file($names_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$n_lines[] = $yeni_vnum . "\t" . trim($yeni_data[1]);
file_put_contents($names_file, implode("\n", $n_lines) . "\n");
header("Location: ".$_SERVER['PHP_SELF']."?search=".$yeni_vnum); exit;
}
}
}
// 3. MOB SİL
if (isset($_GET['sil'])) {
$target = trim($_GET['sil']);
foreach([$proto_file, $names_file] as $f) {
$lines = file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$new = []; foreach($lines as $l) if(trim(explode("\t", $l)[0]) != $target) $new[] = $l;
file_put_contents($f, implode("\n", $new) . "\n");
}
header("Location: ".$_SERVER['PHP_SELF']."?p=$sayfa&search=$search"); exit;
}
// Verileri Hazırla
$proto_all = file($proto_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$header_row = $proto_all[0];
unset($proto_all[0]);
// --- SON 5 MOB BÖLÜMÜ ---
$last_5_raw = array_slice($proto_all, -5);
$recent_list = [];
foreach(array_reverse($last_5_raw) as $line) {
$p = explode("\t", $line);
$v = trim($p[0]);
$recent_list[] = ['vnum' => $v, 'name' => $mob_names[$v] ?? (isset($p[1]) ? trim($p[1]) : 'NONAME')];
}
// ------------------------
$filtered = [];
foreach ($proto_all as $line) {
$parts = explode("\t", $line); $v = trim($parts[0]);
$n = $mob_names[$v] ?? (isset($parts[1]) ? trim($parts[1]) : 'NONAME');
if ($search === '' || stripos($v, $search) !== false || stripos($n, $search) !== false) {
$clean = [];
for($i=0; $i<count($cols_list); $i++) {
$val = isset($parts[$i]) ? trim($parts[$i]) : "0";
if($i==1) $val = $n;
$clean[] = $val;
}
$filtered[] = $clean;
}
}
$total_pages = max(1, ceil(count($filtered) / $limit));
$current_data = array_slice($filtered, $offset, $limit);
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>MOB PROTO DÜZENLEYİCİ</title>
<style>
:root { --accent: #e74c3c; --bg: #0d1117; --panel:#e74c3c2; --bor#0d11170363d; --ho#161b221262d; --suc#30363d238636; }
#21262dbody { backgr#238636ar(--bg); color: #c9d1d9; font-family: sans-serif#c9d1d9n: 0; overflow: hidden; height: 100vh; }
header { background: #010409; height: 60px; display: #010409lign-items: center; padding: 0 20px; gap: 15px; border-bottom: 2px solid var(--accent); }
.recent-bar { background: #010409; padding: 5px 20px; bord#010409om: 1px solid var(--border); display: flex; gap: 10px; align-items: center; font-size: 11px; overflow-x: auto; white-space: nowrap; }
.recent-item { color: #7ee787; text-decoration: none; #7ee787: 2px 8px; background: var(--panel); border-radius: 4px; border: 1px solid var(--border); }
.recent-item:hover { border-color: var(--accent); }
.viewport { height: calc(100vh - 95px); width: 100%; overflow: auto; }
table { border-collapse: separate; border-spacing: 0; width: max-content; }
th { background: #1c2128; padding: 10px; border-b#1c21281px solid var(--border); border-right: 1px solid var(--border); position: sticky; top: 0; z-index: 100; font-size: 11px; }
tbody tr:hover td { background: var(--hover) !important; }
.sticky-col { position: sticky; background: #0d1117; z-index: 80; }
#0d1117l { left: 0; width: 40px; text-align: center; }
.col-vnum { left: 40px; width: 80px; color: var(--accent); font-weight: bold; border-right: 2px solid var(--accent); }
.col-name { left: 120px; width: 160px; color: #7ee787; border-right: 2px solid#7ee787accent); }
td { border-bottom: 1px solid var(--border); border-right: 1px solid var(--border); }
input.cell { background: transparent; border: 1px solid transparent; color: #fff; padding: 8px; width: 100%;#fffline: none; font-size: 12px; }
input.cell:focus { background: rgba(31, 111, 235, 0.2) !important; border: 1px solid #1f6feb !important; }
in#1f6febnged { background: rgba(35, 134, 54, 0.3) !important; border: 1px solid var(--success) !important; }
.btn { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; color: white; font-size: 12px; text-decoration: none; display: inline-flex; align-items: center; }
.btn-save { background: #238636; } .btn-add { background#238636-accent); } .btn-nav { background: #30363d; }
.modal { disp#30363dne; position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 9999; padding: 40px; }
.modal-content { background: var(--panel); padding: 25px; border-radius: 8px; max-width: 900px; margin: auto; border: 1px solid var(--accent); max-height: 80vh; overflow-y: auto; }
.diff-row { border-bottom: 1px solid var(--border); padding: 8px; font-family: monospace; font-size: 12px; line-height: 1.5; }
</style>
</head>
<body>
<?php if(isset($error_msg)): ?><script>alert("<?=str_replace('"', '\"', $error_msg)?>");</script><?php endif; ?>
<header>
<a href="<?=$_SERVER['PHP_SELF']?>" class="btn" style="background:none; font-size:16px; padding:0; color:var(--accent); font-weight:bold;">MOB PROTO</a>
<form method="GET" style="display:flex; align-items:center;">
<input type="text" name="search" style="background: #0d1117; border: 1px solid var(--bo#0d1117color: white; padding: 5px 10px; border-radius: 4px; outline: none;" placeholder="Vnum veya İsim..." value="<?=htmlspecialchars($search)?>">
</form>
<div style="display:flex; gap:5px; font-size:11px;">
<a href="?p=<?=max(1, $sayfa-1)?>&search=<?=$search?>" class="btn btn-nav">«</a>
<span style="margin-top:7px; min-width:40px; text-align:center;"><?=$sayfa?> / <?=$total_pages?></span>
<a href="?p=<?=min($total_pages, $sayfa+1)?>&search=<?=$search?>" class="btn btn-nav">»</a>
</div>
<button onclick="document.getElementById('addModal').style.display='block'" class="btn btn-add">+ YENİ MOB</button>
<button onclick="saveCheck()" class="btn btn-save">DEĞİŞİKLİKLERİ KAYDET</button>
<div style="margin-left:auto; color:var(--accent); font-weight:bold; font-size:12px;">ORHAN BULUT</div>
</header>
<div class="recent-bar">
<b style="color:var(--accent)">SON EKLENENLER:</b>
<?php foreach($recent_list as $rm): ?>
<a href="?search=<?=$rm['vnum']?>" class="recent-item">[<?=$rm['vnum']?>] <?=$rm['name']?></a>
<?php endforeach; ?>
</div>
<div class="viewport">
<table>
<thead>
<tr>
<th class="sticky-col col-sil">SİL</th>
<?php foreach($cols_list as $k => $b): ?>
<th class="<?=($k==0?'sticky-col col-vnum'$k==1?'sticky-col col-name':''))?>"><?=$b?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($current_data as $row): $v = $row[0]; $name = $row[1]; ?>
<tr>
<td class="sticky-col col-sil"><a href="?sil=<?=$v?>&p=<?=$sayfa?>&search=<?=$search?>" style="color:var(--accent); text-decoration:none;" onclick="return confirm('<?=$v?> silinecek?')">×</a></td>
<?php foreach ($row as $i => $val): $cl = ($i==0?'sticky-col col-vnum'$i==1?'sticky-col col-name':'')); ?>
<td class="<?=$cl?>"><input type="text" class="cell" data-vnum="<?=$v?>" data-name="<?=htmlspecialchars($name)?>" data-orig="<?=htmlspecialchars($val)?>" data-idx="<?=$i?>" value="<?=htmlspecialchars($val)?>" oninput="track(this)"></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div id="saveModal" class="modal">
<div class="modal-content">
<h2 style="color:var(--accent); margin-top:0;">Değişiklik Özeti</h2>
<div id="diffArea" style="background:#000; padding:10px; border-radius:4px; margin-bottom:20px; border:1px solid var(--border);"></div>
<form method="POST">
<input type="hidden" name="bulk_data" id="bulk_data_input">
<button type="submit" name="confirm_bulk_save" class="btn btn-save" style="width:100%; padding:12px;">ONAYLA VE KAYDET</button>
<button type="button" onclick="document.getElementById('saveModal').style.display='none'" class="btn btn-nav" style="width:100%; margin-top:10px;">İPTAL</button>
</form>
</div>
</div>
<div id="addModal" class="modal">
<div class="modal-content" style="max-width:1000px;">
<h2 style="color:var(--accent); margin-top:0;">Yeni Mob Ekle</h2>
<form method="POST">
<div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap:10px;">
<?php foreach($cols_list as $i => $name): ?>
<div><label style="font-size:10px; color:#8b949e;"><?=$name?></label><br>
<input type="text" name="yeni[<?=$i?>]" value="<?=$i>1?'0':''?>" style="width:100%; background:#000; color:#fff; border:1px solid var(--border); padding:5px;"></div>
<?php endforeach; ?>
</div>
<button type="submit" name="tam_ekle" class="btn btn-save" style="width:100%; margin-top:20px; padding:12px;">MOB'U EKLE</button>
<button type="button" onclick="document.getElementById('addModal').style.display='none'" class="btn btn-nav" style="width:100%; margin-top:10px;">VAZGEÇ</button>
</form>
</div>
</div>
<script>
const COL_NAMES = <?=json_encode($cols_list)?>;
function track(el) {
if (el.value.trim() !== el.getAttribute('data-orig').trim()) el.classList.add('changed');
else el.classList.remove('changed');
}
function saveCheck() {
let diffs = ""; let updates = {}; let found = false;
document.querySelectorAll('input.cell').forEach(inp => {
let cur = inp.value.trim();
let ori = inp.getAttribute('data-orig').trim();
if (cur !== ori) {
found = true;
let v = inp.getAttribute('data-vnum');
if (!updates[v]) {
updates[v] = [];
document.querySelectorAll(`input.cell[data-vnum="${v}"]`).forEach(i => updates[v][i.getAttribute('data-idx')] = i.value.trim());
}
diffs += `<div class="diff-row"><span style="color:var(--accent)">[${v}]</span> <b>${inp.getAttribute('data-name')}</b> <br> <span style="color:#8b949e">${COL_NAMES[inp.getAttribute('data-idx')]}</span>: <span style="color:#e74c3c">${ori}</span> → <span style="color:#2ecc71">${cur}</span></div>`;
}
});
if (!found) { alert("Değişiklik yok."); return; }
document.getElementById('diffArea').innerHTML = diffs;
document.getElementById('bulk_data_input').value = JSON.stringify(updates);
document.getElementById('saveModal').style.display = 'block';
}
</script>
</body>
</html>[/CODE]
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 2
- Görüntüleme
- 56
- Cevaplar
- 2
- Görüntüleme
- 56
- Cevaplar
- 0
- Görüntüleme
- 164
- Cevaplar
- 1
- Görüntüleme
- 75















