Commit 2db09b20 authored by Nemo Ma's avatar Nemo Ma

fix(admin): resolve resourcemng template parse error

parent 7d154693
...@@ -22,6 +22,7 @@ $admin_cmd_list = Array( ...@@ -22,6 +22,7 @@ $admin_cmd_list = Array(
'roommng' => 5, 'roommng' => 5,
'antiAFKmng' => 4, 'antiAFKmng' => 4,
'templates_clean' => 4, 'templates_clean' => 4,
'resourcemng' => 7,
); );
if(!$cuser||!$cpass) { gexit($_ERROR['no_login'],__file__,__line__); } if(!$cuser||!$cpass) { gexit($_ERROR['no_login'],__file__,__line__); }
......
...@@ -257,6 +257,8 @@ $lang = array ...@@ -257,6 +257,8 @@ $lang = array
'templates_clean_comment' => '清空已生成的模板缓存文件', 'templates_clean_comment' => '清空已生成的模板缓存文件',
'roommng' => '临时性房间管理', 'roommng' => '临时性房间管理',
'roommng_comment' => '强制关闭指定编号的房间<br>不能关闭0号大房间(临时功能)', 'roommng_comment' => '强制关闭指定编号的房间<br>不能关闭0号大房间(临时功能)',
'resourcemng' => '游戏资源管理',
'resourcemng_comment' => '管理地图物品/商店/开局物品与NPC配置,支持按RuleSet编辑',
'pcmng' => '玩家数据管理', 'pcmng' => '玩家数据管理',
'pcmng_comment' => '修改当前局玩家的各数值,不影响帐号', 'pcmng_comment' => '修改当前局玩家的各数值,不影响帐号',
......
<?php
if(!defined('IN_ADMIN')) {
exit('Access Denied');
}
if(!isset($res_type)) $res_type = 'mapitem';
if(!isset($start)) $start = 0;
if(!isset($pagemode)) $pagemode = '';
if(!isset($keyword)) $keyword = '';
if(!isset($ruleset)) $ruleset = '__default__';
if(!isset($action)) $action = 'list';
if(isset($edit_id)) {
$action = 'edit';
$record_id = intval($edit_id);
}
if(isset($delete_id)) {
$action = 'delete';
$record_id = intval($delete_id);
}
$start = getstart($start,$pagemode);
$keyword = trim($keyword);
$res_type = in_array($res_type, array('mapitem','shopitem','stitem','stwep','npc')) ? $res_type : 'mapitem';
$ruleset = preg_match('/^[A-Za-z0-9_]+$/', $ruleset) ? $ruleset : '__default__';
$ruleset_list = resourcemng_get_rulesets($res_type);
if(!isset($ruleset_list[$ruleset])) $ruleset = '__default__';
$target_file = $ruleset_list[$ruleset]['file'];
$allow_upload = ($mygroup > 10);
if($action === 'download') {
if(file_exists($target_file)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($target_file).'"');
header('Content-Length: '.filesize($target_file));
readfile($target_file);
adminlog('resourcemng_download',$res_type,$ruleset,basename($target_file));
exit;
}
$cmd_info = '下载失败:目标文件不存在。';
}
if($action === 'upload' && $allow_upload) {
if(!empty($_FILES['cfgfile']['tmp_name']) && is_uploaded_file($_FILES['cfgfile']['tmp_name'])) {
$uploaded = file_get_contents($_FILES['cfgfile']['tmp_name']);
if($uploaded !== false && strlen($uploaded) > 0) {
if(@file_put_contents($target_file, $uploaded) !== false) {
$cmd_info = '上传覆盖成功。';
adminlog('resourcemng_upload',$res_type,$ruleset,$_FILES['cfgfile']['name']);
} else {
$cmd_info = '上传失败:写入文件失败。';
}
} else {
$cmd_info = '上传失败:文件内容为空或不可读。';
}
} else {
$cmd_info = '上传失败:未检测到上传文件。';
}
}
$resource = resourcemng_read_data($res_type, $target_file);
$records = $resource['records'];
$header = $resource['header'];
$columns = $resource['columns'];
if($action === 'save_record') {
$id = isset($record_id) ? intval($record_id) : -1;
if(isset($records[$id])) {
$new_row = resourcemng_collect_row($res_type, $_POST, $records[$id]);
$valid = resourcemng_validate_row($res_type, $new_row, $err);
if($valid) {
$records[$id] = $new_row;
if(resourcemng_write_data($res_type, $target_file, $header, $records)) {
$cmd_info = '记录已保存。';
adminlog('resourcemng_edit',$res_type,$ruleset,$id);
} else {
$cmd_info = '保存失败:写入文件失败。';
}
} else {
$cmd_info = '保存失败:'.$err;
}
} else {
$cmd_info = '保存失败:记录不存在。';
}
$resource = resourcemng_read_data($res_type, $target_file);
$records = $resource['records'];
}
if($action === 'delete') {
$id = isset($record_id) ? intval($record_id) : -1;
if(isset($records[$id])) {
unset($records[$id]);
$records = array_values($records);
if(resourcemng_write_data($res_type, $target_file, $header, $records)) {
$cmd_info = '记录已删除。';
adminlog('resourcemng_delete',$res_type,$ruleset,$id);
} else {
$cmd_info = '删除失败:写入文件失败。';
}
}
$resource = resourcemng_read_data($res_type, $target_file);
$records = $resource['records'];
}
if($action === 'add') {
$new_row = resourcemng_collect_row($res_type, $_POST, array());
$valid = resourcemng_validate_row($res_type, $new_row, $err);
if($valid) {
if($res_type === 'npc' && isset($record_id) && intval($record_id) >= 0) $records[intval($record_id)] = $new_row;
else $records[] = $new_row;
if(resourcemng_write_data($res_type, $target_file, $header, $records)) {
$cmd_info = '新记录已添加。';
adminlog('resourcemng_add',$res_type,$ruleset,'new');
} else {
$cmd_info = '新增失败:写入文件失败。';
}
} else {
$cmd_info = '新增失败:'.$err;
}
$resource = resourcemng_read_data($res_type, $target_file);
$records = $resource['records'];
}
$edit_record = array();
if($action === 'edit' && isset($record_id)) {
$id = intval($record_id);
if(isset($records[$id])) $edit_record = $records[$id];
}
$filtered = array();
foreach($records as $i => $row) {
$ok = true;
if($keyword !== '') {
$src = is_array($row) ? json_encode($row,JSON_UNESCAPED_UNICODE) : strval($row);
if(stripos($src, $keyword) === false) $ok = false;
}
if($ok) {
$row['_idx'] = $i;
if($res_type === 'npc') {
$row['_sub_count'] = (isset($row['sub']) && is_array($row['sub'])) ? count($row['sub']) : 0;
}
$filtered[] = $row;
}
}
$total_count = count($filtered);
$paged_records = array_slice($filtered, $start, $showlimit);
$resultinfo = '第'.($total_count?($start+1):0).'条-第'.($start+count($paged_records)).'条 / 共'.$total_count.'条';
include template('admin_resourcemng');
function resourcemng_get_rulesets($res_type){
$map = array(
'mapitem' => 'mapitem_1.php',
'shopitem' => 'shopitem_1.php',
'stitem' => 'stitem_1.php',
'stwep' => 'stwep_1.php',
'npc' => 'npc_1.php',
);
$list = array();
$list['__default__'] = array('name' => '默认配置', 'file' => GAME_ROOT.'./gamedata/cache/'.$map[$res_type]);
$ruleset_root = GAME_ROOT.'./gamedata/ruleset';
if(is_dir($ruleset_root)) {
foreach(scandir($ruleset_root) as $id) {
if($id === '.' || $id === '..') continue;
if(!preg_match('/^[A-Za-z0-9_]+$/',$id)) continue;
$file = $ruleset_root.'/'.$id.'/cache/'.$map[$res_type];
if(file_exists($file)) {
$list[$id] = array('name' => 'RuleSet: '.$id, 'file' => $file);
}
}
}
return $list;
}
function resourcemng_read_data($res_type, $file){
if($res_type === 'npc') {
if(!defined('IN_GAME')) define('IN_GAME', TRUE);
$npcinit = array(); $npcinfo = array();
include $file;
return array('header' => '', 'records' => $npcinfo, 'columns' => array('key','value_json'), 'type' => 'npc');
}
$raw = file_get_contents($file);
if($raw === false) $raw = '';
$raw = str_replace("\r\n", "\n", $raw);
$lines = explode("\n", $raw);
$header = '';
$data_lines = array();
$in_guard = false;
foreach($lines as $line) {
$trim = trim($line);
if($trim === '') continue;
if(strpos($trim, '<?') === 0) { $in_guard = true; $header .= $line."\n"; continue; }
if($in_guard) {
$header .= $line."\n";
if(strpos($trim, '?>') !== false) $in_guard = false;
continue;
}
if(strpos($trim,'//') === 0) { $header .= $line."\n"; continue; }
$data_lines[] = $line;
}
$records = array();
foreach($data_lines as $line) {
$records[] = array_map('trim', explode(',', $line));
}
$columns = resourcemng_columns($res_type);
return array('header' => $header, 'records' => $records, 'columns' => $columns, 'type' => 'csv');
}
function resourcemng_write_data($res_type, $file, $header, $records){
if($res_type === 'npc') {
$data = "<?php\n\n\tif(!defined('IN_GAME')) exit('Access Denied');\n\n";
$data .= "\t\$npcinit = array\n\t(\n\t\t'name' => '',\t'pass' => 'bra', 'gd' => 'm',\t'icon' => 0,\t'club' => 0,\t\n\t\t'mhp' => 0,\t'msp' => 0,\t'att' => 0,\t'def' => 0,\t'pls' => 0,\t'lvl' => 0,\n\t\t'money' => 0,\t'inf' => '',\t'rage' => 0,\t'pose' => 0,\t'tactic' => 0,\t\n\t\t'killnum' => 0,\t'state' => 1,\t'teamID' => '',\t'teamPass' => '','bid' => 0,\n\t\t'horizon' => 0, 'clbpara' => Array(),\n\t\t'wp' => 0, 'wk' => 0, 'wc' => 0, 'wg' => 0, 'wd' => 0, 'wf' => 0, 'skills' => 0, 'rp' => 0,\n\t);\n";
$data .= "\t\$npcinfo = ".var_export($records, true).";\n?>";
return @file_put_contents($file, $data) !== false;
}
$out = rtrim($header)."\n";
foreach($records as $row) {
$out .= implode(',', $row).",\n";
}
return @file_put_contents($file, $out) !== false;
}
function resourcemng_columns($res_type){
$map = array(
'mapitem' => array('刷新禁区','地图编号','数量','名称','类别','效果值','耐久/次数','属性','itmpara'),
'shopitem' => array('记录类型','分类/出现率','价格/参数','等级','名称','类别','效果值','耐久/次数','属性','itmpara'),
'stitem' => array('名称','类别','效果值','耐久/次数','属性','itmpara'),
'stwep' => array('名称','类别','效果值','耐久/次数','属性','itmpara'),
'npc' => array('NPC类别','配置JSON'),
);
return $map[$res_type];
}
function resourcemng_collect_row($res_type, $input, $default){
if($res_type === 'npc') {
$key = isset($input['record_id']) ? intval($input['record_id']) : -1;
$json = isset($input['npc_json']) ? trim($input['npc_json']) : '';
$arr = $default;
if($key >= 0) {
$decoded = json_decode($json, true);
if(!is_array($decoded)) $decoded = array();
$arr = $decoded;
}
return $arr;
}
$row = $default;
$size = count(resourcemng_columns($res_type));
for($i=0;$i<$size;$i++) {
$val = isset($input['col_'.$i]) ? trim($input['col_'.$i]) : '';
$row[$i] = str_replace(array("\n","\r",','), array('','',','), $val);
}
return $row;
}
function resourcemng_validate_row($res_type, $row, &$err){
$err = '';
if($res_type === 'npc') {
if(!is_array($row)) { $err = 'NPC配置必须为对象数组'; return false; }
return true;
}
if(empty($row) || trim($row[0]) === '') {
$err = '首字段不能为空';
return false;
}
return true;
}
?>
...@@ -91,6 +91,11 @@ ...@@ -91,6 +91,11 @@
<td>$lang['templates_clean_comment']</td> <td>$lang['templates_clean_comment']</td>
<td>$admin_cmd_list['templates_clean']</td> <td>$admin_cmd_list['templates_clean']</td>
</tr> </tr>
<tr height="45px">
<td><input type="submit" style="width:100;height:40;" value="$lang['resourcemng']" onclick="$('command').value='resourcemng'" <!--{if $mygroup < $admin_cmd_list['resourcemng']}-->disabled="true"<!--{/if}-->></td>
<td>$lang['resourcemng_comment']</td>
<td>$admin_cmd_list['resourcemng']</td>
</tr>
<tr height="45px"> <tr height="45px">
<td><input type="submit" style="width:100;height:40;" value="$lang['roommng']" onclick="$('command').value='roommng'" <!--{if $mygroup < $admin_cmd_list['roommng']}-->disabled="true"<!--{/if}-->></td> <td><input type="submit" style="width:100;height:40;" value="$lang['roommng']" onclick="$('command').value='roommng'" <!--{if $mygroup < $admin_cmd_list['roommng']}-->disabled="true"<!--{/if}-->></td>
<td>$lang['roommng_comment']</td> <td>$lang['roommng_comment']</td>
......
<form method="post" name="resmng" action="admin.php" enctype="multipart/form-data">
<input type="hidden" name="mode" value="resourcemng">
<input type="hidden" name="start" value="$start">
<input type="hidden" name="record_id" id="record_id" value="$record_id">
<table class="admin" cellspacing="1" cellpadding="4">
<tr><td colspan="4" class="tdtitle">游戏资源管理</td></tr>
<tr><td>资源类型</td><td><select name="res_type"><option value="mapitem" <!--{if $res_type=='mapitem'}-->selected<!--{/if}-->>地图物品</option><option value="shopitem" <!--{if $res_type=='shopitem'}-->selected<!--{/if}-->>商店物品</option><option value="stitem" <!--{if $res_type=='stitem'}-->selected<!--{/if}-->>开局物品</option><option value="stwep" <!--{if $res_type=='stwep'}-->selected<!--{/if}-->>开局武器</option><option value="npc" <!--{if $res_type=='npc'}-->selected<!--{/if}-->>开局NPC</option></select></td><td>配置来源</td><td><select name="ruleset"><!--{loop $ruleset_list $rid $rinfo}--><option value="$rid" <!--{if $ruleset==$rid}-->selected<!--{/if}-->>$rinfo['name']</option><!--{/loop}--></select><input type="submit" name="action" value="list"></td></tr>
<tr><td>搜索</td><td colspan="3"><input type="text" name="keyword" value="$keyword" style="width:300px;"><input type="submit" name="action" value="list"><span class="yellow">$resultinfo</span></td></tr>
<tr><td>文件操作</td><td colspan="3"><input type="submit" name="action" value="download"><!--{if $allow_upload}--><input type="file" name="cfgfile"><input type="submit" name="action" value="upload"><!--{else}--><span class="grey">上传覆盖仅限管理员等级 &gt; 10</span><!--{/if}--></td></tr>
</table><br>
<!--{if $res_type!='npc'}-->
<table class="admin" cellspacing="1" cellpadding="4"><tr><th>ID</th><!--{loop $columns $i $c}--><th>$c</th><!--{/loop}--><th>操作</th></tr><!--{loop $paged_records $idx $row}--><tr><td>$row['_idx']</td><!--{loop $columns $ci $c}--><td>{$row[$ci]}</td><!--{/loop}--><td><button type="submit" name="edit_id" value="$row['_idx']">编辑</button><button type="submit" name="delete_id" value="$row['_idx']" onclick="return confirm('确认删除该记录?');">删除</button></td></tr><!--{/loop}--></table>
<!--{else}-->
<table class="admin" cellspacing="1" cellpadding="4"><tr><th>NPC类别</th><th>子键数量</th><th>操作</th></tr><!--{loop $paged_records $idx $row}--><tr><td>$row['_idx']</td><td>$row['_sub_count']</td><td><button type="submit" name="edit_id" value="$row['_idx']">编辑</button><button type="submit" name="delete_id" value="$row['_idx']" onclick="return confirm('确认删除该类别?');">删除</button></td></tr><!--{/loop}--></table>
<!--{/if}-->
<br><table class="admin" cellspacing="1" cellpadding="4"><tr><td colspan="2" class="tdtitle">编辑/新增</td></tr>
<!--{if $res_type!='npc'}--><tr><td>ID</td><td><input type="text" name="record_id" value="$record_id"></td></tr><!--{loop $columns $i $c}--><tr><td>$c</td><td><input type="text" name="col_$i" style="width:98%;" value="{$edit_record[$i]}"></td></tr><!--{/loop}--><tr><td colspan="2"><button type="submit" name="action" value="save_record">保存当前ID</button><button type="submit" name="action" value="add">新增记录</button></td></tr>
<!--{else}--><tr><td>NPC类别ID</td><td><input type="text" name="record_id" value="$record_id"></td></tr><tr><td>JSON配置</td><td><textarea name="npc_json" style="width:98%;height:260px;">{eval echo isset($edit_record)?json_encode($edit_record,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT):'';}</textarea></td></tr><tr><td colspan="2"><button type="submit" name="action" value="save_record">保存当前类别</button><button type="submit" name="action" value="add">新增类别</button></td></tr><!--{/if}-->
</table>
<div style="margin-top:8px;"><button type="submit" name="pagemode" value="up">上一页</button><button type="submit" name="pagemode" value="down">下一页</button></div>
</form>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment