avatar_epmak

Как создать ReadItems класс для чтения вещей из MU online?

Автор epmak, 2013 Фев. 09, 11:47

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

____

Проголосовало пользователей: 26

Ключевые слова [SEO] mu onlineразработкаreaditems

epmak

Решил поделиться  моей "читалкой" вещей из базы. Что-то мне подсказывает, что я в очередной раз сделал велосипед, который уже был, но.. как то-так в общем. Кстати, буду рад выслушать критику.

Для чего это надо?(область применения)

Спойлер
Надо это для веб сайта, точнее, для такого веб сайта, где используется база вещей. Подойдет даже для "загона" вещей в базу для веб магазина от савоя(не знаю, есть там подобная функция или нет). По сути это можно назвать инструментом. Подключаем, "суем" файлик с базой вещей и дальше либо загоняем их в базу, либо делаем что-то еще.
[свернуть]

Пример использования:
Спойлер
$robj = new readitem("Item.txt"); //читаем базу
print "<pre>";
print_r($robj->item); //переменная содержит полученные данные
print "</pre>";
[свернуть]

Текст класса.

Спойлер
Не стал сохранять на файлообменник. тут целее будет. Просто требуется скопировать весь код в php файл, например read.php и где-то задействовать.
<?php
/**
* Класс для чтения атрибутов вещей из Item(kor).txt
* by [p4f] epmak
* v 1.3
* last update 12.02.13
**/


#region Описание Возможностей
# Класс предназначен для чтения атрибутов из базы вещей для MuOnline
# подходит для серверов до появления Rage Fighter (s6)
# Читает файл типа Item(kor).txt и возвращает ассоциативный массив с информацией по каждой вещи.
# Как применять:
/*
include "<путь_до_файла_класса>";
$robj = new readitem("Item.txt"); //читаем базу
print "<pre>";
print_r($robj->item); //переменная содержит полученные данные
print "</pre>";
*/
# Формат возвращаеммого массива:
/*      [Weapons]
[index] => 0      Index
[slot] => 0        Slot
[skill] => 0      Skill
[x] => 1          X
[y] => 2          Y
[serial] => 1      Serial
[option] => 1      Option
[drop] => 1        Drop
[level] => 6      Level
[dMin] => 6        MinDmg
[dMax] => 11      MaxDmg
[speed] => 50      AttSpeed
[dur] => 20        Dur
[mdur] => 0        MagDur
[mpow] => 0        MagPower
[lreq] => 0        LvlReq
[sreq] => 40      StrReq
[areq] => 40      AgiReq
[ereq] => 0        EneReq
[vreq] => 0        VitReq
[creq] => 0        CmdReq
[sattr] => 1      SetAttr
[dw] => 1          DW/SM
[dk] => 1          DK/BK
[elf] => 1        ELF/ME
[mg] => 1          MG
[dl] => 1          DL
[sum] => 1        SUM
[name] => Kris    Name
[group] => 0      Item Group
*/
#Более подробно смотрите легенду в Item(Kor).txt все сделано по ней для всех групп вещей
#end

/*
директива для медленных серверов
*/
ini_set("max_execution_time","60");

class 
readitem
{
var 
$item//массив с данными о вещах
var $firstS = -1;

#region "базы" атрибутов для гупп вещей
private $gW = array("index""slot""skill","x","y","serial","option","drop","level","dMin","dMax","speed","dur","mdur","mpow","lreq","sreq","areq","ereq","vreq","creq","sattr","dw","dk","elf","mg","dl","sum","rf");//weap
private $gA = array("index","slot","skill","x","y","serial","option","drop","level","def","block","dur","lreq","sreq","areq","ereq","vreq","creq","sattr","dw","dk","elf","mg","dl","sum","rf"); //arm
private $gWn = array("index","slot","skill","x","y","serial","option","drop","level","def","dur","lreq","ereq","sreq","areq","creq","buymoney","dw","dk","elf","mg","dl","sum","rf");//12
private $gP = array("index","slot","skill","x","y","serial","option","drop","level","dur","lreq","ereq","sreq","areq","vreq","creq","Res7","sattr","dw","dk","elf","mg","dl","sum","rf");//13
private $gJ = array("index","slot","skill","x","y","serial","option","drop","value","level");//14
private $gS = array("index","slot","skill","x","y","serial","option","drop","level","lreq","ereq","BuyMoney","dw","dk","elf","mg","dl","sum","rf");//15
#end

/**
* Конструктор класса
* @file - адрес до файла с вещами
**/
function readitem($file)
{
if (
file_exists($file))
{
$dataAr file($file);
$i=0;

foreach(
$dataAr as $id=>$value)
{
$value trim($value);
if (
substr($value,0,2)!="//" && strlen($value)>&& $value!="end")
{

if (
strlen($value)>&& strlen($value)<3)
$cGroup $value;

else
{
if (
$this->firstS==-1)
{
if (
strlen($value)<90)
$this->firstS 0;
else
$this->firstS 2;
}


switch (
$cGroup)
{
case 
0:
case 
1:
case 
2:
case 
3:
case 
4:
case 
5$this->item[$i]= self::readWeapons($value);  break;
case 
6:
case 
7:
case 
8:
case 
9:
case 
10:
case 
11$this->item[$i]= self::readArmors($value); break;
case 
12$this->item[$i]= self::read12($value); break;
case 
13$this->item[$i]= self::read13($value); break;
case 
14$this->item[$i]= self::read14($value); break;
case 
15$this->item[$i]= self::readSkiils($value); break;
default: 
$this->item[$i]["error"] = "Unknown item Group";break;
}

$this->item[$i]["name"]= self::getIName($value); //узнаем имя вещи
$this->item[$i]["group"]= $cGroup//указываем группу вещи
$i++;
}
}
}
}
else
$this->item["error"]="Can't found $file";

}

/**
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function getIName($itmar)
{
preg_match("/["]{1}([A-Za-z0-9']{1,20}[s]{0,}){1,5}["]{1}/", $itmar , $name);  //имя вещи, сразу с ковыками

$name = htmlspecialchars(substr($name[0],1,-1),ENT_QUOTES);
if (!$name) return "Unknown item";
return $name;
}

/**
* возвращает массив с данными (циверками)
* @itmar - строка о вещи из базы
**/
function getReq ($itmar,$num=3)
{
$value=preg_replace("/s/","t",$itmar);
preg_match_all("/[0-9-]{1,".$num."}/", $value , $replaced);

return $replaced[0];
}

/**
* читаем оружие
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function readWeapons($itmar)
{
$get = self::getReq (&$itmar);
unset($ar);

if (count($get)<2)
$ar["error"]="Can'
t read item info$itmar";
else
{
$j = $this->firstS;
foreach (
$this->gW as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}
}
return 
$ar;
}

/**
* читаем амуницию
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function readArmors(
$itmar)
{
$get = self::getReq (&$itmar);

unset(
$ar);

if (count(
$get)<2)
$ar["error"]="Can't read item info! $itmar";
else
{
$j = $this->firstS;
foreach ($this->gA as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}
}
return $ar;
}

/**
* читаем группу 12
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function read12($itmar)
{
$get = self::getReq (&$itmar);

unset($ar);

if (count($get)<2)
$ar["error"]="Can'
t read item info$itmar";
else
{
$j = $this->firstS;

if (!self::checkN(
$get[0]))
$j--;

foreach (
$this->gWn as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}
}
return 
$ar;
}

/**
* читаем группу 13
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function read13(
$itmar)
{
$get = self::getReq (&$itmar);

unset(
$ar);

if (count(
$get)<2)
$ar["error"]="Can't read item info! $itmar";
else
{
$j = $this->firstS;

if (!self::checkN($get[0]))
$j--;

foreach ($this->gP as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}
}
return $ar;
}


/**
* читаем группу 14
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function read14($itmar)
{
$get = self::getReq (&$itmar);
unset($ar);


if (count($get)<2)
$ar["error"]="Can'
t read item info$itmar";
else
{
$j = $this->firstS;

if (!self::checkN(
$get[0]))
$j--;

foreach (
$this->gJ as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}
}
return 
$ar;
}

/**
* читаем манию и скиллы
* возвращает название вещи
* @itmar - строка о вещи из базы
**/
function readSkiils(
$itmar)
{
$get = self::getReq (&$itmar,6);

if (count(
$get)<2)
$ar["error"]="Can't read item info! $itmar";
else
{
$j = $this->firstS;

if (!self::checkN($get[0]))
$j--;


foreach ($this->gS as $i=>$val)
{
$ar[$val] = $get[$j];
$j++;
}

}
return $ar;
}

function checkN($var)
{
if (substr($var,0,1)=="0" && strlen($var)>1)
return true;

return false;
}

}
внутри 1 вещь выглядит примерно так:
## здесь был скриншот ##
[свернуть]

Mr.Kernighan

#1
За что не люблю пыхшников, за неумением форматировать код. Или это tag CODE испортил :)

if (substr($value,0,2)!="//" && strlen($value)>0 && $value!="end")
if ($cGroup<6) //weapons
$this->item[$i]= self::readWeapons($value);

Де отступы? :)

epmak


Profesor08

Цитата: Mr.Kernighan от 2013 Фев. 09, 15:00  За что не люблю пыхшников, за неумением форматировать код. Или это tag CODE испортил :)


Де отступы? :)
Видать ты невидал еще неформатированного кода. То что выше еще ляличка..

epmak

#4
Обновлен 1й пост.

Спойлер
  • Версия класса 1.2
  • Изменен алгоритм
  • Более четкое разделение между классами вещей
  • Читает все, что ему подсунут (в том числе и с7. На с7 "плавают" параметры(проверял на igcn), но название вещи узнает четко)
  • Поддержка RF
  • Для более старых сезонов rf & sm, а возможно и dl будут пустыми, если в базе не указано, что они могут одеть вещь
[свернуть]

П.С.: на этот раз я прошелся TextFX'ом. можете наслаждаться отступами (sun)

Обновлен 1й пост
Спойлер
  • Версия 1.3
  • класс автоматически определяет, что передним: обычные файлы или муть от игцн  (как говорят у пендосов "hot" :D)
  • поддержка 7го сезона (как говорят у пендосов "hot" :D)
  • требует тестов с серверами ТТ, так как я на видел даже их новых итем баз.
[свернуть]

Юзайте класс на здоровье, единственное, прошу не тереть комментариев в классе (то  бишь, кредитов)
Очень жду, что хотя бы 1 человек несколько разнообразит мой монолог своими идеями и наработками, так как я мог просто упаковать данный класс в 1.6 и кому-то пришлось бы изобретать "лисапеды".

И позвольте узнать, что в вашем понимании "Ждем еще чего-нить вкусненького" ? веб я точно в паблик пока не собираюсь выкладывать

Обновлен 1й пост

немного подчистил код. Так же было замечено, что все это дело очень чувствительно к курочению итемкор, поэтому перед использованием, убедитесь, что итем кор нормально написан, лучше если будет пропущен через маджикхенд

Vaflan

Чесно сказать много лишнего и не нужного, и то что:
Цитата: epmak от 2013 Фев. 12, 14:57  Так же было замечено, что все это дело очень чувствительно к курочению итемкор, поэтому перед использованием, убедитесь, что итем кор нормально написан, лучше если будет пропущен через маджикхенд

это всё печалит, может разберёшься со временем как лучше сделать.
Дам совет, все пробелы и табуляции переделать на один тип, сжать их, сделать trim(), и только тогда парсить, и тогда будет всё стабильно.

Подобная шняга, была написано мной в 2010 ближе к 2011, по сей день ещё не одной погрешности не было

epmak

#6
(sun) разберемси
Спойлер
[свернуть]

Цитата: Vaflan от 2013 Фев. 14, 11:05  Чесно сказать много лишнего и не нужного
что на твой взгляд не нужно?
я писал намеренно класс. Это класс-родитель. На каждую группу вещей ( тут, в основном, объединено по несколько групп из-за сходств в параметрах) своя реализация. если что-то надо запилить отличное, то можно просто изменить 1 функцию, а не править весь код.

Прошу меня покорнейше простить за поклеп: класс нормально реагирует на любое кол-во табуляций и пробелов в файле.

valerik

наверное глупо продавать такой класс.. т.к. те кто знает как и где его можно использовать, сами напишут такой без труда.. а кто не знает, тому он нафиг не нужен.

epmak

между делом курент
Цитировать* v 1.8
* last update 23.02.13

и там не 1 класс. как я уже замечал - это класс - родитель, причем здесь самая ммм.. унылая на мой взгляд реализация.

Видишь ли, я и сам без проблем мог бы написать и зарилизить. Это скорее был вопрос на тему, остался ли здесь кто живой или нет из веб-разработчиков, кто был готов был развить тему. Диалога ведб не построишь в 1 действующее лицо

valerik

Ну вот я написал класс Items, для преобразования HEX предмета в массив, и обратно. Там есть аналогичная функция ItemKor(), которая парсит этот файл. У меня вся функция в 60 строк кода уложилась, и то же адекватно парсит файлы с любым кол-вом пробелов и табуляций.. И результат аналогичный твоему возвращает..

Единственное, что мне в моей функции не нравится - страшная длинная регулярка.. У тебя возможно лучше сделано, 2 маленькие регулярки, одна для цифр, вторая для названия.. Возможно возьму у тебя эту идею.. Но всё остальное у тебя как то громоздко выглядит.

epmak

Я начинал с функций, но чуть позже пришлось переходить на классы (в моем паблик они есть, но за некоторые мне стыдно, там по факту некоторые реально слеплены из больших функций). Пришел к выводу, что мне гораздо удобнее что-то менять в классе, ибо он четко прописан только на чтение, например. хотя есть и на генерацию, но в целом возможно это и не оправдано...


на самом деле, я переделал в 1 и тоже страшно блинную (~150 символов), так как у этих 2х регулярок есть 1 беда и из-за них надо делать костыли - они четко проявляются когда начинаешь пилить дальше, то есть делать универсально и для игцн и для обычных сезонов. + меня сильно не устраивало 2 функции, сейчас все красивее 1 функция и на все годится. ДА и не думаю я, что из - за такой вот 1 регулярки настолько сильно пострадает скорость: я проверял и так и так - разницы почти нет  + регулярки же компилятся, то есть ты её 1 раз закомпилил, а дальше она просто юзается... вообще, кому я рассказываю, ты ж знаешь

По поводу громоздкости - я хотел выделить отдельно классы: оружие/арморы/винги/все остальное, так как они по-разному немного имеют опций + там же парс не только итем кора, а и остальных примочек к вещи. В классе четко видно, где какая расположена и можно менять реализацию, не разгребая конструктор класса (логическое отделение, впринципе и в функции пильнуть можно).
единственное, пока прожевывал концепцию, благодаря тебе, нашел оверинжиниринг.. надо будет переделать пару вещей.

valerik

Цитата: epmak от 2013 Фев. 27, 17:16  + регулярки же компилятся, то есть ты её 1 раз закомпилил, а дальше она просто юзается... вообще, кому я рассказываю, ты ж знаешь :)
Понятия не имел.. Собирался.. ну и собираюсь как то закэшировать результаты этих функций, которые парсят файлы. У меня при разборе HEX предмета 4 файла парсится Item(Kor).txt , ItemAddOption.txt,  Skill(Kor).txt,  JewelOfHarmonyOption.txt
На каждый файл есть своя функция.. я подумываю взять результаты всех функций, слить всё в один массив, сериализовать его и сохранить в один файл, чтоб не 4 файла парсить, а один unсериализовывать

PS, ты мою регулярку не видел.. 516 символов! Да мне стыдно за это.
Спойлер
<?php
if (preg_match('/([0-9]+)+([0-9-]+)+([0-9]+)+([0-9]+)+([0-9]+)+([0-9]+)+([0-9]+)+([0-9]+)+"([0-9a-zA-Z-)([]' ]+)"{0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,}){0,}([0-9]{0,})/', $str, $mas)) {
...
}
?>
[свернуть]

epmak

сериализовать... ты можешь не хило поплатиться производительностью от сериализации, веещей-то много, это 1. а 2е, как показывает практика, файл должен быть читабелен, чтобы в последствии твои же клиенты могли его прочесть и изменить, если нужно, и самое смешное, что у них "если нужно" чаще бывает чем "воспользоваться конвертером"  
по поводу регулярки подскажу, попробуй не полностью пытаться описать строку в выражении а только то, что тебе нужно. + ты почему-то не юзаешь группировку и на группировку вполне можно накинуть количество повторений, это как минимум, в половину уменьшит твой текст. И то, это еще не идеал, я думаю, мне самому регулярки писать не шибко нравится, хотя, год назад это было хуже

valerik

Цитата: epmak от 2013 Фев. 28, 04:48  сериализовать... ты можешь не хило поплатиться производительностью от сериализации, веещей-то много, это 1. а 2е, как показывает практика, файл должен быть читабелен, чтобы в последствии твои же клиенты могли его прочесть и изменить, если нужно, и самое смешное, что у них "если нужно" чаще бывает чем "воспользоваться конвертером" :)
Во первых сериализовать придётся предметов ничуть не больше чем я сейчас из файлов парсю.. Во вторых это только в качестве кэша, а не для редактирования.. редактировать всё те же оригинальные файлы можно, а кэш если что обновится просто.

Цитата: epmak от 2013 Фев. 28, 04:48  по поводу регулярки подскажу, попробуй не полностью пытаться описать строку в выражении а только то, что тебе нужно. + ты почему-то не юзаешь группировку и на группировку вполне можно накинуть количество повторений, это как минимум, в половину уменьшит твой текст.
Не очень понял что за группировка

Profesor08

За долгое время - первый адекватный более менее разговор.

А как вы думаете на счет того, чтоб сделать базу в xml формате или json. Это самые такие распространенные формы. Да и парсеров для них есть куча на любой вкус и цвет.

valerik

База это что? Имеется в виду текстовые файлы Item(Kor) и т.п.?
Зачем? Редактировать от этого проще не станет.. только сложнее.. Парсить, да проще, но смысла не вижу один фиг.

Vaflan

valerik тему сказал, сразу видно опыт.
serialize() это специально разработанный тип содержания массива, данных, обьектов для пхп, который работает быстрее всех видов сохранения информации, того же json, xml, или даже тот же тип сохранения как в csv.
Сериализация используется для хранения в темпе сессии у php. Это явный пример где применяется и очевидно что создатели не будут использовать медленнее блокнота.

Уже года 2 юзаю такое для кеша, очень удобно и быстро. По поводу парсинга всех файлов в один, это очень мудрое решения. нежели как я каждый файл парсю в каждый свой сериализованый.

Ермак как всегда много текста, и сплошная вода  

Mr.Kernighan

Сколько времени класс затрачивает на загрузку одного файла, скажем IGCN?

epmak

#18
надо смотреть. если сервер загружен не сильно то пару секунд с виду +/-. на ноуте он у меня долго это делал, но ноут рабочий, старый, тут и венда "долгая". Правдаэто + с работой с файлами. А так почти сразу. точнее позже скажу.

Время выполнения 0.500795841217 секунд 1 запуск

Время выполнения 0.52032494545 секунд 2 зайпуск - небольшое форматирование на  экране

читал сами вещи и скиллы к ним. (т.е. без учета пвп, и анц). Сервер средненько нагруженный.

если при этом создавать файл базы как в ДЕВ и диск жесткий ссд или высокоскоростной, думаю будет еще быстрее. дома на локалке строил базу для своего сайта примерно по времени так же - чуть заметно, что страница медленнее загружается(но там.. гм.. несколько поболе файлов в парсинге), но можно сделать бекэндом, тогда вообще не будет видно скока и тчо делается

valerik

#19
Собственно вот мой рабочий класс
Items.php

Похожие темы (5)

Сообщений: 37
Просмотров: 21541

Сообщений: 127
Просмотров: 37986

Сообщений: 32
Просмотров: 12318