Таблица лидеров
Популярный контент
Показан контент с высокой репутацией за 08/22/12 в Инструкции
-
13 балловПриветствую всех начинающих JAVA разработчиков. Гайд предназначен для тех, кто все еще пытается дебажить c помощью System.out.println, но уже осведомлен в целом о JAVA разработке, и немного умеет пользоваться IDE Дебагинг один из важнейших и трудозатратных процессов после самой разработки, и очень важно чтобы этот процесс был максимально удобен для разработчика. Большинство современных IDE имеют встроенный функционал отладки, который позволяет приостаналивать приложение в определенные моменты выполнения и просматривать\изменять память с помощью т.н брейкпоинтов. В данном гайде я расскажу как запускать ява эмулятор или "сборку" в режиме отладки и использовать инструменты отладчика на примере IDE IntelliJ IDEA. Часть #1 - "Быстрый запуск, удаленная отладка" Я расскажу о двух вариантах отладки, первым из них будет "удаленная отладка" Этот вариант, позволяет вашей IDE удаленно подключаться к приложению с помощью спец. инструментов java Пусть слово "удаленная" вас не пугает, формально это будет сетевое подключение, но происходить оно будет локально в пределах вашего ПК. Шаг 1. Параметры запуска. Для того, чтобы запустить Ваш сервер в режиме ожидающий отладки, в параметры запуска ява приложение необходимо добавить следующие значения Это делается соотвественно в .bat или .sh файле -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=7456 Шаг 2. Добавляем конфигурацию запуска в IntelliJ IDEA В главном меню переходим в раздел Run -> Edit configuration В левом верхнем углу нажимаем на "плюсик" и из выпадающего списка выбираем "Remote" Пишем удобное для Вас название (к примеру "DebugGameserverRemote", в поле "Host" вводим "localhost, в поле "Port" - "7456" Сохраняем. Шаг 3. Запуск Перед запуском сборки убедитесь, что исполняться будет последнее собраное ядро (если что-то изменяли, пересоберите ядро и замените в папке с сервером). Запускайте сборку с помощь .bat или .sh файла, вы получите сообщение о том, что ожидаеться подключение дебагера. В IntelliJ IDEA в главном меню переходим в раздел Run, и выбираем "Debug DebugGameserverRemote" - Или там будет любое название, которое вы написали при создании конфигурации. IDE подключилась к приложению, сборка продолжает запускаться. Можете расставлять брейпоинты и дебажить. После изменения какого либо класса, для того, чтобы брейпоинты в этом классе сработали - нужно соотвественно собрать новое ядро и заменить в папке с вашей тестовой сборкой. Часть #2 - "Автоматизация или "Лень - двигатель прогресса" Каждый раз копировать новое ядро, запускать сборку с помощью .bat\.sh файла - нормально, но со временем понимаешь, что и это не совсем удобно. Следующий вариант запуска в режиме отладки - запуск прямо из IntelliJ IDEA. Дополнительно перед каждым запуском будем автоматически собирать новое ядро Шаг 1. Артефакты. Собирать будем средствами IDE, это еще незывают "сборкой артефакта" В главном меню переходим в раздел File -> Project Structure Выбираем раздел Artifacts, нажимаем на плюсик для создания нового артефакта, выбераем JAR -> From module with dependencies Пишем удобное название ( к примеру "gameserver:jar-test_server") В поле Output Directory указываем путь, где лежит ядро вашей тестовой сборки, в моем случае это "D:\test_server\lib" В поле Main class вводим полное название главного класса (класс, который содержит метод main()), подсмотреть его можно из .bat\.sh файла Сохраняем. Таким образом, можно собирать любые JAR библиотеки, отказывашись от других сборщиков типа ANT Шаг 2. Добавляем конфигурацию запуска в IntelliJ IDEA В главном меню переходим в раздел Run -> Edit configuration (см выше, в первой части) В левом верхнем углу нажимаем на "плюсик" и из выпадающего списка выбераем "Application" Вводим удобное для Вас название (к примеру "Gameserver-test_server") В поле Main class вводим полное название главного класса (класс, который содержит метод main()), подсмотреть его можно из .bat\.sh файла В поле VM options нужно прописать classpath (-cp) с нужными зависимостями для вашей сборки, а так же другие параметры при необходимости. Подсмотреть эти параметры можно в .bat\.sh файле В поле Working Directory указываем путь, к корневой папке, из которой запускается ваш тестовый гейм-сервер (путь, где лежат .bat\.sh файлы запуска). В моем случае это "D:\test_server\gameserver" Use classpath of module - выбираем модуль с исходниками геймсервера В самом низу окна есть раздел "Before launch" - действия, которые будут выполняться перед запуском (там уже по умолчанию должен быть Build). Нажимаем на зеленый плюсик, выбираем "Build artifacts" в появившемся окне выбираем ранее созданный артефакт "gameserver:jar-test_server" Конфигурация готова, сохраняем ПС. на ворнинг на моем скрине не обращайте внимания, глюк IDE после переименования пакета. У вас ошибок и варнингов быть не должно. Шаг 3. Запуск В IntelliJ IDEA в главном меню переходим в раздел Run, и выбираем "Debug Gameserver-test_server" - Или там будет любое название, которое вы написали при создании конфигурации (см. пример выше, по аналогии с первой частью) Сборка пересобираеться, затем запускается. Можете расставлять брейпоинты и дебажить. Таким образом можно настроить билд сервера авторизации или настроить различные цепочки событий, чтобы запускать все в 1 клик. Удачи в разработке ПС. Если кому-то будет интересно, могу написать небольшой гайд по самому процессу отладки, брейкпоинтам, условным брейкпоинтам, ватчеру и т.д
-
8 балловИзменяем оформление для внутренних страниц Регистрации, Личного кабинета, Статистики и Восстановления пароля Пример для статистики. Открываем application/stat.php После: if ( !defined( "STRESSWEB" ) ) die( "Access denied..." ); Вставляем: $_SW_TEMPLATE = 'index_stat'; в шаблоне создаем файл index_stat.tpl в котором оформляем вывод статистики. В этом файле будут доступны все теги с index.tpl Не сложно догадаться, что вы можете задать любое название вместо index_stat и создать для каждой внутренней страницы свое оформление. Другие страницы изменяются там же в папке application: В чистом SW можно без проблем изменить forget.php / register.php / cp.php / stat.php и если не ошибаюсь файлы рейтингов mmotop/l2top Для чего это нужно? В св весь контент выводить через тег {content} и бывают такие дизайны в которых места под контент очень мало. Например: При помощи этого способа можно переоформить например регистрацию: Делитесь своими наработками благодаря этому мы развиваемся и развиваем!
-
7 балловЗдравствуйте. Многие знают о некоторых командах режима разработчика, к примеру: sv / pv / nv / stat l2 / show [ ] , но давайте познаем немного больше. Авторство принадлежит пользователю ExLite. Список: / / / l2debugwindow - / / / l2debug - displays messages in the open console / / / geodata - you must copy the GEODATA folder to a folder GEODATA in the client / / / buildzone map = [map_name] is the same crap but in one area / / / showborderline - shows the boundary / / / showsectors - divides the world on sectors / / / camerawalking mode = on | off - enables the camera to move a limited distance without moving Player. / / / c_rmode [1-7] - changes the map of the world ... very badly) to demonstrate how until I found) / / / bighead size = [1-n] - increases the size of the head. (only you can see it) / / / open [map name] - ///open 24_24 / / / get [class_name] [attrib_name] / / / set [class_name] [attrib_name] / / / editdefault class = [class_name] / / / stat l2 - info of everything ... constantly changing. useful. / / / stat fps - number of frames per second UClient::Exec BRIGHTNESS CONTRAST GAMMA ULevel::Exec SHOWEXTENTLINECHECK SHOWLINECHECK SHOWPOINTCHECK UInput::ExecL2Test SIMULMESH SPAWNDUMMY OnRelease ReloadSkillEffect | ReloadSE ReloadSceneInfo | ReloadSI Perf count dump TSkin ZoneState ChNPCState gfx L2Console SkipFullUShader rec blendspine airbind on off SuperShadow on off CameraNearPlane | CNP IZ FlyMove show_range dm on off gfxmsg USELIGHTMAP SPAWNSkillEffect | sse ExchangeSubstitute efflvl builder UInput::Exec SceneEditor ow CAMERAYAW CAMERAPITCH PLAYERPAWNMOVETO CameraRotationOn UseAutoTrackingPawnOff STOPMOUSE CameraRotationOff OnRelease UseAutoTrackingPawnOn OnRelease MOVEMOUSE OnRelease FIXEDDEFAULTCAMERA OnRelease UP DOWN ZOOMINPRESS ZOOMOUTPRESS ZOOMINHOLD ZOOMOUTHOLD TURNBACK DEFAULTCAMERA OnRelease KEYBOARDMOVEUPAIRSHIP OnRelease KEYBOARDMOVEDOWNAIRSHIP OnRelease KEYBOARDSTOPMOVEAIRSHIP OnRelease KEYBOARDMOVESTART OnRelease KEYBOARDMOVEFINISH OnRelease LEFTTURNINGSTART OnRelease LEFTTURNINGFINISH OnRelease RIGHTTURNINGSTART OnRelease RIGHTTURNINGFINISH OnRelease KEYBOARDPERMANENTMOVE OnRelease KeyboardPermanentMovingForward OnRelease KEYBOARDBACKMOVESTART OnRelease KEYBOARDBACKMOVEFINISH OnRelease KeyboardMoveFinishAl OnRelease BUTTON PULSE TOGGLE AXIS JOYPAD COUNT KEYNAME LOCALIZEDKEYNAME KEYBINDING L2Restart Warp rwarp FadeOut FadeIn bbb bbbb MoveWarp L2WaterInfo L2WaterReflect L2UnderWaterEffect EnterChat YAWTURN HideName L2EVENTON L2EVENTOFF GETITEM OnRelease ATTACK OnRelease SHOWCOMPASS HIDECOMPASS SCENE0 SCENE1 ANTIPORTA TELEPORT OnRelease Observer On WAITMODECHANGE OnRelease MOVEMODECHANGE OnRelease CONTROLLERVIEW PAWNVIEW SPAWNPLAYERPAWN OnRelease DeletePlayer OnRelease SPAWNACTOR OnRelease SPAWNNPCS OnRelease PlayerMove DumpActor OnRelease SPAWNVEHICLES OnRelease SAS ON OFF RIDE D P MOVE TRAI SPS SPSM SPAWNITEM OnRelease SPAWNEDPAWNMOVETO STOPPAWNMOVING OnRelease DISTANCEFOG DISTANCEFOGRANGE PERSPECTIVE GROUNDSPEEDUP GROUNDSPEEDDOWN CAMERAVIEWHEIGHTADJUST SELECTINGCANCE Crash CHAIR SIT STAND JOYSTICKMOVE OnRelease STEPMOVE COMBOANIMPLAY CHANGEANIM CheckGrp Addabnorma | aa deleteabnorma | da AddEffect DeleteEffect CursedWeapon FIRECRACKER FENCE BONESCALE | BS FLY DASH TRANS SETROT bighead Lodchange Env Reload SETTIME SETTIMERATIO CancelMAGICTEST DeleteSelectedActor DeleteActor pv | PawnViewer nv | NpcViewer sv | SkillViewer SHOWMAP HERO HDR PE dof water inst Cast SkillRemain beginmr Specia RequestExEnchantSkillInfo RequestExEnchantSkillInfoDetai RequestExEnchantSki Norma WaitType Swim On Off Weather AirState On Off addcubic decubic cubicski ATTACKSPEEDDOWN ATTACKSPEEDUP setwyvern SVS BoneSim ReduceLOD KeepMinFrame SkipAnim Hitwater ToggleCollideWorld SHADOW DEFAULTSHADOW RIDE UNRIDE ANIMPLAY REFRESH TRANSFER BuildZone LoadPath Limit C_TELEPORT RETURN HOME C_RMODE GEODATA SEAMLESS ON OFF MAPLOC SHOWBORDERLINE SHOWSECTORS LINECHECK CacheTexture RenderDeco Density Arrow On Off RadarTime MapBug Batch SkipGC ChangeServer Thread On Off SHOWLOADLINE Range ResetCam CameraDist ResetProfiler CAMERAWALKING | cw INCCAMERAWALKINGACCE OnRelease DECCAMERAWALKINGACCE OnRelease MODMAXAIRSPEEDSTART OnRelease MODMAXAIRSPEEDFINISH OnRelease CAMERAMODESELECTINGCANCE ChangeEnv FISH START END COMBAT REGEN RANK GPUSkinning PA SpawnPC | SpawnPCs SpawnNPC | SpawnNPCs SDPC SETALPHA SPAWNEMITTER | SE VARIATIONEFFECT | VE ClickMe | cm L2CheckResource | L2CR DestroyActor A NameOffset off Flight Clear_block Clear_Lines D OFF SW UGameEngine::Exec OPEN START SERVERTRAVEL SAY DISCONNECT RECONNECT EXIT | QUIT CRASH GETCURRENTTICKRATE GETMAXTICKRATE GSPYLITE SAVEGAME CANCEL SOUND_REBOOT LazyMode On | Off SetAgit SET UEngine::Exec FLUSH STAT ANIM DEFAULT | RESET FPS RENDER HARDWARE GAME HISTOGRAPH XBOXMEM MATINEE AUDIO NET PACKETCOUNT EXPACKETCOUNT GRAPH DEBUG ALL NONE CONSOLE L2 MEM Thread Script ScriptR GFx ET ER EA CRACKURL PACKETCOUNTSTART PACKETCOUNTSTOP EXPACKETCOUNTSTART EXPACKETCOUNTSTOP RELOAD REPLAYSAVE START END REPLAYLOAD BuildLevel | ReleaseLevel FAKEITEM UViewport::Exec TRUETYPE TTFSHOT ISFULLSCREEN GETPING INJECT NETSPEED LANSPEED SHOWALL REPORT SHOT SHOWACTORS HIDEACTORS RMODE L2S SPAWNTARGET REND BLEND | NORMALS BONE BONENO SKIN BOUND SIMULCOLLISION | SC BONENAME | BN SIMULVERTEX | SV DEFAULT | RESET cp SHOW CINEMATICS CINEMATICSRATIO FIXEDVISIBILITY TOGGLEREFRAST EXEC ACTORS ACTORINFO STATICMESHES TERRAIN FOG SKY CORONAS PARTICLES BSP RADII FLUID PROJECTORS FALLBACKMATERIALS COLLISION TERRITORY VOLUME NAME DROP WINDOWNAME WINDOWBOX UISCRIPTDEBUGINFO MUSICVOLUME CLEAR UPD от TURGOR: ///reloadui
-
7 балловСобственно цель данной статьи - поведать об одном из самых простых способов развертывания на сервере с помощью git'а и его хуков. Предисловие: данная статья предполагает что Вы понимаете что такое VCS, в часности гит и уже им пользовались Развертывание проходит в 3 этапа Пуш в репозиторий размещенный на нашем сервере Тригер хука на сервере Выволнение нужного нам скрипта, в данном случае чекаут из репозитория в нужную нам папку Статья на примере работы с Centos 7 в качестве продакшн сервера и Windows 10 в качестве дев-машины. Авторизироваться будем по ssh, и для начала нужно сгенерировать ssh ключ. Сгенерировать его можно, к примеру, у тилитой ssh-keygen, которая идет в составе git для windows Из CMD выполняем: ssh-keygen -t rsa Следуем инструкциям (вас спросят куда положить ключ, можете просто нажать enter, ключ будет сохранен в C:\Users\username\.ssh), устаналиваем пароль, получаем ключ, файл будет называться примерно так id_rsa.pub Далее нужно настроить гит репозиторий на сервере. Устаналиваем git $ yum install -y git Создаем гит юзера, для ssh авторизации, указываем пароль $ sudo adduser git $ sudo passwd git создаем папку для ssh ключей $ su git $ cd $ mkdir .ssh Скопируйте на сервер (через фтп или другим удобным фам способом) ранее сгенерированый паблик ключ, к примеру в папку tmp, в итоге получаем /tmp/id_rsa.pub Добавляем этот ключ в список доверенных $ cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys Переходим к созданию гит репозитория, к примеру в папке /home/git $ cd /home/git $ mkdir project.git $ cd project.git $ git --bare init project.git - можете назвать как угодно. Длее нужно создать хук в папке /home/git/project.git/hooks Создаем файл post-receive с содиржанием #!/bin/bash echo 'post-receive execute start' >> hooks.log TARGET="/home/myproject" GIT_DIR="/home/project.git" BRANCH="master" while read oldrev newrev ref do # only checking out the master (or whatever branch you would like to deploy) if [[ $ref = refs/heads/"$BRANCH" ]]; then echo "Ref $ref received. Deploying ${BRANCH} branch to production..." >> hooks.log git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f echo "Deploying done" >> hooks.log else echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server." >> hooks.log fi done TARGET - путь к папке в которую будет происходить копирование из репозитория GIT_DIR - путь к папке с гит репозиторием BRANCH - ветка из которой будем забирать Настройте данные переменные под себя. Репозиторий готов, возвращаемся на нашу дев-машину, и создаем из папки с проектом локальный репозиторий. Это можно сделать и спомощью CMD или любой програмы для управления гит (к примеру я пользуюсь SourceTree) Выполняем в CMD cd /d D:\path\to\project git init path\to\project соотвественно меняете на путь к папке с вашим проектом. Комитим изменения, подключаем удаленный репозиторий на сервере и пушим. (если вы создали репозиторий в пустой папке, скопируйте в нее файлы вашего проекта) git add . git commit -m 'initial' git remote add origin git@myserver.com:/home/git/project.git git push origin master myserver.com - домен или ИП адрес вашего сервера. Гит спросит пароль от юзера, вводим пароль который указывали при его создании После пуша на удаленном сервере выполнится хук и файлы будут скопированы в папку для развертывания.
-
6 балловПервым делом, еще раз оговорюсь, что рациональней перепилить это дело под полноценный экшен, я же делал байпассом. Потому первым делом в ядре стоит запилить что-то такое: (!)Обратите внимание на мои условия, мне нужны были в таргете только монстры, для своих целей перепишите соответствующим образом. (да, у меня такой синтаксис что игроки это мобы, а мобы - это игроки, все в порядке) Так же заметьте, я ограничиваю максимальную дальность 1200, Вы можете этого не делать, либо задать свою. Я бы советовал ограничить максимальную дальность именно в ядре, ибо зная байпасс с интерфейса можно будет творить чудеса. Так же вопрос: нужно ли принудительно обновлять хп/мп таргета, если Вы уже шлете пакет MyTargetSelected? - На адекватных сборках может и нет, а вот у меня были проблемы пока так не сделал. Так же Вы можете добавить проверку на видимость целей, что-то вроде: GeoData.getInstance().canSeeTarget(activeChar, nextMob) Почему я такую не добавил? Об этом в следующей кулстори расскажу. Теперь в интерфейсе прикрутим в функцию OnLoad() следующее: (здесь тоже довольно извращенная и чрезмерно нагроможденная конструкция, опять же скорее для наглядности, адекватно на это посмотреть и переписать нормально, а не копировать): nrage(int(class'UIAPI_EDITBOX'.static.GetString("тут адрес нашего окна"))); Сама функция nrage: function nrage(int valueX) { if ( valueX < 400) { NTrange = 400; } if ( valueX > 1200) { NTrange = 1200; } else { NTrange = valueX; } } И наш отправляемый байпас: RequestBypassToServer("наш байпасс посылаемый с интерфейса "$ NTrange); Дальше (очень логично и последовательно, идя от конца к началу) оформим сам эдит бокс, с которого только что считывали дальность нашего некст таргета. Я его храню в другом классе, потому у Вас все может быть проще и красивее, в который раз повторюсь, что эта информация больше подходит для ознакомления, а не копипаста, хоть и будет работать и в таком виде. И так, прежде всего: var EditBoxHandle e_autoMacroRange; var MacroListWnd* script_mc; ..... e_autoMacroRange = GetEditBoxHandle("Ваше окно"); script_mc = MacroListWnd(GetScript("MacroListWnd")); *на всякий случай: это я тяну с другого класса скрипт, и напомню, что Вы можете без проблем обойтись и без этого Я сохраняю настройки по клику кнопки, потому нужен хендлер OnClickButton, и в нем наша кнопка: case "btnApply": OnApplyBtn(); break; .... сама функция кнопки (уже вне хендлера ,если что, наверное, это и так очевидно, но мне бы такая пометка жизнь спасти могла) function OnApplyBtn() { local int valueX if (e_autoMacroRange.GetString() != "") { valueX = int(e_autoMacroRange.GetString()); if (valueX >= 400 && valueX <= 1200) { SetINIInt("MacroSettings", "AutoMacroRange", valueX, "PatchSettings"); script_mc.nrage(valueX); } } } Для загрузки наших данных о дальности нексттаргета из файла: function LoadINISets() .... GetINIString("MacroSettings", "AutoMacroRange", valueS, "PatchSettings"); if (e_autoMacroRange.GetString() == "") { valueS = "750"; } e_autoMacroRange.SetString(valueS); И вот сейчас был спорный момент, ибо раз уже замешано ядро - то зачем хранить эти данные в интерфейсе и почему бы не запихивать их куда-то на сервер сайде? Для себя я ответил: чтобы в эдитбоксе выводить актуальную дистанцию и не создавать лишних запросов в БД, а свой ответ Вы можете поискать сами, либо засунуть инфу на серверсайд.
-
6 балловСоздаем файл clantop.php в папке module и копируем туда этот код: <?php /** * STRESS WEB * @author S.T.R.E.S.S. * @copyright 2008 - 2012 STRESS WEB * @version 13 * @web http://stressweb.ru * @fix L2Banners.ru */ if ( !defined("STRESSWEB") ) die( "Access denied..." ); /****************************** * НАСТРОЙКА МОДУЛЯ ******************************/ $T_ENABLE = true; // вкл/выкл модуль $T_COUNT = 10; // количество результатов $T_SID = 1; // ID сервера с которого выводить результаты $T_CACHE = 5; // время кеширования в минутах, 0 - отключить /****************************** * ВЫВОД РЕЗУЛЬТАТОВ ******************************/ if ( !$T_ENABLE ) $tpl->SetResult( 'clantop' ); else { $clantop = $controller->GetCache( 'mod_clantop' ); if ( $clantop ) $tpl->SetResult( 'clantop', $clantop ); else { $db->gdb( $T_SID ); $T_SEL = $gdb[$T_SID]->query( "SELECT `clan_name`,`clan_level`,`reputation_score` FROM `clan_data` ORDER BY `clan_level` DESC, `reputation_score` DESC LIMIT {$T_COUNT}" ); if ( $gdb[$T_SID]->num_rows($T_SEL) > 0 ) { $T_N = 1; while ( $T_RESULT = $gdb[$T_SID]->fetch($T_SEL) ) { $tpl->LoadView( 'clantop' ); $tpl->Block( 'main', false ); $tpl->Block( 'item' ); $tpl->Set( 'n', $T_N ); $tpl->Set( 'clan_name', $T_RESULT['clan_name'] ); $tpl->Set( 'clan_level', $T_RESULT['clan_level'] ); $tpl->Set( 'reputation_score', $T_RESULT['reputation_score'] ); $tpl->Build( 'clantop_item' ); $T_N++; } $tpl->LoadView( 'clantop' ); $tpl->Block( 'item', false ); $tpl->Block( 'main' ); $tpl->Set( 'item', $tpl->GetResult('clantop_item', true) ); $tpl->Build( 'clantop' ); } else $tpl->SetResult( 'clantop' ); if ( $T_CACHE > 0 ) { $controller->SetCache( 'mod_clantop', $tpl->GetResult('clantop'), $T_CACHE ); } } } ?> В папке с шаблоном создаем файл clantop.tpl и записываем в него шаблон по умолчанию по аналогии с топ пвп/пк: [main] <!-- Модуль Clan Top --> <table id="l2clan"> <tr> <th>Клан</th> <th>Уровень</th> <th>Репутация</th> </tr> {item} </table> [/main] [item] <tr> <td>{n}. {clan_name}</td> <td>{clan_level}</td> <td>{reputation_score}</td> </tr> [/item] Естественно вы можете составить свой шаблон апеллируя новыми тегами {clan_name} - Название клана {clan_level} - Уровень клана {reputation_score} - Репутация клана В корне сайта заходим в папку dev и открываем файл cfg.default.php и находим: $SWMODULES = array( 'copyright', 'login', 'poll', 'server', 'pvptop', 'pktop', 'forum' ); Дописываем в массив после 'forum' : , 'clantop' Должно получиться как-то так: $SWMODULES = array( 'copyright', 'login', 'poll', 'server', 'pvptop', 'pktop', 'forum', 'clantop' ); Теперь в файле index.tpl будет доступен тег {clantop} с помощью которого и будет выводиться репутация кланов по аналогии с топ пвп/пк
-
5 балловПриветсвтую, в данной инструкции рассмотрим возможность сборки ява сервера в докер образ и последующем запуске в контейнере. В данном примере будет вариант с использованием 3-х образов, логин-сервер, гейм-сервер и образ для инсталяции базы данных, запускать будем через docker-compose Введение Данная инструкция не предусматривает рассказ о том что такое контейнеризация, отличия от виртуализации, что такое docker и т.д. В интеренте достаточно информации на эту тему, с учетом того что docker с каждым днем продолжает набирать популярность. Так, что предлагаю перед прочтением этого мануала ознакомиться с общимим материалами на тему "docker и контенеризация приложений" О докере можно почитать на официальном сайте https://docs.docker.com/get-started/overview/ Окружение Дев-машина: Windows 10, установленный docker desktop for windows, работает через hyper-v. С информацией по установке можно ознакомиться по ссылке https://docs.docker.com/docker-for-windows/install/ В этом мануале не будет рассматриваться какая-то конкретная сборка, их огромное количество со своими сходствами и отличиями, по этому прдеположим что у нас есть скомпилированый ява сервер с такой структурой L2Server ├─── loginserver (файлы логин-сервера, конфиг файлы, файл запуска java процесса StartLoginServer.sh) ├─── gameserver (файлы гейм-сервера, конфиг файлы, файл запуска java процесса StartGameServer.sh) ├─── libs (необходимые библиотеки) ├─── install (файлы установки базы данных) ├─── login (sql файлы установки базы логин-сервера, файл запуска установки install-login.sh) ├─── game (sql файлы установки базы гейм-сервера, файл запуска установки install-game.sh) Dockerfile'ы Для того чтобы сбилдить докер-образ необходимо создать файл Dockerfile (название файла, без расширения), в котором прописываються необхходимые инструции билдера. С синтаксисом можно ознакоиться здесь https://docs.docker.com/get-started/overview/ Один образ - один докерфайл, следовательно у нас будет 3 образа и 3 докерфайла. Докерфайл для логин сервера разполагаем в папке loginserver, для гейм-сервера в папке gameserver, для установищка бд в папке install В итоге получаем следующую структуру L2Server ├─── loginserver ├─── Dockerfile ├─── gameserver ├─── Dockerfile ├─── libs ├─── install ├─── Dockerfile Dockerfile для loginserver #исходнй образ который взят за основу FROM adoptopenjdk/openjdk8:jdk8u292-b10-centos #рабочая папка внутри контейнера WORKDIR /server #копируем файлы логин-сервера в контейнер COPY ["loginserver", "/server/loginserver"] #копируем библиотеки COPY ["libs", "/server/libs"] #порты которые пробрасываються в контейнер EXPOSE 2106 9014 #добавляем права на испольнение sh файла RUN chmod +x /server/loginserver/StartLoginServer.sh RUN chmod +x /server/loginserver/UpdateHosts.sh #команда которая выполниться при запуске контейнера CMD ["/bin/bash", "-c", "cd /server/loginserver/ && sh UpdateHosts.sh && sh StartLoginServer.sh"] Примичание: что такое UpdateHosts.sh и зачем он нужен будет рассмотрено ниже. Dockerfile для gameserver #исходный образ который взят за основу FROM adoptopenjdk/openjdk8:jdk8u292-b10-centos #рабочая папка внутри контейнера WORKDIR /server #копируем файлы логин-сервера в контейнер COPY ["gameserver", "/server/gameserver"] #копируем библиотеки COPY ["libs", "/server/libs"] #порты которые пробрасываються в контейнер EXPOSE 7777 #добавляем права на испольнение sh файла RUN chmod +x /server/gameserver/StartGameServer.sh RUN chmod +x /server/gameserver/UpdateHosts.sh CMD ["/bin/bash", "-c", "cd /server/gameserver/ && sh UpdateHosts.sh && sh StartGameServer.sh"] Примичание: что такое UpdateHosts.sh и зачем он нужен будет рассмотрено ниже. Dockerfile для инсталлера базы данных #исходные образ который взять за основу (alpine - легкий дестрибутив linux) FROM alpine:latest WORKDIR /db-install #копируем файлы установки COPY ["install/login", "/db-install/login"] COPY ["install/game", "/db-install/game"] #устаналиваем необходимые пакеты #mysql client RUN apk update && apk add --no-cache mysql-client && apk add --no-cache bash #добавляем права на испольнение sh файлов RUN chmod +x /db-install/login/install-login.sh RUN chmod +x /db-install/game/install-game.sh #команда которая выполниться при запуске контейнера CMD ["/bin/bash", "-c", "cd /db-install/login && sh install-login.sh && cd /db-install/game && sh install-game.sh"] Файл UpdateHosts.sh Образ представляет собой готовый к запуску артефакт, т.е при сборке в него копируються файлы в том состоянии в котором они есть на момент сборки, следовательно для того чтобы изменить конфиг нужно каждый раз пересобирать образ. Одной из самых основных настроек логин и гейм сервера - настройки сети, а конкретнее хосты к которым биндиться сокет. Самым простым вариантом как управлять этими настройками без ребилда образа - передать нужные значения через переменные окружения (environment variables). К примеру, в данном случае, команды заменяющие настройки в конфиге вынесены в отдельный файл для удобства Для loginserver #!/bin/bash echo "Updating LoginserverHostname with $LOGINSERVER_HOST" sed -ir "s/^[#]*\s*LoginserverHostname = .*/LoginserverHostname = $LOGINSERVER_HOST/" /server/logibserver/config/server.ini Для gameserver #!/bin/bash echo "Updating ExternalHostname with $GAMESERVER_EXTERNAL_HOST" sed -ir "s/^[#]*\s*ExternalHostname = .*/ExternalHostname = $GAMESERVER_EXTERNAL_HOST/" /server/gameserver/config/server.ini echo "Updating InternalHostname with $GAMESERVER_INTERNAL_HOST" sed -ir "s/^[#]*\s*InternalHostname = .*/InternalHostname = $GAMESERVER_INTERNAL_HOST/" /server/gameserver/config/server.ini Таким образом можете вынести любые необходимые настройки, которые нужно часто менять "на лету" К томуже переменные окружения удобно использовать для установки памяти требуемой для запуска в вашем sh файле, например StartLoginServer.sh java -Xmx$JAVA_MAX_MEMORY l2p.loginserver.LoginServer 2>&1 | tee /server/logs/loginserver-stdout.log В переменную можно передать $JAVA_MAX_MEMORY можно передать значение "256m", "1G" и тд Сборка образов Контейнер собираеться командой docker build (https://docs.docker.com/engine/reference/commandline/build/) В данном случае выполняем команду из рут папки с сервером (L2Server) с указанием докерфайла, для того чтобы сохранить контекст, т.к по умолчанию билдер не имеет доступа к родительским деррикториям Билд образа логинсервера docker build -t server:loginserver -f ./loginserver/Dockerfile . Билд образа геймсервера docker build -t server:gameserver -f ./gameserver/Dockerfile . Билд образа инсталятора docker build -t server:db-install -f ./install/Dockerfile . На данном этапе из этих образов уже можно запустить конйтенер с помощью команды docker run (https://docs.docker.com/engine/reference/run/) и получить работоспособные логин и гейм серверы, но мы идем дальше Примичание: В данным момент нобходимо передать переменные окружения если они используються для обновления конфигурации. База данных Сервер базы данных так же можно запустить в отдельном контейнере, например запуск mariadb docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d docker.io/library/mariadb:10.3 Больше информации о работе с бд будет далее, когда мы будем обьеденять контейнеры в одно окружение. Примичание: MYSQL_ROOT_PASSWORD - переменная окружения которую использует mariadb, подобно тому как выше было описан способ обновления конфигурации docker-compose По отдельности собраные выше образы и запущенные из них контейнеры мало чем полезны, запускать их по очереди не совсем удобно, по этому соберем стак контейнеров в одно окружение с помощью docker-compose https://docs.docker.com/compose/ docker-compose позволяет одновременно запускать и управлять несколькими контейнерами, настраивать внутренее изолированноее окружение, сеть между контейнерами, зависимости, порядки запуска и так далее. docker-compose'у нужен свой файл с инструкциями, который парситься из YAML файла. По умолчания ожидаеться файл с одноименный названием docker-compose.yml Подробнее о синтаксисе: https://docs.docker.com/compose/compose-file/ Создаем файл, помещяем его корневую папку с нашим сервером, в итоге получаем следующую стркутуру L2Server ├─── docker-compose.yml ├─── loginserver ├─── Dockerfile ├─── gameserver ├─── Dockerfile ├─── libs ├─── install ├─── Dockerfile Содержимое docker-compose.yml #версия парсера файла, влияет на доступность некоторых фич, более подробное описание на официальном сайта version: "3.9" #контейнеры, которые буду запускаться в docker-compose, их принято называть сервисами services: #сервис базы данных, будем использовать mariadb mysql: image: mariadb restart: always environment: #рут пароль MYSQL_ROOT_PASSWORD: root #при необходимости при запуске конейтенра сразу будет создана база MYSQL_DATABASE: lvldev #при необходимости при запуске контейнера сразу будет создан допонительный пользователь MYSQL_USER: localnetwork MYSQL_PASSWORD: localnetwork ports: - 3306:3306 #внешняя дериктория для сохранения данных volumes: - D:\docker\mysql:/var/lib/mysql healthcheck: test: "/usr/bin/mysql --user=root --password=root --execute \"SHOW DATABASES;\"" interval: 10s timeout: 20s retries: 10 #инсталятор базы данных db-install: container_name: db-install image: db-install #сборка образа инсталятора из докерфайла build: context: . dockerfile: ./install/Dockerfile depends_on: mysql: condition: service_healthy profiles: - db-install #сервис логинсервера authserver: container_name: authserver image: loginserver restart: on-failure #сборка образа логинсервера из докерфайла build: context: . dockerfile: ./loginserver/Dockerfile ports: - 2106:2106 environment: #переменная окружения в которую передаем память выделяему для процесса логинсервера JAVA_MAX_MEMORY: 256m #переменная окружения для обновления конфига адреса биндинга для логинсервера LOGINSERVER_HOST: "*" depends_on: mysql: condition: service_healthy healthcheck: test: "netstat -an | grep 9014 > /dev/null; if [ 0 == $$? ]; then echo 1; fi;" interval: 10s timeout: 1s retries: 10 #внешняя дериктория для сохранения данных volumes: - D:\docker\logs:/server/logs profiles: - server #сервис геймсервера gameserver: container_name: gameserver image: gameserver restart: on-failure #сборка образа геймсервера из докерфайла build: context: . dockerfile: ./gameserver/Dockerfile ports: - 7777:7777 environment: #переменная окружения в которую передаем память выделяему для процесса логинсервера JAVA_MAX_MEMORY: 5G #переменная окружения для обновления конфига внешнего хоста геймсервера GAMESERVER_EXTERNAL_HOST: "ВАШ ВНЕШНИЙ ИП ТУТ" #переменная окружения для обновления конфига внутренего хоста геймсервера GAMESERVER_INTERNAL_HOST: "127.0.0.1" depends_on: mysql: condition: service_healthy authserver: condition: service_healthy #внешняя дериктория для сохранения данных volumes: - D:\docker\logs:/server/logs profiles: - server Теперь стоит вспомнить о конфигурационных файлах логин и гейм серверов, как написано выше - docker-compose строит внутреннюю сеть между контейнерами, в которой они могут между собой общаться с помощью именовоного хостнейма которое являеться именем сервиса в yml файле. Например для того чтобы из java приложения в контейнере loginserver подключиться к базе данных в контейнере mysql можно использовать адресс mysql:3306, а чтобы из конейтенра gameserver подключиться к конйтенру loginserver можно использовать адресс loginserver:9104 и т.д (смысл думаю понятен) Меняем настройки подключения к бд в конфигах логинсервера и геймсервера, например в моем случае получилось следующее /gameserver/config/server.ini /loginserver/config/server.ini dataSource.url = jdbc:mariadb://mysql:3306/l2server?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true dataSource.user = localnetwork dataSource.password = localnetwork Также меняем настройки подключения геймсервера к логинсерверу Например в моем случае /gameserver/config/server.ini LoginPort = 9014 #имя сервиса в docker-compose.yml LoginHost = loginserver Так же на забываем менять настройки в вашем инсталяторе базы данных Обратите внимание на настройки в секции environment, здесь можно настроить параметры переменных окружения, которые будут переданны в контейнер при запуске, выше был описан момент обновления настроек с помощью енв-варов на лету. Персистентность данных Контейнер имеет своую виртуальную фаловую систему, при удалении контейнера так же удаляться все данные, в том числе и база данных сервера, соответсвенно база должна храниться гдето на хост машине. Смотрим на настройки volumes, с помощью этой инструкции можно смонтировать папку на хост машине как виртуальную в контейнере. ОСОБОЕ ВНИМАНИЕ пршу обратить на сервис mysql, в который смонтирована папка на хосте как /var/lib/mysql Эта директория используеться ядром mysql для сохранения данных, следовательно все данные остануться на хост машине (в момем случае в D:\docker\mysql) Так же, к примеру в логин и гейм серверы смонтирована папка на моем пк для записи логов D:\docker\logs как /server/logs Запуск в docker-compose Запустить стек контейнеров можно с помощью команды docker-compose up https://docs.docker.com/compose/reference/up/ С помощью настроек в docker-compose.yml файлы мы определили т.н профили запуска (с.м выще содержание файла, секцию profiles) Это нужно для того, чтобы запускать определенный сервисы, при этом пропускать другие, например при запуске профиля db-install запуститься только сервис mysql и инсталятор базы данных (нам ведь нужно запустить его лишь один раз, не так ли?), а при запуске профиля server запустятся сервисы mysql, loginserver, authserver, минуя инсталятор Запуск инсталятора docker-compose --profile db-install up --build --force-recreate Примичание: флаг --build используеться для того чтобы зафорсить ребилд контейнера, флаг опционален, удобно для дев окружения Примичание 2: флаг --force-recreate ипользуеться для того чтобы пересоздать контейнер (если он ранее был создан), флаг оционален, удобно для дев окружения Запуск логин и гейм сервера без инсталятора docker-compose --profile server up --build --force-recreate Так же с помощью docker-compose можно билдить образы без запуска, удобно docker-compose build --no-cache db-install docker-compose build --no-cache loginserver docker-compose build --no-cache gameserver Для того чтобы оставить все контейнеры используется команда docker-compose stop https://docs.docker.com/compose/reference/stop/ Для того чтобы остановить и удалить все контейнеры используется команда docker-compose- down https://docs.docker.com/compose/reference/down/ Продакшн Получилось собрать и запустить все на локальной дев машине? Отлично! Что дальше? У нас есть готовые образы, их нужно как-то передать на продакшн сервер, для этого используеться так называемый Docker реестр (Docker Registry). Реестр может быть свой, (вопрос запуска собственного реестра это отдельная тема, которая требует отдельного манула) либо один из доступных платных или безплатных в олаке. У docker есть собственный реестр - Docker Hub https://hub.docker.com/ который предоставляет один безплатный приватный репозиторий (и неограниченное количествао публичных), его и будем использовать в рамках данного мануала В докер хабе создаем рпозиторий, например его название будет "server". Для того чтобы отправить образы в свой репозиторий они должны называться по принцину "ИМЯ_ПОЛЬЗОВАТЕЛЯ/ИМЯ_РЕПОЗИТОРИЯ". В моем случае образы должны именоваться "lvlkoo/server". Можно ли загрузить несколько образом с одним именем? Нет. НО, на выручку приходят теги, у каждого образа может быть тег, и их может быть неограничение количество. Более подробнее о тегах можно почитать на официальном сайте, в основном они используеться для вариации похожих образов или версионирования Тег образу проставляеться через двоеточие "ИМЯ_ОБРАЗА:ТЕГ". Сопоставив это с именованием образов для загрузки в репозиторий получаем следующие имена образов Геймсервер: lvlkoo/server:gameserver Логин-сервер: lvlkoo/server:loginserver Инсталятор: lvlkoo/server:db-install Подобный образом можно к примеру собирать несколько разных вариаций сборки, к примеру server:gameserver-x-1200, server:gameserver-x-100 и так далее Перименовуем название образов в docker-compose.yml файлах (поле image). Например для инсталятора. Остальное по аналогии image: lvlkoo/server:db-install Ребилдим образы и пушим их в реестр с помощью команды docker push https://docs.docker.com/engine/reference/commandline/push/ или с помощью docker-compose push https://docs.docker.com/compose/reference/push/ Собираем docker-compose.yml файл для продакшн окружения. В чем отличия? Самое очевидное это то, что там будут передаваться различные переменные окружения с настройками (ип адресс хоста, итд) Второй момент - это то, что на продакшне мы не будем билдить образы, а будем скачивать из докер реестра, если Вы посмотрите на текущий docker-compose.yml там будет секция build с указанием контекста и докерфайла, она не нужна. Создаем файл docker-compose.prod.yml version: "3.9" services: mysql: image: mariadb restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: l2server MYSQL_USER: localnetwork MYSQL_PASSWORD: localnetwork ports: - 3306:3306 volumes: - /home/server/mysql:/var/lib/mysql healthcheck: test: "/usr/bin/mysql --user=root --password=root --execute \"SHOW DATABASES;\"" interval: 10s timeout: 20s retries: 10 db-install: container_name: db-install image: lvlkoo/server:db-install depends_on: mysql: condition: service_healthy profiles: - db-install authserver: container_name: loginserver image: lvlkoo/server:loginserver restart: on-failure ports: - 2106:2106 environment: JAVA_MAX_MEMORY: 256m LOGINSERVER_HOST: "*" depends_on: mysql: condition: service_healthy healthcheck: test: "netstat -an | grep 9014 > /dev/null; if [ 0 == $$? ]; then echo 1; fi;" interval: 10s timeout: 1s retries: 10 volumes: - /home/server/logs:/server/logs profiles: - server gameserver: container_name: gameserver image: lvlkoo/server:gameserver restart: on-failure ports: - 7777:7777 environment: JAVA_MAX_MEMORY: 4G GAMESERVER_EXTERNAL_HOST: "ИП ХОСТИНГ МАШИНИ ТУТ" GAMESERVER_INTERNAL_HOST: "127.0.0.1" depends_on: mysql: condition: service_healthy authserver: condition: service_healthy volumes: - /home/server/logs:/server/logs profiles: - server Важный момент по поводу имени файла: все команды docker-compose изначально ожидают что файл будет называться docker-compose.yml, без лишних приставок, но можно дополнительно передать конкретный файл с помощью флага -f например запуска инсталятора docker-compose -f docker-compose.prod.yml --profile db-install up В таком случае можно иметь по друкой несколько compose файлов, например docker-compose.dev.yml, docker-compose.prod.yml, docker-compose.prod-server=2.yml и т.д Запуск на продакшене Собственно кульминация истории и зачем все это нужно Окружение: только-что купленная хостинг машина с centos на борту, без дополнительно установленного софта. 1. Устанавливаем docker https://docs.docker.com/engine/install/centos/ 2. Устанвливаем docker-compose https://docs.docker.com/compose/install/ 3. Создаем паки /home/server/logs и /home/server/mysql 4. Копируем файл docker-compose.prod.yml в /home/server (при этом сделав нужные изменения в переменных окружения) 5. Запускаем инсталятор docker-compose -f docker-compose.prod.yml --profile db-install up 6. Вырубаем инсталятор, запускаем сервер docker-compose -f docker-compose.prod.yml --profile server up Несколько моментов о которых стоит упомянуть - Для того, чтобы посмотреть список запущенных контейнеров используется команда docker ps https://docs.docker.com/engine/reference/commandline/ps/ либо docker-compose ps https://docs.docker.com/compose/reference/ps/ - При запуске контенера (ов) вы окажитесь в т.н attached режие, в котором весь консольный ввод передаеться напрямую контейнеру, для запуска в deatached режиме нужно передать флаг -d Чтобы приатачиться обратно можно использовать команду docker attach https://docs.docker.com/engine/reference/commandline/attach/ - Для того чтобы выполнить какую-нибудь команду в контейнер без аттача можно использовать команду docker exec https://docs.docker.com/engine/reference/commandline/exec/ или docker-compose exec https://docs.docker.com/compose/reference/exec/ - Для просмотра стдаута приложения можно воспользоваться командой docker logs https://docs.docker.com/engine/reference/commandline/logs/ или docker-compose logs https://docs.docker.com/compose/reference/logs/ - После того как сделали какие-то изменения в файлах сервера контейнер нужно пересобрать (с.м выше про сборку образов), и перезалить в реестр (с.м выше про пуш образов) а дальше перезагрузить на продакшн сервере Запулить нужный образ заного можно командой docker-compose pull https://docs.docker.com/compose/reference/pull/ Например docker-compose -f docker-compose.prod.yml pull authserver -При частой локальной пересборки будеи накапливаться мусор из старых образов. Очистить образы можно командой docker image prune https://docs.docker.com/engine/reference/commandline/image_prune/ - Тему можно развивать и настроить авматические билды и пуши образов из репозитория, с тегированием по номеру билда или ревизией (возможно будет полезно командам разработчиков) Послеловие Данная статья не претендует на научность или хау-ту, а лишь передает мой личный опыт. В основном я работаю с докером в другой сфере и в этом материале лишь описывается некоторый подход который возможно кому-то будет полезен. Спасибо всем кто дочитал до конца.
-
5 балловАвтор: obius (соседний форум) /application/donate.php <?php $secretKey = 'Секретный ключ проекта'; $publicKey = 'Публичный ключ проекта'; $tpl->LoadView( "donate" ); if ( isset( $_POST['act'] ) && $_POST['act'] == 'confirm' ) { function getFormSignature( $account, $currency, $desc, $sum, $secretKey ) { return hash( 'sha256', $account . '{up}' . $currency . '{up}' . $desc . '{up}' . $sum . '{up}' . $secretKey ); } $account = isset( $_POST['account'] ) ? $_POST['account'] : ''; $currency = isset( $_POST['currency'] ) ? $_POST['currency'] : ''; $desc = isset( $_POST['desc'] ) ? $_POST['desc'] : ''; $sum = isset( $_POST['sum'] ) ? $_POST['sum'] : ''; $tpl->Set( 'publicKey', $publicKey ); $tpl->Set( 'account', $account ); $tpl->Set( 'currency', $currency ); $tpl->Set( 'desc', $desc ); $tpl->Set( 'sum', $sum ); $tpl->Set( 'signature', getFormSignature( $account, $currency, $desc, $sum, $secretKey ) ); $tpl->Block( 'prepare', false ); $tpl->Block( 'confirm' ); } else { $tpl->Block( 'prepare' ); $tpl->Block( 'confirm', false ); } $tpl->Build( "content" ); ?> /templates/default/donate.tpl [prepare] <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script type="text/javascript"> $(function () { function calculateBonuses() { var coinPrice = parseFloat($('#unitpayForm #coinPrice').val()); var coins = parseInt($('#unitpayForm #coins').val()); if (isNaN(coins) || isNaN(coinPrice) || coins <= 0) { $('#unitpayForm #sum').val(''); return; } var price = coins * coinPrice; if (price > 1) { price = 1; } $('#unitpayForm #sum').val(price); } $('#unitpayForm input#coins').keyup(function () { calculateBonuses(); }); calculateBonuses(); $('#unitpayForm').submit(function(){ var sum = parseFloat($('#unitpayForm #sum').val()); if (isNaN(sum) || sum <= 0 || sum > 1) { alert('Неверная сумма платежа'); return false; } }); }); </script> <form id="unitpayForm" action="/donate" method="post"> <input type="hidden" name="act" value="confirm"> <label for="account">Ник персонажа:</label> <input type="text" value="" name="account" required="required" id="account"><br> <label for="coins">Количество монет:</label> <input type="text" id="coins" name="coins" value="1" required="required"><br> <input type="hidden" id="sum" name="sum" value=""> <input type="hidden" name="currency" value="RUB"> <input type="hidden" id="coinPrice" name="coinPrice" value="1"> <input type="hidden" name="desc" value="Покупка внутриигровой валюты"> <input type="submit" class="btn" value="Оплатить"> </form> [/prepare] [confirm] <form id="unitpayForm" action="https://unitpay.money/pay/{publicKey}/card" method="post"> <label for="account">Ник персонажа: {account}</label><br> <label>Пожертвование: {sum} {currency}</label> <input type="hidden" name="account" value="{account}"><br> <input type="hidden" name="currency" value="{currency}"> <input type="hidden" name="sum" value="{sum}"> <input type="hidden" name="desc" value="{desc}"> <input type="hidden" name="signature" value="{signature}"> <input type="submit" class="btn" value="Подтвердить"> </form> [/confirm]
-
5 балловМеня часто просят сделать на сайте гугл переводчик и в качестве примера ставят выбор языка "Как у Rampage". Выглядит он вот так: Я сразу же заметил ряд недостатков в скрипте рампейджа и вообще в методе который был взят за его основу, поэтому при первой же возможности занялся написанием своего решения. Прочитав документацию и покопавшись в сети, я увидел, что многие вопросы связанные с кастомизацией остаются без ответов, в лучшем случае предлагаются решения похожие на скрипт рампейджа, но более упрощенные. Так уж сложилось, что я как раз искал тему для моей первой статьи на habr.com и судя по всему с темой я не прогадал. Статью практически сразу опубликовали и я получил полноправный аккаунт. Эта тема будет полезна всем верстальщикам и фронтенд разработчикам форума поэтому я размещаю её здесь. Перед тем как преступить к написанию данной статьи, я решил посетить страницу где генерируется Google Translate Widget, чтобы узнать о возможных изменениях и увидел данное сообщение: Получить доступ к переводчику сайтов больше нельзя. Это никак не отразится на тех, кто уже установил соответствующий плагин. Советуем пользователям переводить веб-страницы с помощью браузеров, имеющих встроенную функцию перевода. Не сложно догадаться какой браузер имеет ввиду Google, но речь не об этом. Самое главное, что плагин все также остается рабочим и мы можем им пользоваться. Кроме того, за неимением возможности генерировать виджет, данная тема становиться еще более актуальной, ведь потребность в машинном переводе никуда не исчезла, а Google Translate, на мой взгляд, один из самых мощных инструментов для этого. Как будет выглядеть наш пример: Для корректной работы нашего кастомного виджета необходимо подключить файлы: <link rel="stylesheet" href="css/style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> <script src="js/google-translate.js"></script> <script src="//translate.google.com/translate_a/element.js?cb=TranslateInit"></script> Содержимое style.css: body { margin: 0; padding: 0; } .page { display: flex; min-height: 100vh; } /* Фиксируем позицию body, которую меняет панель гугла*/ .page_fix { top: 0 !important; position: static !important; } /* Прячем панель гугла */ .skiptranslate { display: none !important; } /* language */ .language { position: fixed; left: 10px; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; } .language__img { margin: 2px; cursor: pointer; opacity: .5; } .language__img:hover, .language__img_active { opacity: 1; } /* content */ .content { text-align: center; margin: auto; } Используемые флаги: Разметка кастомного виджета: <div class="language"> <img src="images/lang/lang__ru.png" alt="ru" data-google-lang="ru" class="language__img"> <img src="images/lang/lang__en.png" alt="en" data-google-lang="en" class="language__img"> <img src="images/lang/lang__de.png" alt="de" data-google-lang="de" class="language__img"> <img src="images/lang/lang__fr.png" alt="fr" data-google-lang="fr" class="language__img"> <img src="images/lang/lang__pt.png" alt="pt" data-google-lang="pt" class="language__img"> </div> Содержимое google-translate.js: const googleTranslateConfig = { lang: "ru", }; function TranslateInit() { let code = TranslateGetCode(); // Находим флаг с выбранным языком для перевода и добавляем к нему активный класс $('[data-google-lang="' + code + '"]').addClass('language__img_active'); if (code == googleTranslateConfig.lang) { // Если язык по умолчанию, совпадает с языком на который переводим // То очищаем куки TranslateClearCookie(); } // Инициализируем виджет с языком по умолчанию new google.translate.TranslateElement({ pageLanguage: googleTranslateConfig.lang, }); // Вешаем событие клик на флаги $('[data-google-lang]').click(function () { TranslateSetCookie($(this).attr("data-google-lang")) // Перезагружаем страницу window.location.reload(); }); } function TranslateGetCode() { // Если куки нет, то передаем дефолтный язык let lang = ($.cookie('googtrans') != undefined && $.cookie('googtrans') != "null") ? $.cookie('googtrans') : googleTranslateConfig.lang; return lang.substr(-2); } function TranslateClearCookie() { $.cookie('googtrans', null); $.cookie("googtrans", null, { domain: "." + document.domain, }); } function TranslateSetCookie(code) { // Записываем куки /язык_который_переводим/язык_на_который_переводим $.cookie('googtrans', "/auto/" + code); $.cookie("googtrans", "/auto/" + code, { domain: "." + document.domain, }); } При смене языка добавляется куки с ключом googtrans и значением вида /ru/en /ru — это язык который переводим /en — это язык на который переводим Это стандартное поведение, поэтому я им и воспользовался для кастомизации виджета. Кликая по флажкам необходимых языков, из атрибута data-google-lang в куки записываются соответствующие значение вида /auto/выбранный_язык. Затем происходит перезагрузка и auto заменяется на язык записанный отдельно в конфиг: const googleTranslateConfig = { lang: "ru", }; Это сделано для того, чтобы мы не привязывались к одному языку. Если к примеру сайт переведен на 2 языка, русский и английски, то мы можем передать текущий язык в конфиг и правильно обработать его. Все доступные языки и их код стандарта ISO-639-1 можно найти тут. Функции добавления и очисти куки я вынес отдельно, чтобы была возможность провести дополнительные проверки и вызвать в других местах. Важный момент, куки необходимо менять для основного домена и всех поддоменов. Теперь, имея контроль над нашим виджетом, мы можем без проблем реализовывать более сложные дизайны: Репозиторий с проектом на GitHub Cсылка на оригинал статьи
-
5 балловПожалуй начнем без долгих вступлений. В большинстве случаев сервер запускается на удаленной машине, а основная машина базируется на WinOS. Именно такой способ я и буду разбирать. 1. Необходимый софт Putty [скачать] WinSCP [скачать] 2. Соединяемся с сервером Запускаем putty.exe Вводим IP сервера и запускаем. Скрин снизу. Далее вводим логин и пароль от сервера. После удачного логина перед вами появится командная строка. 3. Установка компонентов Java JDK MySQL сервер/клиент Установка Java: Открываем терминал Вводим: apt-get install sun-java6-bin sun-java6-jre Установка Java 8: apt-get install oracle-java8-installer Вводим: update-java-alternatives -s java-6-sun #Устанавливаем ява sun - стандартной Java средой Проверка, вводим: java -Xmx100m -version #Если ошибок не выдает, то все ок Установка MySQL: Открываем терминал Вводим: apt-get install mysql-server mysql-client Во время установки система потребует ввести пароль для root пользователя MySQL 4. Передача сборки Открываем WinSCP который мы скачали в начале Подключаемся через него к нашему серверу (аналогично как в putty) Допустим у вас уже есть готовая сборка, не архивом,а просто папка В WinSCP на сервере создаем папку под сборку, к примеру /root/server В WinSCP заходим в папку на сервере, и выделяем нашу папку со сборкой на компе Нажимаем F5 -> пошла загрузка 5. Установка сборки Создаем базу mysql Вводим: mysql -u root -p #От нас потребуют пароль от root юзера который мы указывали при установке Вводим: CREATE DATABASE `server`; #Где server - имя создаваемой БД Вводим: exit Вводим: /etc/init.d/mysql restart Выдача прав root: grant all privileges on *.* to 'root'@'%' with grant option; С созданием базы все, теперь нужно ее заполнить Вводим: cd /root/server/tools #На PW папка не tools, а sql Вводим: chmod +rwx *.sh #Это дает rwx права sh файлам в данной папке Вместо *.sh желательно вбивать имена файлов, на PW это: login.sh и game.sh Вводим: sh ./installer.sh и устанавливаем сборку #На PW: sh ./login.sh и sh ./game.sh 6. Настройка и запуск сборки Настройку описывать не буду, там все просто Просто запускаем WinSCP -> соединяемся -> нажимаем на конфиг. файлы,открываем,редактируем,сохраняем Регистрация ГС (в PW не требуется) Вводим: cd /root/server/game/ #Путь до папки с гейм-сервером, в PW: gameserver Вводим: chmod +x registergameserver.sh #Выдаем права на запуск. Вводим: sh ./registergameserver.sh #Запускаем,регистрируем ГС Запуск сборки Вводим: cd /root/server/login/ Вводим: chmod +x *.sh или chmod +x start.sh Вводим: sh ./start.sh Если нету ошибок,поздравляю вы запустили логин, аналогично запускаем гейм Вводим: cd /root/server/game/ Вводим: chmod +x *.sh или chmod +x start.sh Вводим: sh ./start.sh Все, сервер запущен. Внимание, для установки Java теперь нужно добавить в ручную репозитарий. Для установки требуется добавить non-free репозитарии. В файле /etc/apt/sources.list было так: deb http://ftp.us.debian.org/debian/ squeeze main Сделать надо так: deb http://ftp.us.debian.org/debian/ squeeze main non-free После этого вы без проблем поставите Java. Внимание, для установки Java 8 нужно в ручную добавить репозитарий. deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise maindeb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main /etc/apt/sources.list - добавить в этот файл. После того как вы добавили репозитарий, вам не обходимо обновить список командой "apt-get update". После чего начать установку Java с помощью команд которые описаны выше. //франция - зеркало репозитария. deb http://ftp.fr.debian.org/debian wheezy main contrib non-freedeb-src http://ftp.fr.debian.org/debian wheezy main contrib non-freedeb http://ftp.fr.debian.org/debian wheezy-updates main contrib non-freedeb-src http://ftp.fr.debian.org/debian wheezy-updates main contrib non-freedeb http://ftp.fr.debian.org/debian wheezy-backports main contrib non-freedeb-src http://ftp.fr.debian.org/debian wheezy-backports main contrib non-freedeb http://security.debian.org/ wheezy/updates main contrib non-freedeb-src http://security.debian.org/ wheezy/updates main contrib non-free //Проблемы которые могут возникнуть Проблема: root@onix:~/onix/login# ./LoginServer_loop.sh: 2: ./LoginServer_loop.s: not found Исправление: Измените sh файл через notepad++, Правка > Формат конца строк > Преобразовать в Unix-формат (LF) Автор мануала: Pro (делалось для сборки pwsoft) Дополнил мануал: SteveDogs.
-
5 балловactionname-e.dat описание и назначение меню действий Alt-C (сесть, встать, аплодисменты и.т.д) armorgrp.dat список всех одежды в игре с описанием bighead.int настройка и описание классов binkw32.dl убыстряет игровой процесс ирая в два окна castlename-e.dat название замков и клан холлов chargrp.dat описание текстур чаров (обычно здесь меняет нижнее бельё на чаров) chatfilter.ini тут хранятся настройки наших окошек чата (общий, торговый, клановый, пати и алли). Лично я советую, чтоб клановый, алли и пати чат обязательно отображался на всех окошках, а то можно пропустить что-то важное classinfo-e.dat информация о разных классах, показывается при создании чара commandname-e.dat здесь хранится информация о командах, которые можно прописывать в чате. Пример:/loc - выведет ваше месторасположение по 3 осям - x,y,z. Не стал бы это трогать, так как можно нарушить структуру и игра может зависать, или вылетать. Сore.* под Windows. Данный файл требуется для запуска игры Lineage 2 creditgrp-e.dat здесь хранится информация о настройке заставки о создателях игры. Engine.* что то крутое - коль из него достают токин для сервера env.int свечение заточенного оружия etcitemgrp.dat собирание вещей в одну ячейку (напр. книги) (сопоставление текстуры с ID) eula-e.dat соглашение (Согласен/Не согласен) перед выбором сервера, соответствующее серверу gametip-e.dat полезные советы при загрузке игры hennagrp-e.dat как я понял, тут находятся имена тату huntingzone-e.dat сопоставление локации и название территории (названия зон охоты) itemname-e.dat здесь хранятся имена и описание вещей Вещи, Кристаллы, Цены. l2.ini содержит основные настройки клиента. И лишь малая часть из них может быть изменена непосредственно через опции клиента Localization.ini локация шрифт и текст logongrp.dat определение локации musicinfo.dat где какую музыку проигрывать Npcgrp.dat часть дропа спойла составная npcname-e.dat файл отвечает за отображение имен мобов. Над головой указаны: агр, хп, лвл мобов obscene-e.dat здесь находится фильтр мата, а если говорить конкретней не сам фильтр, а тот текст который фильтрует сервер. option.ini Все те параметры, которые мы задаем в настройках игры, хранятся здесь. Если игра запускается, но разрешение экрана не то, что нужно (все необходимые менюшки-окошки за границей видимости и нельзя даже произвести сброс параметров по-умолчанию) - удалить файл Option.ini перед запуском игры. optiondata_client-e.dat описание аугментированного оружия questname-e.dat В этом файле хранятся все названия квестов которые вы видите в клиенте когда бирете квест raiddata-e.dat Вся история рейд боссов игры servername-e.dat здесь распологаются названия серверов. Тоесть когда мы заходим в Lineage 2, авторизовавшись мы выбираем сервер. Так вот в этом файле хранятся их имена и их можно изменить на собственное. skillgrp.dat отвечает за связь скилла и его оформления, и за панель инфы о НПЦ/Мобе. Составная часть дропа и спойла skillname-e.dat названия скилов и их описание. Составная часть дропа спойла. skillsoundgrp.dat Озвучивание действий скилов. staticobject-e.dat в нем хранятся названия дверей которые существуют в Lineage symbolname-e.dat Точно незнаю, но точно знаю, что здесь есть тот текст или "смайл" когда в клиенте мы ругаемся матом вместо мата появляется sysstring-e.dat тут храниться инфа из меню логин, чар и т.д. меню, названия кнопок. systemmsg-e.dat Тут храниться системные сообщения. Пример: Вы нанесли X урона. Вы подобрали 12 аден. Я думаю понятно про что я говорю. user.ini содержит информацию о сервере и настройках клиента. В файле реализованы: оконный режим без рамки, увеличина дистанция отображения ников zonename-e.dat Тут храниться все то что появляется когда мы находимся на какой либо территории. Тоесть по среди экрана текст высвечивается - Gludio Territory и тд. localization.ini, largefont-e.gly, LargeFont-r.gly, LargeFont.gly, nwindow.dll, smallfont-e.gly, SmallFont-r.gly, smallfont.gly Это все нужно для поддержки русских шрифтов в патчах и чате. binkw32.dll убыстряет игровой процесс ирая в два окна help-r.utx отвечает за встроенную базу знаний в игру elp-r.utx Интерактивный помощник. Замена англоязычной версии меню Справка. L2Font-e.utx Текстуры основные игры, экран загрузки, карты. L2UI_CH3.utx фаил отвечающий за вид оформления игрового меню L2Text папка в которой полная русификация хелпа+некоторые квесты на русском. GameGuard Каталог (ГГ), с набором файлов, для защиты клиента от хакеров и читеров, Animations содержит текстуру все классов а так же эффектов действий Music все мелодия игры Sounds музыка и звуки в игре: движений, нажатий, действий и т.д. StaticMeshes текстура всех материалов (одежда, оружие, города) Во общем то что мы видим 3D объекты SysTextures текстура : карт, кнопок, иконок, меню...... 2D System главная папка. все настройки по отображение, движение, визуализации игры Voice озвучивание действий при начале игре. (например: для создание чара.....) fdarkelf.utx Текстуры женских моделей Тёмных эльфов fdwarf.utx Текстуры женских моделей Гномов felf.utx Текстуры женских моделей Светлых эльфов FFighter.utx Текстуры женских моделей Людей бойцов FMagic.utx Текстуры женских моделей Людей магов FOrc.utx Текстуры женских моделей Орков бойцов FShaman.utx Текстуры женских моделей Орков шаманов fkamael.utx Текстуры женских моделей Камаель mdarkelf.utx Текстуры мужских моделей Тёмных эльфов mdwarf.utx Текстуры мужских моделей Гномов melf.utx Текстуры мужских моделей Светлых эльфов MFighter.utx Текстуры мужских моделей Людей бойцов MMagic.utx Текстуры мужских моделей Людей магов MOrc.utx Текстуры мужских моделей Орков бойцов MShaman.utx Текстуры мужских моделей Орков шаманов mkamael.utx Текстуры мужских моделей Камаель gametip-e.dat полезные советы при загрузке игры
-
4 баллаПосле обновления API Unitpay у многих возникла проблема с цифровой подписью, которую необходимо генерировать используя секретный ключ и все передаваемые параметры. На поддерживаемых CMS, в модулях и фреймворках это конечно уже работает, но я попробовал реализовать свое решение с использованием технологии ajax, то есть без перезагрузки страницы. Я постарался сделать форму красивой и понятной, реализовал предварительный подсчет итоговой стоимости, вывод ошибок, запрет ввода букв в числовое поле и прочие неявные мелочи. Данный код можно использовать прямо как есть, то есть залить все файлы на свой хостинг, вписать свои данные и страница оплаты полностью готова к работе. Так же можно интегрировать в существующую форму, для этого понадобиться подключить gw.unitpay.js, указать в action путь к gw.unitpay.php, добавить специальные data атрибуты и наименование полей. Скрипт написан на чистом js и не требует подключения каких-либо дополнительных библиотек. Если вы нашли ошибку в работе скрипта или у вас есть вопросы, пишите сюда Если вы знаете как улучшить код, то предлагайте свои правки в репозиторий и я с удовольствием их добавлю. Демонстрация Скачать Ответы на вопросы: Да. Данный скрипт будет работать везде где возможно выполнение php скрипта Ссылка на оригинал статьи
-
4 баллаВсем привет перезалил я свой канал с мануалами теперь тут плейлист с 32-мя мануалами. PS/ Одного какого то мануала не хватает на канале тут он перечислен но в плей листе его нет напишите в комментах какой именно отсутствует я залью его. Ссылка на плейлист: https://www.youtube.com/playlist?list=PL96mdHb8V74FOpWI18Hcnj_NSjh9Td5wT Содержание : NPC Магазин и Диалог Гайд по вытаскиванию NPC из текстур в Lineage Гайд по решению проблем автозамены скилов на GOD хрониках . Гайд по созданию текстур в Lineage 2 .utx Гайд по установке сервера Lineage на домашнем компьютере Изменение внешнего вида NPC Изменение языкового пакета папки system с Англ. на Рус. в Lineage 2 Как Добавить телепорты и изменить названия телепортов у Хранителя портала . Как запустить сервер Lineage 2 на внешних Ip Как играть с друзьями на сервере Lineage 2 без внешнего ip на домашнем ПК Как изменить название сервера Lineage 2 Как перенести Community (Камьюнити)с одной сборки на другую) Как сделать PvP зону в городе Lineage Как сделать возможность создания персонажей с ником на Русском языке в Lineage Как сделать фарм зону за 30 минут, и предать серверу Особенности . Как создать предмет с ограниченным временем использования Как создать собственного Рейдового Босса ( РБ ) Как создать собственного Рейдового Босса ( РБ ) продолжение Как создать собственное умение, скил, баф в Lineage 2 Компиляция исходников Lineage II Java с использованием IDE Логотип при запуске сервера Lineage 2 Меняем место спавна созданных персонажей Lineage 2 Настройка предметов выдающихся новым персонажам при создании. Не передающиеся предметы для продажи в community board Lineage 2 Один и тот же NPC но с разным функционалом Основы правки скилов и стартовые знания Lineage 2 Редактируем Community Board Lineage Создаём патч для подключения клиента к серверу Lineage Создание нового предмета Урок как войти в режим разработчика Lineage 2 Урок написания дроп листа с нуля в Lineage 2 Урок по починке открывающихся предметов (Коробки упаковки и тд.) Lineage 2 Ссылка на плейлист: https://www.youtube.com/playlist?list=PL96mdHb8V74FOpWI18Hcnj_NSjh9Td5wT
-
4 баллаСобираем исходники L2 при помощи ANTa, что же нам для этого понадобится? Сам ANT - Актуальная версия Java SE Development Kit - 6, 7, 8 Исходники с наличием файла build.xml, который обычно находится в корневой папке исходников 1. Скачиваем все это дело, размещаем в удобных для вас директориях, у меня все это располагается по таким путям D:\Program Files\AntC:\Program Files\Java\jdk1.8.0_65 2. Переходим "Свойства компьютера" - "Дополнительные параметры системы" - "Дополнительно" - "Переменные среды" https://yadi.sk/i/vBARbojZnGdJ7 3. Добавляем в "Системные переменные" в переменную Path, через символ ";" пути до папок bin от установленного софта. Прежде чем добавлять, убедитесь, что ранее не была добавлена, путем внимательного просмотра содержания "Значение переменной" нажмите "Ок" https://yadi.sk/i/gv85VpvXnGedR https://yadi.sk/i/K0jm8tMInGekr 4. В "Системных переменных" нажимаем "Создать" для создания новой переменной и присваиваем ей имя JAVA_HOME и значение путь до вашей папки JDK, жмем "Ок" во всех окнах с переменными и "Применить" в "Доп. параметрах" https://yadi.sk/i/4pSLGQa1nGftY 5. Переходим в папку с вашими исходниками (сурсами, Source и т.д.), где находится файл Build.xml и создаем там текстовый файл с простым содержанием ant -l Build.logилиant -f buildScripts.xml -l buildScripts.log Где -f наименование файла из которого берется информация для сборка исходов, по дефолту это build.txt, а -l наименование файла в который будет поступать информация и компиляции исходников или же возникающих проблемах. Сохраняем и переименовываем формат файла в .bat и запускаем данный файл https://yadi.sk/i/aHYdRDeCnGhu9 https://yadi.sk/i/a_9mZAH9nGiGy 6. При закрытии командной строки и успешной компиляции, вы увидите вот такое сообщение в конце лог файла BUILD SUCCESSFUL а так же появится новая папка build в которой будет находится скомпиленная сборка. https://yadi.sk/i/Sw8pbTPQnGjz
-
4 баллаСсылка на Видео Инструкцию Урок по Photoshop - Как сделать объемный текст
-
4 баллаКруглый прогрессбар, линейный или просто вывод процента в числовом виде, обычно делают через JavaScript. Самым большим минусом данного способа является то, что через инспектор кода можно без проблем узнать онлайн, поэтому нужно не только ставить процент, но еще и накручивать онлайн для самых любознательных. Кроме того, не каждый умеет написать скрипт и уж тем более правильный скрипт. Все это можно сделать так же и через php, изменив всего пару строк в файле движка Stress Web 13 Итак начнем: Открываем файл module/server.php Находим: if ( !defined( "STRESSWEB" ) ) die( "Access denied..." ); Ниже дописываем: $server_full = 500; 500 - это онлайн который будет считаться 100% Далее находим: $slink = ( $l2cfg["mod_rewrite"] ) ? "/stat/s{$_S}":"/index.php?f=stat&sid={$_S}"; И ниже вставляем: $server_percent = intval( $Online / ( $server_full / 100 ) ); if ($server_percent > 100) { $server_percent = 100; } Тут мы рассчитываем процент и если процент после вычисления больше 100(онлайн больше 500), то записываем 100 Далее находим: $tpl->Set( "name", "{$l2cfg["gs"][$_S]["title"]}" ); Ниже дописываем: $tpl->Set( "percent", $server_percent ); Сохраняем! Теперь в шаблоне, в файле server.tpl доступен новый тег {percent} который соответственно выводит процент онлайна от указанного ранее максимального онлайна. Этот новый тег вы можете писать в любом месте между тегами [item] [/item] файла server.tpl Кто не хочет делать все это самостоятельно, можете скачать готовый файл тут
-
4 балла
-
3 баллаТребования: Программы: 1 File Edit для клиента что бы включить кнопку 2 L2ClientDat Для описания итема точнее ид итема с описанием 3 Текстовый редактор 4 Сам сервер File Edit открываем файл l2.ini ищем строки [PrimeShop] UsePrimeShop=false UseClassicPrimeShop=false UseGoodsInventory=false NewPrimeShop=true Если нет строк делаем как выше. Сохраняем. Едем дальше... Программой L2ClientDat открываем файл из папки system в клиенте Productid-e.dat product_name_begin id=1080001 outer_name=[Маленькая Коробка Фортуны] description=[] icon=[br_cashtex.item.br_cash_lucky_box_i00] icon_panel=[None] mainsubject=[] product_name_end Копируем все в текстовый редактор таких строк там много Нам нужно product_name_begin id=1080001<---- вот эти цифры это и есть те самые картинки в магазине в игре Shot00000.bmp Открываем на сервере файл PrimeShop.xml шапка страницы с подсказкой что вписывать <?xml version="1.0" encoding="UTF-8"?> <list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/PrimeShop.xsd"> <!-- cat = 1 - Exping, 2 - Supplies, 3 - Cosmetic, 4 - Specials, 5 - Other --> <!-- panelType = 0 - None, 1 - Event, 2 - Sale, 3 - New, 4 - Best --> <!-- recommended = 1 - Top, 2 - Left, 4 - Right --> <!-- paymentType = 0 - Euro, 1 - Adena, 2 - Hero Coin --> <!-- on EU 1 NC coin/Prime point shows as 0.01 euros --> <!-- startSale = unixTime --> <!-- endSale = unixTime --> Шаблон написания (<item id="1081242") <--- Вот сюда ID из файла Productid-e.dat (cat="1")<--------Категория Shot00000.bmp (paymentType="0" price="150")<--------- Тип оплаты рублики , Адена, или хиро коины panelType="3" recommended="0" (startSale="315558000" endSale="2127452400" )<------ это время начала и конца продаж в уникс коде в браузере вводите декодер уникс времени и поймете как это работает dayOfWeek="127" startHour="0" startMinute="0" stopHour="23" stopMinute="59" stock="-1" maxStock="-1" salePercent="0" minLevel="0" maxLevel="0" minBirthday="0" maxBirthday="0" restrictionDay="0" availableCount="0"> (<item itemId="37562" count="1" />)<----- это итем айди сам Id в сервере предмета берется из папки stats/item или при запущенном сервере альт + G поиск итема (<!-- Emperor's Vitality Tonic (Large) -->)<---- описание чтобы не запустаться </item> заменили Id и все больше не трогайте как заработает играйтесь со временем для ограниченных продаж сохраните сервак на перезагрузку и все Вопросы остались в пм пиши Не понравилось что тут написано не читай пожалуйста я тебя не заставляю это делать
-
3 баллаКогда сворачивается окно lineage 2 меняется яркость? Многие годами мучаются с этой проблемой, некоторые вообще перестали сворачивать окно л2 чтобы яркость экрана не изменялась. Но решения на самом деле очень простое. Все что вам необходимо это отредактировать всего один файл в папке system, это та папка, которую вам надо менять для игры на любом сервере л2. И так что нам понадобится для того что бы исправить яркость экрана при свернутом окне: 1. Программа L2 FileEdit ( Скачать: https://yadi.sk/d/4txLm6a63JZDW7 ) 2. Открываем при помощи программы FileEdit файл l2.ini в папке system и ищем в 2-х местах параметры Brightness, Contrast, Gamma ( См. Прикрепленную картинку) По умолчанию их значения такие: Brightness=0.800000 Contrast=0.700000 Gamma=0.800000 3. Заменяем эти значения вот этими ( См. Прикрепленную картинку): Brightness=0.500000 Contrast=0.500000 Gamma=1.000000
-
3 баллаНедавно создавал топик в общении на тему актуальности манула по созданию и развитию собственного проекта lineage 2 с нуля. Мнения разделились, но вопрос рекламы явно интересен многим начинающим администраторам, поэтому в благодарность форуму и его обитателям за отзывчивость и наставления, данный гайд будет посвящен рекламе и раскрутке сервера. Пользоваться я буду данными полученными из личного опыта и в конце озвучу свои скромные результаты. Оглавление: 1) База 2) Выбор площадок 3) Итоги 1. Пускать рекламу на "сырой" проект - равносильно подаянию "якобы-нищим" в вагонах столичного метро - лучше просто отдать деньги местным форумчанам, Вы все равно их потеряете! Поэтому все далее описанное подразумевает, что у Вас уже есть: * Поставленный сервер (машина, сборка, веб-обвязка, форум, SSM) * Настроен авто-донат (ОЧЕНЬ ВАЖНЫЙ ПУНКТ) * Определены бюджет и дата открытия 1.1 Первое с чего необходимо начать это решить простую задачу - показать входящему трафику (потенциальным игрокам), что проект сможет как минимум стартовать и на нем будет некое количество игроков. Как показала практика 97% трафика переходящего на Ваш сайт по рекламе - первым делом идут на форум! Форум - есть показатель "раскрученности" и жизнеспособности вашего проекта. Если зайдя на форум, посетитель видит нулевые показатели активности, то в 90% случаев он разворачивается не ознакамливаясь с описанием проекта. Таким образом, для начала нам необходимо наполнение форума и создание на нем активности или видимости этой активности. Теперь разберем по пунктам, как этого добиться: a) Наполнение контентом - заливайте на форум максимум информации которая может быть полезна будущим игрокам, описание сервера, анонсы обт\открытия, разнообразные акции (кстати это пункт SMM), гайды по игре, информация о технических доработках и игровых изменениях, полезный софт (прим. патч клиента для игры на Win 10), в общем все, что может быть интересно к ознакомлению, но без лишнего хлама! * маленький совет, если Вы являетесь единственным администратором на проекте, создайте пару левых учетных записей со статусом адм\гм\модер - так не ведающие будут думать, что проектом занимается целая команда b.) Срач - к моменту запуска рекламы и старта ОБТ, на форуме уже должна быть активность! Наивно полагать "Вот ща я запущу обт и игроки сами придут ко мне на форум и там будут общаться" - нет не будут, и более того, увидев 0 активность (не считая 5 учеток админов, которые Вы создали и yandex, google роботов) игроки скорее всего даже не зайдут на ОБТ. Поэтому как бы это не выглядело парадоксально, Вам опять таки придется создавать видимость этой активности. Попросите друзей, которые играли\играют в л2, создайте топики на тематических форумах ( не рассчитывайте на халявный help, как минимум будьте готовы скинуть на бутылочку-другую), регистрируйте фейковые учетки и от их лица создавайте топики, посты и лайки. В идеале у Вас должны быть как минимум два живых сайда, которые необходимо столкнуть лбами и на форуме и в игре! с) Статистика. Есть определенные зависимости между живостью в темах и пользователями\посетителями. Так к примеру если на вашем форуме очень много сообщений и топиков, а активных пользователей за 15 мин один, не сложно догадаться, что админ тупо релогает учетки и набивает посты, согласитесь убого выглядит в глазах еще не играющего на вашем проекте игрока. Но скрывать статистику - тоже не лучшее решение, т.к. это первое на что смотрят перешедшие с сайта игроки. На нее идет не малый ориентир. Значит необходимо все это дело "настроить" Если Вы используете для своего форума платформу IPB, то по дефолту в верхнем правом углу окна статистики будет стоять "Пользователей онлайн: (N-число) за последние (N-времени). Поставьте в админке вывод активных посетителей скажем за 2 часа, а в коде уберите выводящееся время или поменяйте на 15 мин (более сложный вариант). Тогда все кто посещал ваш форум, будут показываться активными в течение всего этого времени. Так же разбавить серую унылость в списке посетителей нам поможет чудо-скипт Elven-script, ознакомиться и скачать его Вы можете Здесь в общем это накрутка пользователей и активности на форуме, юзайте аккуратно дабы не возникало подозрений со стороны игроков И не забываем выражать благодарность авторам плюшек. 1.2 С форумом вроде бы разобрались, теперь переходим к SMM. Принцип работы и назначение примерно схожи с форумом, у Вас должны иметься заполненные контентом группы\странички в популярных среди игроков социальных сетях - по дефолту это VK и Facebook, реже OK и Instagram. Перед тем как пускать "живой" трафик на эти странички, там так-же как и в случае с форумом необходимо навести марафет. Попросите добавиться всех ваших друзей и знакомых, накидайте контента и накрутите хотя-бы пару сот подписчиков и с десяток постов с лайк-репостами. Помогут в накрутке разнообразные сервисы работающие как платно, так и бесплатно - по принципу ты налайкал, получил за это бонусы, потом за эти бонусы накрутил подписчиков\лайков в свою группу. Лично я пользуюсь данными двумя: Socgain.com (не реклама) и fastfreelikes.com (не реклама). Далее Вы ведете трафик с форума на данные страницы и обратно. Самый простой способ это акции поощряемые игровыми плюшками. Благо примеров полным полно, заходим на форум любого топового проекта и черпаем от туда идеи (хочу заметить уже проверенные на практике). Как только в группу начинают вступать реальные люди, которые реально играют в ла2 - начинайте по-тихому чистить страничку от "собачек" (накрученные мертвые души). Еще один не маловажный пункт это спам по соц.сетям, эл.почте, скайпам, информационных сообщений об открытие вашего проекта, писать стоит в первую очередь КЛам и ПЛам среднего уровня, контакты которых можно найти на форумах live проектов Lineage 2 соответствующих хроник. Делать это необходимо параллельно с запуском основной рекламы. И да - будет много агра, поэтому стоит заранее запастись левыми аккаунтами с которых вы будете проворачивать данные махинации. В окончание данного пункта хочу отметить, что по эффективности грамотный SMM ничем не уступает платной рекламе, и заслуживает отдельной темы на несколько страниц. * Так же во время запуска ОБТ стоит посадить некоторое количество фейковых персонажей разной масти на офлайн трейд с надписями типа "увидимся на старте" "Норм серв" и т.п. но делать это тоже необходимо с умом. 2. Выбор площадок. Можно условно разделить на платные и бесплатные, но в 90% случаев это именно платная реклама, которая приносит разный результат. 2.1 Анонсеры. Существует с десяток сайтов-анонсеров где можно и необходимо размещать рекламу вашего проекта. Подбор не сложен, это те площадки сайты которых вываливаются в топе поисковиков по определенным релевантным запросам. Для моего проекта мною были выбраны следующие: l2hop.com (не реклама) la2-anons.ru (не реклама) l2oops.com (не реклама) l2op.ru (не реклама) new-lineage.ru (не реклама) pickns.ru (не реклама) mmotop.ru (не реклама) l2top.ru (не реклама) la2-anons.ru (не реклама) Последний кстати, почему-то на момент написания данной статьи лежит Все эти сервисы работают по принципу размещение кнопки с их кодом, на вашем сайте, с последующим попаданием в анонсы и рейтинги игровых серверов. Но не надо думать, что Вы сможете добавиться на все из них, некоторые попросят за это небольшую сумму денег, а некоторые и вовсе проигнорируют ваши заявки. В 90% случаев размещение кнопки возможно только без изменения кода (в том числе CSS) и Вам доступно до 4х позиций на вашем сайте (углы экрана), так же есть уникумы, которые категорически не приемлют наличие кнопок других анонсеров на вашем ресурсе. Из личного опыта: la2-anons.ru (не реклама) - прямо в условиях просит за добавление вашего сайта 600 деревянных, после оплаты практически сразу добавляет ваш проект в список серверов, которые скоро откроются. И хоть 600руб - это сумма которая была указана за неделю пребывания в данном анонсере, по истечении этого времени и уже после старта сервера, мой проект перевели в раздел уже открывшихся и он висит там по сей день (около 1.5 месяцев). Лично мне данный субъект вел около 20 уникальных посетителей в сутки. new-lineage.ru (не реклама) - второй анонсер, который я добавил, хоть у них в соглашении и указано, что добавление якобы бесплатно, в течение дня со мной связался админ и попросил за добавление 300р. Черт с ними, это не деньги, отдал и получил размещение, VIP статус брать не стал, т.к. рядом со мной крутился La2Dream.su (не реклама), как такой же простой смертный без vip статусов. Еще примерно 20 уникалок в копилку общего трафика. На l2top.ru (не реклама) и mmotop.ru (не реклама) я попал совершенно бесплатно, хоть и не сразу. От других анонсеров, эти два отличает рейтинговая система выдачи. Т.е. не важно какие фильтры ставит потенциальный игрок при поиске игрового сервера, позиция в выдаче напрямую зависит от количества голосов за ваш проект! Так же очень важно проверить не существует ли уже добавленный в рейтинг проект со сходными названием и доменом, у меня как раз случилось так, и пиар я хочу вам сказать не очень хороший. Там были негативные отзывы о предыдущей администрации ( и мало того негативные, так еще и не обработанные по возражениям) и все это привело к тому, что я добавился туда только спустя неделю. Про остальных резидентов из выше упомянутого списка я вообще промолчу. Господа просто проигнорировали мои потуги добавиться к ним в анонсы, не предлагали никаких сумм, проще говоря забили. В завершение пункта, отмечу, что не стоит облеплять Frontend сайта вашего проекта кнопками анонсов, как остановку на улице - выглядеть в галазах игроков это тоже будет дешево и убого. * Маленький лайф-хак. Можно создать клон вашего основного сайта и вывесить его на отдельный домен, облепить его самыми печальными анонсами, которые только развиваются и имеют низкую посещаемость, а с этого клона поставить линк на ваш основной форум. В итоге мы имеем: еще некоторое количество трафика, люди могут регистрироваться и скачивать патч с клона, а перейдя на форум они при обратном возвращении через шапку форума будут попадать на основной сайт. * На вашем основном сайте должны быть счетчики посещаемости с открытой статистикой, для того, чтобы апнуть цифры, можно воспользоваться автосёрфингом. 2.2 Медийная реклама. Переходя на всё те же сайты анонсеров, мы всегда натыкаемся на разного рода, и масти обои, и баннеры. Обои - один из самых эффективных видов рекламы приносящий дикий трафик на Ваш проект, но стоит это удовольствие безумно дорого и лично мне как начинающему и не опытному, были не по карману. Да и слить в только вылупляющийся проект пару-другую тысяч баксов - проще простого. Поэтому мной было выбрано размещение одного единственного баннера на mmotop. Не судите строго за банер, это мои первые работы. Как оказалось, размещение подобного рода медийки почти всегда происходит не через администрацию анонсеров, а через рекламное агенство, которое арендует "места" на сайтах анонсов, и уже в свою очередь пересдает их в аренду конечному заказчику. В моем случае таким агентством стал сервис oyy.ru (не реклама). Если Вас интересует какая-то конкретная площадка, то вы легко можете увидеть подобные ссылки на рекламодателя, под действующими баннерами. Как и многих других меня прямо таки скажу заманили надписью "от 20 руб. за 1000 показов" На самом деле все оказалось куда прозаичнее - минимальное количество показов которые вы можете заказать = 100.000 и того на размещение 1го банера пришлось влить 2000руб. Будучи связанным ранее с контекстной рекламой, я ошибочно предположил, что сто тысяч показов, умноженные на минимальный по меркам яндекса и гугла CTR в медийке, я получу более дешевый, чем обычный контекст - траф. Ага... Вот результаты: Просмотры скручиваются нещадно, по 20-25к в сутки, откуда такая посещаемость раздела l2 в mmotop только богу известно, их же открытый счетчик указывает что общее число посетителей примерно 25к за день и это по всем разделам, а мой баннер пилил место с банером конкурента выстреливая поочередно. Путем не сложных математических расчетов, получаем 2.000 : 314 = ~6 руб 40 коп. за клик. К примеру в том же yandex.direct можно купить клики схожего по релевантности трафика за 4 рубля, будучи полным нолем в контекстной рекламе, и при этом быть уверенным на 99% в уникальности этих кликов (яд возвращает бабло за с клики произведенные в сутки с 1го IP) Вобщем дело ваше товарищи, как говориться на вкус и цвет, но я думаю можно и повыгодней. Такую же самую по принципу рекламу, можно пускать через таргетинг yandex\google в социальные сети. И как подсказали знающие люди, только так и можно размещать подобного рода рекламу в соц.сетях. При всем желании разместить свой банер скажем Вконтакте - вы не сможете, объявление забанят. Яндекс и Гугл в этот раз я не использовал, а стоило! 3. Итоги * Банер - покрутился 4 дня перед самым стартом сервера * Анонсы - запущены за неделю до старта сервера * Рейтинги - запущены на старте сервера * SMM и СПАМ - минимальный, честно говоря было уже впадлу. (не повторяйте моих ошибок) * Контекст - не крутился вообще (не повторяйте моих ошибок) Было потрачено около 3к рублей на платную рекламу, проделана работа по форуму и SMM, спамил я крайне не активно и с учетом того, что донат я настроил только через неделю (вместо заявленных игрокам 3-х дней) я ожидал полного фейла. Стартовый онлайн не перевалил за 50 Далее устаканился и держался в районе 30 около 2х недель, потом еще столько же 20. На мое удивление серв окупился и принес 100% прибыль сверху. (в общем около 10к руб) В любом случае изначально было решено тянуть проект годик-два из своего кармана. Не серчайте на качество мануала, это мой первый, по вашему желанию и моему нарастающему опыту - он будет обновляться и дополняться.
-
2 баллаТак вот хочу поделится своим опытом! Глава первая: Люди с кем стоит и не стоит работать! Steve Dogs - неоднократно пользуюсь услугами! Человек в общении приятен! помимо основной работы всегда подскажет то что знает! mcwa - До сих пор пользуюсь услугами данного человека и сбегать не собираюсь!!! Этот уникум с железными нервами, ответит на любой вопрос даже самый тупой в любое время суток!!! Тех поддержка на высочайшем уровне!!! •°•°•PsycHoO•°•°• - тут расписывать вообще нечего не надо! Быстро, качественно и надежно. gvb - обращался за помощью, поп*здели в скайпе, подсказал быстренько, заработал пивка! хороший человек SmokiMo - знает все о серверостроении, кодер, всегда помогал, отвечал на столько глупые вопросы что п*здец! этому человеку надо памятник поставить. Demoncool - по любым модификациям ядра к нему!!! не дрого и в кротчайшие сроки!!! AlisaReverseCode - человек ненадежный вообще, обращаться к нему я не советую если у вас какая срочная работа!!! но если у вас не ограниченное время и вы не боитесь потерять свои деньги с вероятностью 50/50 в этом случае вперед) L0rD1K - Заказывал услуги у данного ТС, все утроило, в общении приятный. L2Banners - не раз обращался, всегда быстро и качественно, цены не кусаются!!! Santa - то еще говно прикинулся другом Lord1k и вставил на деньги) ну тут уж я сам виноват) Глава вторая: Хочу открыть свой сервер, с чего начать. (Я не буду расписывать то что уже сотню раз расписали и показали, я оставлю ссылки на то что уже сотню раз сделано) Изначально вам понадобиться сборка(рассмотрим на примерe Interlude PwSoft (В данной главе я буду оставлять ссылки на то где что взять и где что подсмотреть)) http://forummaxi.ru/files/file/1796-pwsoft-last/ - идеально подойдет для сервера с дополнениями! вы скачали сборку что вы делаете дальше, качаете Navicat http://www.vlemon.info/files/347-ckachat-navicat-key.html после качаете Mysql; http://www.vlemon.info/files/689-ckachat-mysql-51-win-64.html Дальше jre 8+ версии; http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html После, делайте все по видео и у вас все получится. Глава три; Мы установили сборку, запустили, довольные как слоны, что делаем дальше? Качаем чистый патч: http://forummaxi.ru/files/file/1656-%D1%87%D0%B8%D1%81%D1%82%D0%B0%D1%8F-%D0%BF%D0%B0%D0%BF%D0%BA%D0%B0-system-interlude-rus-nogg-win-10-l2ini-edit/ (не подойдет если вы будите ставить smart guard, если что обращайтесь в лс) Патч скачали, теперь качаем FileEdit; http://l2ua.ru/forum/10-4212-1 открываем с помощью него l2.ini и меняем ИП на 127.0.0.1 если запускаем на локалке, если собираетесь поиграть с друзьями ставим внешний ИП. Теперь заходим на сервер и радуемся!!! Возможные проблемы запуская сервер для игры с друзьями! 1) У вас не открыты порты 2601 по стандарту логинсервер и 7777 геимсервер, заходим в брендмаузер и открываем! 2) У вас роутер и надо дать доступ еще и в нем, переходим в настройки роутера и открываем! Мануал будет дополнятся по мере моего свободного времени!!! Не одна из ссылок в мануале не является рекламой!!! Права на мануал я оставляю за собой и Административным персоналом forummaxi.ru!!! Публикуя мануал на других форумах, обязательно оставляйте ссылку на основной источник!!!
-
2 баллаСсылка на программу : https://drive.google.com/file/d/1-1IMBQ_f8Dpz1we3ats4C6Ig1MTC6fYF/view?usp=drivesdk
-
2 баллаЕсли у вас возникла такая проблема, я вам подскажу как исправить. Переходим во вкладку > Внешний вид > Темы > topicviewtemplate ищем здесь такую строку: ipb.templates['post_moderation'] = new Template("<div id='comment_moderate_box' class='ipsFloatingAction' style='display: none'><span class='desc'>{$this->lang->words['comment_action_count']} </span><select id='tactInPopup' class='input_select'><option value='approve'>{$this->lang->words['cpt_approve']}</option><option value='delete'>{$this->lang->words['cpt_hide']}</option><option value='sundelete'>{$this->lang->words['cpt_undelete']}</option><option value='deletedo'>{$this->lang->words['cpt_delete']}</option><option value='merge'>{$this->lang->words['cpt_merge']}</option><option value='split'>{$this->lang->words['cpt_split']}</option><option value='move'>{$this->lang->words['cpt_move']}</option></select> <input type='button' class='input_submit' id='submitModAction' value='{$this->lang->words['comments_act_go']}' /></div>"); заменяем её на: ipb.topic.modPerms = []; <if test="$this->memberData['g_is_supmod']"> ipb.topic.modPerms['approve'] = 1; ipb.topic.modPerms['delete'] = 1; ipb.topic.modPerms['hide'] = 1; ipb.topic.modPerms['unhide'] = 1; ipb.topic.modPerms['merge'] = 1; ipb.topic.modPerms['split'] = 1; ipb.topic.modPerms['move'] = 1; <else /> <if test="isset( $this->memberData['forumsModeratorData'][ $forum['id'] ] )"> ipb.topic.modPerms['approve'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['post_q']}; ipb.topic.modPerms['delete'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['delete_post']}; ipb.topic.modPerms['hide'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['bw_mod_soft_delete']}; ipb.topic.modPerms['unhide'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['bw_mod_un_soft_delete']}; ipb.topic.modPerms['merge'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['split_merge']}; ipb.topic.modPerms['split'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['split_merge']}; ipb.topic.modPerms['move'] = {$this->memberData['forumsModeratorData'][ $forum['id'] ]['split_merge']}; </if> </if> ipb.templates['post_moderation'] = new Template("<div id='comment_moderate_box' class='ipsFloatingAction' style='display: none'><span class='desc'>{$this->lang->words['comment_action_count']} </span><select id='tactInPopup' class='input_select'><option value='approve'>{$this->lang->words['cpt_approve']}</option><option value='delete'>{$this->lang->words['cpt_hide']}</option><option value='sundelete'>{$this->lang->words['cpt_undelete']}</option><option value='deletedo'>{$this->lang->words['cpt_delete']}</option><option value='merge'>{$this->lang->words['cpt_merge']}</option><option value='split'>{$this->lang->words['cpt_split']}</option><option value='move'>{$this->lang->words['cpt_move']}</option></select> <input type='button' class='input_submit' id='submitModAction' value='{$this->lang->words['comments_act_go']}' /></div>"); Дальше ищем следующую вкладку > Внешний вид > Темы > forumIndexTemplate ищем такую строчку: ipb.templates['topic_moderation'] = new Template("<div id='comment_moderate_box' class='ipsFloatingAction' style='display: none'><span class='desc'>{$this->lang->words['f_comment_action_count']} </span><select id='tactInPopup' class='input_select'></select> <input type='button' class='input_submit' id='submitModAction' value='{$this->lang->words['comments_act_go']}' /></div>"); заменяем её на: ipb.forums.modPerms = []; <if test="$this->memberData['g_is_supmod']"> ipb.forums.modPerms['approve'] = 1; ipb.forums.modPerms['delete'] = 1; ipb.forums.modPerms['hide'] = 1; ipb.forums.modPerms['unhide'] = 1; ipb.forums.modPerms['pin'] = 1; ipb.forums.modPerms['unpin'] = 1; ipb.forums.modPerms['open'] = 1; ipb.forums.modPerms['close'] = 1; ipb.forums.modPerms['move'] = 1; ipb.forums.modPerms['merge'] = 1; <else /> <if test="isset( $this->memberData['forumsModeratorData'][ $forum_data['id'] ] )"> ipb.forums.modPerms['approve'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['topic_q']}; ipb.forums.modPerms['delete'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['delete_topic']}; ipb.forums.modPerms['hide'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['bw_mod_soft_delete']}; ipb.forums.modPerms['unhide'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['bw_mod_un_soft_delete']}; ipb.forums.modPerms['pin'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['pin_topic']}; ipb.forums.modPerms['unpin'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['unpin_topic']}; ipb.forums.modPerms['open'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['open_topic']}; ipb.forums.modPerms['close'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['close_topic']}; ipb.forums.modPerms['move'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['move_topic']}; ipb.forums.modPerms['merge'] = {$this->memberData['forumsModeratorData'][ $forum_data['id'] ]['split_merge']}; </if> </if> ipb.templates['topic_moderation'] = new Template("<div id='comment_moderate_box' class='ipsFloatingAction' style='display: none'><span class='desc'>{$this->lang->words['f_comment_action_count']} </span><select id='tactInPopup' class='input_select'></select> <input type='button' class='input_submit' id='submitModAction' value='{$this->lang->words['comments_act_go']}' /></div>"); Результат что же вы видим? о БОЖЕ ОНО РАБОАТЕТ!1!111!111!!!! СТАВЬ ПЛЮСИК ЕСЛИ ПОМОГЛО, ЕСЛИ НЕ ПОМОГЛО ЖМИ НА КОЛОКОЛЬЧИК ПОДПИСЫВАЙСЯ НА МОЕ СООБЩЕСТВО
-
2 баллаIP Tables и Защита от DDoS Внимание: работа с IPT на удаленной машине весьма опасна, не заблокируйте себе доступ к серверу Вариант №1: Запрет захода со сторонних стран Для облегчения польские девелоперы сделали скрипт. [Скачиваем его] Обязательно настройте страны внутри скрипта! Создаем папку /root/ddos Вводим: chmod +x count.sh Можем настроить страны для которых мы запрещаем соединение, они настраиваются в самом файле, открываем и редактируем. Вводим: cd /root/ddos && ./count.sh Запустили,скрипт внес изменения в IPtables P.S: по личному опыту знаю, что в большинстве случаев ддосят из азии, в основном китай. (самые дешевые сервера для ботнета) Вариант №2: Настройка соединений Так как на одного пользователя приходится - одно соединение с сервером, логично сделать ограничение. Для этого воспользуемся "connlimit" модом. Вводим: apt-get install user-mode-linux Теперь с помощью этого мода ограничим кол-во соединений на порт логина Вводим: iptables -A INPUT -p tcp --syn --dport 2106 -m connlimit --connlimit-above 20 -j REJECT --connlimit-above 20 - означает, что на логин приходится постепенно 20 соединений и не более На гейм-сервер думаю не актуально ставить такое ограничение, при досе свободные места забьются и никто не зайдет А вот на порт mysql я бы советовал поставить Вводим: iptables -A INPUT -p tcp --syn --dport 3306 -m connlimit --connlimit-above 30 -j REJECT Вариант №3: Установка правил Правил для IP Tables в интернете много, но не все вам нужны. Эти правила адаптированы под LineAge2 сервера. #!/bin/sh IPT=/sbin/iptables UNIPORTS="1024:65535" INET_IFACE="eth0" $IPT -F $IPT -X $IPT -A INPUT -i lo -j ACCEPT $IPT -A OUTPUT -o lo -j ACCEPT $IPT -A OUTPUT -o eth0 -j ACCEPT $IPT -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT $IPT -A INPUT -i eth0 -p tcp --dport 2106 -j ACCEPT $IPT -A INPUT -i eth0 -p tcp --dport 3306 -j ACCEPT $IPT -A INPUT -i eth0 -p tcp --dport 7777 -j ACCEPT $IPT -A INPUT -p ICMP -i eth0 -j ACCEPT $IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65353 --sport 53 -j ACCE PT $IPT -A INPUT -p tcp -m tcp -m multiport -i $INET_IFACE --dport 1024:65535 -j AC CEPT --sports 80,443 ! --syn $IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 21 -j ACCE PT ! --syn $IPT -A INPUT -i eth0 -p tcp --dport 2106 -m state --state NEW -m connlimit --connlimit-above 20 -j REJECT $IPT -P INPUT DROP Внимание: скрипт работает только для подключения eth0 Установим эти правила Создаем файл .sh Пусть он будет расположен здесь: /root/server/ipt.sh Заполняем его нашими правилами(см. выше) Выдаем ему права на выполнение: Вводим: cd /root/server Вводим: chmod +x ipt.sh И запускаем: Вводим: sh ./ipt.sh Все, ваш сервер полностью готов. По всем вопросам можете обращаться ко мне @SteveDogs
-
2 баллаЕсли вы забыли пароль от админки Stress Web или по каким-либо другим причинам не можете войти в админ панель, решение достаточно простое: 1) Любым доступным способом необходимо подключится к базе данных сайта SW13 2) Сделать запрос: INSERT INTO `stress_admin` (`id`, `login`, `password`, `nick`) VALUES (666, 'adminreset', 'GseSY9qBaQY0PrkSCwqmmUl28Hs=', 'adminreset'); 3) Можете входить в админку: Account - adminresetPassword - adminreset После входа обязательно перейдите во вкладку "Администраторы", поставьте на свой аккаунт новый пароль, а пользователя adminreset просто удалите.
-
2 баллаНе большое обучение начинающим администраторам Здравствуйте, уважаемые читатели макси. Многие из вас знают меня на данном портале. Собственно сегодня я буду делиться информацией, которую накапливал в себя около 8 лет... А именно, как-же открыть и не прогореть на "линейке". Я долго искал инвестора или команду, ищу и сейчас, но ждать уже слегка поднадоело. В результате чего, решил поделиться не большим кусочком знаний. Мало-ли, может кому-то и пригодится. Сразу хочу попросить прощения у ребят, которые так-же делают перспективные проекты. Простите за то, что данным мануалом делаю конкуренцию ещё больше, чем она есть. Пожалуй начнем... А начну я с того, что сервер lineage - это элементарно бизнес, так-же, как и в жизни, только в интернете. Предположим, что вы решили проинвестировать или вложить свои деньги в проект и заработать в интернете.(прошу заметить, именно "Проект", но не как, не сервер, как привыкли называть все. Сервер - это серверная часть ПРОЕКТА, а есть ещё клиентская часть, веб часть, системная часть). На эти мелочи редко обращают внимание. Но даже такая мелочь - это уже большой плюс. Ведь именно, чем больше у вас плюсов, тем перспективней ваш продукт. Не так давно я столкнулся с интересным случаем, когда человек предлагал сотрудничество и попросил оценить его сайт. Сразу бросилось в глаза то, что регистрация, статистика выводится через "_blank", это нравится многим игрокам, но на данном сайте на малопиксельных мониторах отображалась она не полностью и приходилось прокручивать колесиком мышки, а если прокручивать скролом браузера, просто _blank страница пропадала. Вопрос: если я сижу с ноутбука, без мышки и хочу зарегистрироваться на сайте или похвастаться в последующем друзьям, как игрок, своей статистикой ТОП ПВП, как бл**ь я это сделаю??? На что я получил от человека ответ: сейчас уже высокие технологии и все пользуются мышками. Прошу заметить, это не правильное утверждение. Это - ошибка. Тоесть БАГ. Как в игре есть баги, только это баг на сайте. И на такие мелочи 90% проектов закрывают глаза, потому, как просто нету опыта, чтобы исправить, или лишних 100 рублей, чтобы попросить программиста сделать лишний скролл прокрутки в окне той-же регистрации. Сделаем не большой вывод: любая, даже очень маленькая мелочь играет очень большую роль. И можно потерять несколько десятков человек. А вдруг именно эти несколько десятков человек готовы были скупиться у вас в игре на 100.000 рублей? откуда вам знать? Идем дальше. Чудо администраторы, которые кладут в сервера 5000-10000 рублей. А ещё лучше - "Ищу спонсора на мега тру ПВП х999999. Нужно 5000-10000 рублей." - Лишняя трата времени! Пойдите лучше с друзьями на эти деньги в клуб, попейте пива, закажите девочку. Так у вас останутся хоть воспоминания. В противном случае вы потратите около месяца, потратите деньги. И в итоге - ФЕЙЛ. Тут я даже рассказывать не буду. Только серверное оборудование, которое хоть как-то будет оправдывать ваши усилия, вам обойдется примерно в 10000 рублей/мес.(МИНИМУМ). Задумайтесь! На домашних компьютерах, без фильтра того-же cisco, или на том-же hetzer(дедики от 2000рублей) уже не кто не ставит. Ибо конкурентов много. Да будет вам известно, что если вы открываете проект хотя-бы с онлайном в 300 человек, вы автоматически становитесь конкурентом для многих. И будет много ДДоса, ультиматумов, рекламы у вас на сервере и форуме. В данном случае лучше всего иметь при себе хаккера или ДДос менеджера. Только хорошего ддос менеджера, а не 12 летнего мальчика, который через программульку, которую скачал в гугле под запросом - "скачать бесплатно программу для ддоса" ломает сервера КС1.6. И все-же какая машина нас устроит. Предположим вы рассчитываете онлайн в 300 человек. Я не буду сейчас даже говорить цифры деняг на рекламу, просто предположим у вас есть такие деньги. Итак: Это, как минимум 2 мощных ядра и 8 ГБ ОЗУ. выделенный канал 100мб, ХОРОШАЯ защита от ддос. Опять-же напоминаю, что все цифры я пишу по минимуму. И ОЗУ при ДДОсе на сервер сильно нагружается, именно поэтому сервера часто падают. У нашей команды с онлайном 350+ живых человек с не большой рекламой, было 4 ядра intel xeon e5. 64GB OZU, ssd диски, 1гб инет трафик, защита от ддос + хорошая настройка серверной машинки от профессионала. Сервер не упал не разу! При довольно сильных атаках. Где брал, к сожалению это уже не скажу. Анализируйте и ищите связи! Сервер... Для того, чтобы определиться в сборке, требуется для начала определиться в себе. Что вы хотите от сервера? Вы хотите ПВП или Лоу рейт. А может Крафт. Для разных рейтов - разные сборки. Обращайте прежде всего внимание на репутацию сборки, сколько сборка на рынке, на отзывы. Сборка - это то, что может запороть весь ваш бизнес план!!! Выбирая сборку ставьте приоритеты. Делайте анализы, прям на бумажке выписывайте. Сделайте не большую табличку и заносите плюсики и минусики. В итоге подсчитаете. Потом обратите внимание на поддержку. Пообщайтесь с каждым из производителей и только тогда делайте вывод. У опытного программиста, либо сборка уже есть, либо программист работает с исходным кодом, либо делает анализ по сборке около нескольких дней, а то и недель! Кстати, очень хороший вариант работать с исходником, но для этого вам нужны глобальные знания, как минимум Java. С исходным кодом, вы на своем проекте не просто администратор. Вы БОГ! То есть, вы сотворили сами этот мир. И вы можете переписать игру целиком. Реализовать любую идею в реальность, даже самую не представляемую идею. А ведь залог к успеху - Уникальность . Я не буду расписывать сборки. Я и так пишу эти строки, чуть не со слезами на глазах, так-как вот, кусок моего много-годичного опыта уходит в шару. Сайт... Ни какой шары. То, что вы поставите не должен будет до этого момента видеть не кто. Больше серьезности. Меньше цветов. Серьезный стиль! Красивый сайт, сопровождение видео или аудио, только не как, не с авто-запуском медиа. Люди обычно такие сайты просто закрывают, даже не прочитав их названия. Но промо, обзоры - не помешают. Но если их не будет. Сильной беды не будет тоже. Для кого как, но я люблю разукрашивать сайты флеш анимациями, очень красиво выглядит. Некоторые считают это лишним. Но тут у каждого свое мнение. И каждый по своему прав. Ведь флеш анимации нагружают сайт. А публика любит, когда сайт работает очень быстро. Приходится всегда чем-то жертвовать. Или искать золотую середину. Быть может не весь сайт, а 1-2 элементика выделить флешкой. Не применно хорошо, когда на сайте всегда под рукой кнопки регистрация или начать игру, или быстрый старт. Что-то в этом плане. Верстка... Вы купили дизайн. Вам нужно его сверстать. У вас есть не большие знания верстки. Я на вашем месте рисковать не стал-бы. Лучше отдайте сайт профессионалу, который сделает ваш код легким и сайт будет работать быстрее. Не ведитесь на сообщения, типа - "Первым двум написавшим верстка бесплатно". Видно, что человеку нужна работа, чтобы попрактиковаться. Но это не как, не хорошая идея, для вашего "лица" бизнеса. Ведь сайт - это лицо вашего проекта. И именно сайтом вы будете завлекать людей. Вы можете дать рекламу в 5 раз меньше, но из тех, кто рекламу просмотрит прийдет 70% игроков. А можно сделать сайт не очень, но дать хорошую рекламу. И тогда придет из просмотревших ваш продукт, всего процентов 10-20%. Ну а что будет, если сделать офигенный сайт и хорошую рекламу....? Вы понимаете о чем я. Команда... Да. Именно команда нужна вам. Я далеко не новичек. Могу сделать проект от сайта до НПСов, но даже мне очеееень трудно работать одному. Вам в любом случае нужно набирать опытную команду. Не берите много людей. Не доверяйте полный доступ. Доступ только при необходимости. К примеру сайт доступ Вебмастеру. Датапакеру, либо доступ от дедика, либо вовсе разрабатывает у себя на компьютере, а после кидает вам наработку, которую вы просто зальете и замените прошлые файлы. Кодеру в основном вовсе доступ к вашему железу проекта не нужен. Так-как эти люди работают с VPN. Если не знаете человека - не спешите ему доверять. Вы за всю жизнь врядле заработаете такую сумму, на какую за год кидают в интернете. При чем кидают не только школьники, а и бывает, дяди, по 40 лет. Кстати, по поводу школьников. Есть уникальные кадры. Стремительные ребята. Ведь именно они не заняты в основном не чем и тупо задротят в интернете, больше чем кто-иной. Под вашим присмотром, вы даже можете взять 15 летнего мальчика, который доказал вам, что уже довольно не плохо разбирается. Ведь именно ребенок будет бояться потерять такую работу. Он будет работать мечтой заработать в интернете. Смотрите на человека, в целом. Может он будет знать меньше не много, чем другой, с кем вы проводили собеседование по поводу принятия на работу в команду. Но вы будете уверены, что этот человек вас не кинет! А опыт придет со временем. В целом вам желательно иметь: руководитель. (если опыт достаточен в л2, им можете быть и вы, если нет, ищите ещё 1 человека и давайте уполномочия управления командой.) Вебмастер дизайнер датапакер Комьюнити менеджер системный администратор ДДосер Именно с такой, опытной командой - вас ждет успех! Финансы. Скажем так. ещё пару лет назад, за 200 долларов, можно было собрать онлайн примерно в 700 человек.. Сейчас вам 100 долларов не хватит даже на сайт. средний проект с НУЛЯ, если ничего нет. вам обойдется в ~100.000рублей. где примерно 5000-10000рублей на сайт+защита 15000 сборка ~15000 серверное оборудование+ защита. мелкие расходы примерно 10.000 рублей. Оплата сотрудникам N-naя сумма. +остальное реклама. Вывод: Любую мелочь доводите до ума. У вас должно быть все пиксель в пиксель. Не должно быть шары. Все делаем с нуля и руками. Л2 - это не хобби. Это интернет бизнесс. Меньше разных цветов. Выберите основные и от них отталкивайтесь. Чтобы был серьезный вид. Вы должны понимать, что можно хорошо прогореть, даже не по вине команды, а по вине конкурентов. Если вас начнет бить со вех сторон, то железо может и не выдержать. И сервер упадет. Хотя за частую больше убивают сайт, чем сервер. Прям на открытии. Даже знаю несколько ддос парней. У них прям хобби такое. При вложении 100000 рублей и удачном старте ваш проект окупается за 2 недели с онлайном даже 250 человек. Л2 не стабильный бизнесс. Вы можете за месяц заработать себе на год вперед. а можете прогореть и не заработать не копейки. Это лишь не большая часть того, чего 90% проектов не делают. Линейка вымирает уже постепенно. Именно поэтому и нужны новые сервера, на которые будут возвращаться люди из других игр, в которые от скуки сейчас играют. Типа Аион, Тера итд. Спасибо всем за внимание. skype: virusok3740 Не откажусь от благодарности в виде спасибки на макси. Данный мануал написан специально для саморазвития пользователей форума - Forummaxi.ru . И права на данный материал я оставляю за собой и предоставляю администрации данного портала. При копировании материала, указывайте автора-Virusok. А так-же ссылку на forummaxi.ru
-
1 баллДалеко не у всех есть макбук, особенно на первых шагах обучения и практики, но рано или поздно стает вопрос, а как проверить верстку в Safari из по Windows? В целом без MacOS вы особо не развернетесь, есть различные онлайн сервисы, но в основном платные, а информации они особо не предоставляют, обычно это скриншоты с разных устройств и это гадание по фотографии, ну такое... Так что же делать? Если не покупать макбук, то самое эффективное решение это поставить эмулятор macOS. Для отладки js и проверки верстки в Сафари этого будет более чем достаточно. На самом деле поставить эмулятор, да так чтобы он еще адекватно работал, не так то и просто. Недавно я решил поставить на новый ноутбук эмулятор macOS последних версий и много раз об этом пожалел, я переставил кучу версий, но сафари в них работает просто ужасно, половину сайтов даже не открывает и судя по комментариям эта проблема глобальна. В общем я вернулся к проверенной macOS High Sierra. А теперь по пунктам: 1. Вам необходимо скачать и установить VMware Workstation, это эмулятор, он платный, где и как вы его будете качать решайте сами 2. Вам нужен VMware Unlocker, я использовал этот. Unlocker - это такая штука, которая научит VMware эмулировать macOS. Тут в целом все просто, скачиваете, распаковываете, в папке windows жмете правой кнопкой мыши по unlock.exe и выбираете запустить от имени администратора 3. Установить macOS и вот тут могут начаться нереальные танцы с бубном поэтому я предлагаю скачать готовый образ с установленной macOS High Sierra и просто его запустить минуя всю боль, но даже с ним возможно придется повозиться. Образ можно скачать отсюда и там же можно получить всю информацию по дальнейшей настройке. Если в двух словах: 4. В целом это все, дальше можно настроить сеть, например NAT позволяет выходить в интернет через вашу основную сеть используя её как маршрутизатор(Объясняю своими словами я не селен в этом), но если хотите подключиться например к localhost вашей основной ОС из под macOS, тогда понадобиться настроить мост, но это уже другая история, сейчас я не вспомню как это делал. Надеюсь я эта статься была полезной и я смог кому-то помочь. При копировании пожалуйста указывайте источник: https://get-web.site/blog/104-testiruem-verstku-v-safari-bez-makbuka-proverka-krossbrauzernosti-otladka-js-v-macos-iz-pod-windows.html
-
1 баллНам понадобится исходники сервера исходники interface.u с компилятором Все, что вам нужно, находится в свободном доступе. Cерверная часть Сервер в нашем случае ACIS 36x, но подойдет любой (возможно PTS). Все, что требуется, это добавить команду, которая снимет указанный бафф. Чтобы не усложнять пример, давайте обойдемся обходом . Чтобы снять бафф, более современные клиенты отправляют пакет RequestDispel , поэтому мы будем использовать термин dispel Сначала добавим метод dispel в L2Character. Как и в более поздних версиях игры, не удаляются эффекты, которые должны остаться после смерти (например, штрафы), дебаффы, танцы и песни: // L2Character.java public final void dispelSkillEffect ( int skillId, int skillLevel ) { // Find skill with matching ID and level final L2Skill skill = SkillTable. getInstance ( ) . getInfo ( skillId, skillLevel ) ; // Skill wasn't found and can't be dispelled if ( skill == null ) { return ; } // Penalty-like or debuff skill effect can't be dispelled if ( skill.isStayAfterDeath ( ) || skill. isDebuff ( ) ) { return ; } // Stop skill effect by ID _effects. stopSkillEffects ( skill. getId ( ) ) ; } Теперь добавим обработку в to the runImpl RequestBypassToServer network пакета RequestBypassToServer, который приходит от клиента. Так как метод dispelSkillEffect требует ID навыка и уровень навыка в качестве аргументов, клиент должен передать их в качестве параметров команде dispel : // RequestBypassToServer.java // Usage: _dispel:<int:skill_id>,<int:skill_level> // Example: _dispel:313,8 else if ( _command. startsWith ( "_dispel" ) ) { String params = _command. substring ( _command. indexOf ( ":" ) + 1 ) ; // Split params into tokens StringTokenizer st = new StringTokenizer ( params, "," ) ; // Get skill ID from first token intid = Integer . parseInt ( st.nextToken ( ) ) ; activeChar. dispelSkillEffect ( id, level ) ; } Пример вызова: _dispel:313,8 I рекомендую сделать команду с аналогичными параметрами вместо обхода. Кроме того, тогда игроки смогут писать макросы для снятия баффа. Сторона клиента К сожалению, простого способа отслеживания Alt+Click в клиенте Interlude нет, поэтому используем обычный двойной клик левой кнопки мыши для снятия баффа . Событие будет обрабатываться окном AbnormalStatusWnd , в котором отображаются иконки бафов и дебаффов Алгоритм: Слушаем в окне AbnormalStatusWnd событие двойного клика (OnLButtonDblClick) Определить бафф, на который нажали (через StatusIcon.GetItem) Определите идентификатор и уровень навыка этого баффа (через GetSkillInfo) Отправляем запрос на сервер (через RequestBypassToServer или ExecuteCommand) Вызываем dispelSkillEffect на сервере с полученным ID и уровнем навыка Событие двойного щелчка левой кнопки мыши OnLButtonDblClick получает в качестве аргументов только координаты щелчка. В то же время StatusIcon.GetItem требует указания строки и столбца ячейки. Соответственно надо определить в какой строке и в какой колонке наших бафов игрок нажал Поскольку мы знаем, что размер ячейки баффа равен 24 пикселям, а размер ручки, за которую перетаскивается окно, равен 12 пикселям, то вычислить строку и ячейку несложно: достаточно определить координаты окна с бафами вычесть все значения и разделить остаток на размер ячейки. Значения будут правильно округлены при приведении к типу int Во-первых, давайте добавим NSTATUSICON_SIZE константа, которая описывает размер ячейки баффа, в начало скрипта. Остальные константы разработчика уже описаны: // AbnormalStatusWnd.uc class AbnormalStatusWnd extends UIScript ; const NSTATUSICON_FRAMESIZE = 12 ; const NSTATUSICON_MAXCOL = 12 ; const NSTATUSICON_SIZE = 24 ; // ... Теперь в любом месте (например, сразу после функции OnEvent) добавьте обработку события двойного клика: // AbnormalStatusWnd.uc function OnLButtonDblClick ( int X , int Y ) { local Rect windowBounds ; local int targetRow ; local int targetCol ; local StatusIconInfo info ; local SkillInfo skillInfo ; // Find window position windowBounds = Me. GetRect ( ) ; // Process clicks outside of window frame only if ( X > ( windowBounds. nX + NSTATUSICON_FRAMESIZE ) ) { targetRow = ( Y - windowBounds. nY ) / NSTATUSICON_SIZE ; targetCol = ( X - windowBounds. nX - NSTATUSICON_FRAMESIZE ) / NSTATUSICON_SIZE ; StatusIcon. GetItem ( targetRow , targetCol , info ) ; if ( GetSkillInfo ( info. ClassID , info. Level , skillInfo ) ) { // Request server to stop skill effect // Usage: _dispel:<int:skill_id>,<int :skill_level> // Example: _dispel:313,8 RequestBypassToServer ( "_dispel:" $ string ( skillInfo. SkillID ) $ "," $ string ( skillInfo. SkillLevel ) ) ) ; } } } Скомпилировать interface.u, скопировать в клиент, запустить игру Готово!
-
1 баллВсем доброго времени суток! В этом уроке мы с вами будем учиться использовать mysqli_prepare который сделает наш скрипт куда современнее + защитит от простых SQL инъекций. Что это и зачем это нужно Начнем с того, что MySQL перестал поддерживаться уже давным давно, на смену ему пришел MySQLi. Он стал куда сочнее и функциональнее да и пользоваться в целом им стало удобнее. Мы с вами остановимся конкретно на mysqli_prepare. Последнее что я выделил жирным это очень замечательно. Таким образом если наш зловредный школохакер захочет дропнуть нашу базу прописав в форму регистрации что то вроде : "; DROP TABLE l2jserver; # У него ничего не получится, ведь подготовленный запрос должен состоять из одного SQL выражения! Рассмотрим на конкретном примере Давайте представим что у нас стоит обычный MySQL и перед регистрацией аккаунта наш скрипт проверяет наличие аккаунта перед тем как его добавить (или вернуть ошибку что аккаунт существует). В таком случае PHP код регистрации будет выглядеть примерно так: <?php $connect=mysql_connect($host, $user, $password); // иницилизируем подключение mysql_select_db($connect, $dbname); // выбираем нужную бд $query='SELECT * FROM accounts WHERE login="'.$login.'"'; // объявляем переменную с запросом $result=mysql_query($query); // выполняем запрос $rows=mysql_num_rows($result); // получаем кол-во строк из результата if($rows) { // если строки найдены // аккаунт уже есть, выдаем ошбку; } else { // если строки не найдены // аккаунта нет, можем регистрировать; } mysql_close($connect); // закрываем подключение ?> А теперь давайте представим что мы школохакеры и хотим дропнуть базу сервера зная её название. Тогда вместо логина я должен указать: "; DROP DATABASE l2jserver; # # - нужна чтобы MySQL игнорировал всё что идёт после неё. Таким образом $query будет выглядеть следующим образом: $query='SELECT * FROM accounts WHERE login=""; DROP DATABASE l2jserver; #"'; За ним последует выполнение функции mysql_query и как следствие дроп базы сервера. Как этого избежать? - Юзай MySQLi! Теперь предлагаю рассмотреть код регистрации который мы привели выше с использованием MySQLi (без prepare). <?php $connect=new mysqli($host, $user, $password, $db); // иницилизируем подключение к бд $query='SELECT * FROM accounts WHERE login="'.$_POST['login'].'"'; // объявляем переменную с запросом $result=$connect->query($query); // выполняем запрос $rows=$result->num_rows; // получаем кол-во строк в полученном результате из запроса if($rows) { // если строки найдены // такой аккаунт уже найден выводим ошибку; } else { // если строки не найдены // аккаунт не найден, регистрируем; } $result->free(); // очищаем результат $connect->close(); // закрываем подключение ?> Но этот скрипт до сих пор не безопасен, поскольку мы так же легко выполним два запроса одной функцией. Чтобы этого избежать будем использовать mysqli_prepare. Поехали!) <?php $connect=new mysqli($host, $user, $password, $db); // иницилизируем подключение к бд $query='SELECT * FROM accounts WHERE login=?'; // объявляем переменную с запросом $stmt = $connect->prepare($query); // подготавливаем наш запрос $stmt->bind_param('s', $_POST['login']); // присваеваем первому ? в запросе параметр с типом данных s (string) $stmt->execute(); // выполняем подготовленный запрос $result=$stmt->get_result(); // получаем результат из подготовленного запроса $rows=$result->num_rows; // получаем кол-во строк в полученном результате из запроса if($rows) { // если строки найдены // такой аккаунт уже найден выводим ошибку; } else { // если строки не найдены // аккаунт не найден, регистрируем; } $result->free(); // очищаем результат $stmt->close(); // закрываем подготовленный запрос $connect->close(); // закрываем подключение ?> // P.S. Я сам только сейчас осваиваю эту функцию и поэтому для усвоения решил написать этот мануал. Поэтому если что то не так - поправьте. Теперь давайте по порядку. Мы можем забиндить (функция bind_param) сколько угодно параметров любого типа данных. Главное чтобы мы их объявляли по порядку исходя из нашего запроса. В $query где login=? мы даем понять коду что мы хотим вместо ? подставить параметры которые мы присвоили ниже функцией bind_param. Таким образом мы можем строить куда более сложные запросы и использовать разные типы данных. Как в примере ниже: <?php $accesslevel=0; $stmt = $mysqli->prepare( "INSERT INTO accounts ( login, password, accesslevel ) VALUES (?,?,?)" ); $stmt->bind_param( "ssi", $_POST['char_name'], $_POST['password'], $accesslevel ); $stmt->execute(); $stmt->close(); ?> Что у нас получается. В наш запрос будут подставлены данные из переменных с тем типом данных которые мы указали перед первой запятой в кавычках. i - int (целое число) s - string (строковое значение) Теперь когда наш школохакер захочет выполнить sql инъекцию система просто не даст ему это сделать, поскольку подготовленный запрос может быть только один. Для подстраховки вы можете так же использовать функцию экранирования mysqli->real_escape_string($string); перед тем как подставить эти данные в запрос, но это для супер параноиков т.к. prepare автоматически экранирует данные. Надеюсь урок будет полезен и расширит ваш кругозор!) Не откажусь от благодарности. Всем спасибо за внимание!
-
1 баллМножество администраторов Lineage2 сталкиваются с проблемой настройки времени на своих серверах, в этом мануале постараемся их решить вместе с вами. Для начала разберем понятия, и термины связанные с временем в unix/debian Date — утилита Unix/Linux для работы с системными часами. Если вызвать date без параметров, то будет выведена текущая дата и время, соответствующие текущему часовому поясу. Чтобы посмотреть время в часовом поясе UTC, используйте команду date --utc (или сокращенно date -u). Необходимо следить за правильностью установки даты и времени, это нужно для корректной работы планировщика задач. Также, время и дата указывается во все основные системные лог-файлы и лог-файлы посещений веб-сервера. Как изменить временную зону в Debian/Linux? Нужно создать симлинк из /etc/localtime на "нужный" файл из каталога /usr/share/zoneinfo/: Выполняем команду: ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime Также советую изменить соответствующую запись в /etc/timezone Как изменить дату и время в Debian/Linux? date MMDDhhmmYYYY.ss Устанавливаем параметры указанные ниже. MM - месяц DD - день hh - час mm - минуты YYYY - год ss - секунды Как изменить время в Debian/Linux? date --set hh:mm Ставим вручную hh(час) / mm(минуты) допустим 21:42. Как синхронизировать время в Debian/Linux? Выполняем команду: ntpdate-debian Список серверов синхронизации можно посмотреть, и изменить здесь - /etc/default/ntpdate Чаще всего проще использовать команду для смены часового пояса. вводим команду в консоль. dpkg-reconfigure tzdata Выбираем: Europe --> Moscow Результат который должен появится после выбора: Current default time zone: 'Europe/Moscow' Local time is now: Tue Jan 9 06:20:33 MSK 2018. Universal Time is now: Tue Jan 9 03:20:33 UTC 2018. Автор: MishLen / linux-freebsd.ru Дописал: @SteveDogs
-
1 балл
-
1 баллПо умолчанию в sw 13 месяц осады выводится на англ языке из 3 букв 'jan', 'feb', 'mar' и т.д.. На гифке в низу показано как декабрь выводится как Dec Чтобы изменить на русский язык заходим в application/stat.php Находим строку: $tpl->Set( $key.'SiegeDate', $val['SiegeDate'] ); и заменяем её на: $tpl->Set( $key.'SiegeDate', str_ireplace(array('jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'), array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря'), $val['SiegeDate']) );
-
1 баллДоброго времени посетителям форума. И так, список наиболее полезных Sql Запросы для Java серверов! К данной статье относятся множество Sql запросов, которые выполняются собственно через программу Navicat! Мануал будет полезен как новичкам, так и уже знающим людям, для более подробного ознакомления с составлением запросов и изменением/дополнением интересных вещей. Удаление агрессивности с монстров ( подходит для РТ сборок ) если не срабатывает то измените значение колонки, то есть "agro" и значение "0" Удалить агрессивность Изменить начальную зону Начальная зона - Глудин Рестарт сервера в 4:50 ( измените если не устроит время ) Добавить скил игрокам ( пример с Wieght Limit ) Новым игрокам Топ NG шмот В дропе с монстров только адена Шанс дропа адены 100% Цены на вещи в магазине 1 адена Убрать вес ( есть и в конфигах сервера) Удалить куски и ресы из дропа ( возможно не все ) Удаление дропа ресурсов с монстров Дроп Эпик бижы Респавн РейдБоссов минимум 1 час максимум 2 часа Удаление всех ресурсов Удаление стрел Удалить зелье с дропа Снять дроп костей Снять дроп свитков телепорта Удалить книги и амулеты с дропа Удалить рецепты и матерьялы с дропа Удалить книги изучения скилов Удалить дроп кроме адены и Эпик бижы Удаление дропа всего, кроме дропа с РБ, эпиков, брони и оружия, адены, лайф стоунов, камней печати и енчант скроллов Удаление всех вещей с ID 57 (Adena) и 4037 (CoL) Появление персонажа в D шмоте Персонаж в С шмоте Персонаж в В шмоте Персонаж в Топ В шмоте Персонаж в А шмоте Выдача новым персонажам вещей по классу, Магам: Arcana Mace и DC Robe Set - Войнам: Angel Slayer и Drac Light Set Увеличить игрокам на 10% P.Def и M.Def Увеличить всем скорость бега на 20% Увеличить CP всех персонажей на 22% на 20 уровне. На 44% на 40 уровне. На 66% на 76 уровне Увеличить время восстановление маны в 10 раз Увеличить статы (Str,Int,Dex,Wit,Men,Con) всех персонажей в 2 раза Сделать что бы с мобов падало от 1к до 10кк адены фиксировано (рейты на адену нужно сделать х1) Сделать телепорт бесплатным Изменить стоимость нанесение краски на 5 аден Матерьял взят с сайта L2Maxi.Ru Пользуйтесь на здоровье.
-
1 баллtag_? - зачем это? (всегда значение одинаковое). quest_id - ID квеста. quest_prog - Поочередность этапа квеста. main_name - Название квеста. prog_name - Название этапа квеста. description - Описание этапа квеста. cnt1 - кол-во занятых столбцов: items. items - ID используемых итемов. cnt2 - кол-во занятых столбцов: num_items. num_items - кол-во используемых итемов. quest_x quest_y quest_z - Координаты ЭТАПА квеста. lvl_min lvl_max - мин. и макс. уровень квеста. quest_type - повторяющийся или одноразовый. 0 - повторяющийся, 1 - одноразовый, я ставил 2 - тоже повторяющийся. entity_name - Имя NPC к которому нужно идти по этапу квеста. get_item_in_quest - Не имею понятия. Нашарил на англ форуме и переводчик гласит так: 1 = Вам товар в квест часть, 0 = Нет объекта, полученной в поисках. UNK_1 - ? - Не имею понятия. Нашарил на англ форуме и переводчик гласит так:1 = же вкладке стек, 0 = конец стека (например:|11110|10| если УР во 2-м стеком ИД 6 или 7 В поисках прог|12345|67| отображается стек будет |167| в дисплее). UNK_2 - ? - Не имею понятия. Англ форум тоже не имеет понятия. contact_npc_id - Начальный NPC квеста. contact_npc_x,contact_npc_y,contact_npc_z - Нахождение NPC у которого берется квест. restricions - Требования по квесту. short_description - краткое описание квеста. cnt3 - Кол-во классов которые могут взять квест. req_class - ID классов которые могут взять квест. cnt4 - Кол-во видов необходимых итемов для начала квеста(то есть занятых столбцов: req_item). req_item - ID итемов необходимых для начала квеста. clan_pet_quest - Квест для клана или нет. 1 - для клана, 0 - нет. req_quest_complete - ID выполненного квеста, для выполнения этого. UNK_3 - ? (не в одном из стандартных квестов, эта графа не меняется, постоянно стоит 0). area_id - ID города к которому привязан квест. Оригиналы с англ форума: get_item_in_quest - 1 = get item in quest part, 0 = no item obtained in quest. UNK_1 - 1 = same tab stack, 0 = end of stack (ex: |11110|10| if ur in the 2nd stack id 6 or 7 in quest prog |12345|67| the displayed stack would be |167| in the display). UNK_2 - no clue. UNK_3 - unknown all 0
-
1 баллСнова всем привет. Наверное очень многие из Вас задаются вопросом, как-же все таки правильно рекламировать Ваш проект. К примеру, у Вас есть сборка, сайт, апдейтер, реализация, защита. Ну собственно все, чтобы начать рекламу. Для начала, я хочу уточнить, что чем больше у Вас финансы, тем более вероятен шанс на более успешное открытие. Совсем без вложений в рекламу сейчас довольно трудно открываться и заработок и онлайн с этого обычно копейчный. Мы возьмем не большую сумму в рекламу. Скажем у нас имеется 15.000 рублей, которые вы готовы отдать в пиар. Довольно большую глупость допускают те люди, которые платят другому человеку, чтобы тот вел проект по рекламе. Ибо все мы люди и каждому хочется заработать. Если Вы дадите 15.000 рублей человеку на рекламу, в данном случае лишь 12.000, в лучшем случае будет задействована в рекламу. А бывает оставляют себе и половину. Но здесь можно понять данный факт. Ибо, это человеческая жадность и как не обидно, но возможно почти любой из вас поступал бы так-же. Возможно человек и разбирается и сможет грамотно все организовать, но вы можете сделать то-же самое, не приложив особых усилий и вложите в рекламу больше. Другой вариант, если У вас есть не 15к рублей, а в разы больше и минимум времени, чтобы самим этим заниматься. Но я бы тоже несколько раз обдумал данного плана шаг. Мы этот факт оставляем и дальше я его здесь не описываю. И так, с чего все-же начать? Уж слишком много факторов здесь участвуют. Анализ и мониторинг. Это Ваш первый шаг. Вы должны проанализировать, какие конкуренты открываются рядом с вами и какие уже открыты. Какой онлайн на серверах, которые уже работают. Оценить сайт, сервер, пообщаться с игроками и узнать их мнение о данном сервере. Ненамеком упомянуть, что слышали, что скоро будет старт нового (Вашего) проекта. Люди, будьте умнее. Не пишите не кому в игре на других серверах, от имени администратора. Вы делаете анализ, а не наживаете себе врагов. Вас могут спалить. И будут не приятности. Мне бы такое не понравилось, как админу живого сервера. А если сервер уже запушен и на нем есть средний онлайн(человек 300), то этому проекту раз плюнуть накрыть Вас на старте, какую бы вы защиту не поставили. Идеальной защиты нет. Проанализировав другие сервера и сделав определенный вывод, вы должны выбрать дату открытия своего сервера. Она должна быть по возможности в день, когда вы будете открываться сами, без конкурентов, либо за день-два до них, а так-же на выходные, когда больше людей дома отдыхыет, так-же на каникулах у детворы, на праздники. с финансами в 15.000 рублей, вам нужно на рекламу минимум - неделя. максимум 2 недели(на больше деняг не хватит) после выбора даты старта, вы должны зарегистрироваться во всех возможных анонсерах бесплатно, кнопки с анонсеров НЕ В КОЕМ случае не ставьте на главную страницу сайта. Это очень отпугивает игроков. Можно создать отдельную страницу на сайте и сделать ссылку на неё. Или поместить на форуме. Купить Vip статусы на анонсерах. 50% игроков, сейчас ведут поиск серверов именно на них. Основные анонсеры - l2op, l2oops, la2anons. Покупка рекламы на анонсах делается за неделю до старта(с такими финансами.) Если более 7 дней планируете вести рекламу. то ВИП покупаем именно за 7 дней. Покупка рекламы на этих анонсах - Это примерно половина всех наших финансов. Далее я рекомендую открыть google и ввести Анонсы игровых серверов. Мы ищим менее знаменитые анонсеры, которые в гугдле на первых местах и можно не за дорого купить випку. К примеру 300 рублей вип на 7 дней. Если на анонсере есть среднее количество посещений, почему не купить? Здесь и начинается самое интересное. Теперь Нам нужно примерно посчитать. Дело в том, что все анонсеры ведут накрутку посещений. Смотрите на внешний вид, прикидывайте примерно, сколько этот анонсер может просматривать человек за сутки. Скажем Вы нашли анонсер, сделали для себя вывод, что средняя реальная посещаемость 100 человек в день. Но так-же на этом линейка делится на много хроник. Человек, который пришел искать сервер HighFive не будет искать ваш сервер, если он, скажем Interlude. Поэтому, пусть из 100 человек ваша аудитория, которую могут заинтересовать ваши сервера - 20%, 100*20/100 = 20, в итоге, мы получаем, что в день, вашу рекламу просмотрят 20 реально заинтересованых игроков, которые готовы были-бы у вас играть. Но дело в том, что по мимо Вас, так-же есть ещё другие сервера с такими хрониками, как у вас. Это и есть конкуренция. Поэтому мы опять считаем, по максимуму, из 20 человек, на ваш сайт войдет лишь половина. 20/2=10. и того, мы имеем 10 человек, который за сутки перешли к вам по ссылке. Сайт. После этого 10 человек вошли на сайт и вычитывают информацию. Всем не угодишь. Даже если у Вас мега крутой сайт и все очень красиво, но из 10 человек, которые в вам войдут, лишь процентов 20%, возможно запомнят сайт. (Если не забудут его до открытия или не найдут что-то другое в ближайшие дни.) И того. мы имеем 2 человека. Да. Это все очень запутано. Но так оно и есть... Ищите достойные анонсеры по достойным ценам. С анонсерами закончили. На данный момент это одно из основных условий пиара. 4.Скайп рассылка может хорошо Вам помочь. Я бы рекомендовал купить её, но только у проверенного продавца. 5.Не большая накрутка в л2топе. 6.Спам по группам в контакте и в личку. 7.Поиск и замануха клан лидеров(Не платите им. Часто разводят. Проверено.) 8.Акции и конкурсы. Хорошо мотивируют денежные бонусы на старте. 9.Постарайтесь кого-либо заинтересовать в стриме. Чтобы Ваш старт транслировался на сайте. 10.Ну я по идее у нас останется не большая копеечка, которую можно вкинуть за 1-2 дня до старта в l2top текстовую рекламу. Естественно выбора с финансами от 50.000 рублей больше, можно и обои купить боковые и стримера, но это отдельная тема для разговора. Успехов Вам.
-
1 балл1. Заходим на свой сервер : L2jFrozen\GameServer\head-src\com\l2jfrozen\gameserver\handler\itemhandlers Пример показан на сборке ( Frozen ) 2.Создаем файл EffectMusic.java и вставляем его в него: /* music effectpackage com.l2jfrozen.gameserver.handler.itemhandlers;import com.l2jfrozen.gameserver.handler.IItemHandler;import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance;import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;import com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance;import com.l2jfrozen.gameserver.network.serverpackets.ActionFailed;import com.l2jfrozen.gameserver.network.serverpackets.PlaySound;/*** @author devScarlet & mrTJO*/public class MusicItem implements IItemHandler{private static int[] _itemIds ={50000};@Overridepublic void useItem(L2PlayableInstance playable, L2ItemInstance item){if(!(playable instanceof L2PcInstance))return;L2PcInstance activeChar = (L2PcInstance) playable;int itemId = item.getItemId();if(activeChar.isParalyzed()){activeChar.sendMessage("Во время парализующего эффекта вы не можете использовать это действие!");activeChar.sendPacket(ActionFailed.STATIC_PACKET);return;}if(itemId == 50000) // Token of Love{PlaySound _snd3 = new PlaySound(1, "triple_kill", 0, 0, 0, 0, 0);activeChar.sendPacket(_snd3);playable.destroyItem("Consume", item.getObjectId(), 1, null, false);}activeChar = null;}/*** @see com.l2jfrozen.gameserver.handler.IItemHandler#getItemIds()*/@Overridepublic int[] getItemIds(){return _itemIds;}} <Дополнение:> Обратите внимание на сроки в коде: PlaySound _snd3 = new PlaySound(1, "triple_kill", 0, 0, 0, 0, 0); Воспроизводит OGG файл с названием triple_kil сам файл кидать в music с игрой ! </Дополнение:> 3.Находим файл ItemHandler.java и прописываем туда наш музыкальный эффект : import com.l2jfrozen.gameserver.handler.itemhandlers.EffectMusic; 3.1 А также после : registerItemHandler(new ChristmasTree()); Ставим : registerItemHandler(new EffectMusic());
-
1 балл(К сожалению форум не поддерживает множество картинок в 1 теме так что я ставлю ссылки просто)
-
1 баллПоскольку при первой установке своего сервера на Debian 7 были трудности я решил создать новый мануал. Скачиваем и устанавливаем нужные программы для Windows: Открываем Putty: В строку Host Name (or IP adress) - вписываем IP адрес VPS Выбираем Connection type: SSH В колонке с настройками с лева выбираем : Windows>Translation>Remote character set > UTF-8 Коннектимся! Вводим данные VPS которые пришли вам на email. По стандарту имя пользователя стоит "root" Username: root Password: Ваш пароль Не пугайтесь при вводе пароля звёздочки не отображаются но всё работает После этого система попросит вас сменить пароль: Вводим текущий пароль и вводим новый. Скачиваем и устанавливаем нужные программы для Debian. Базовые нужные программы для запуска мы установили. Добавление папки: Открываем WinSCP Заходим в папку root добавляем к примеру папку server (Правой клавишей мышки Новый>Папка) Cкидываем архив в папку. Перенос и разархиварование. Открываем Putty Вводим: cd server unzip имя файла.zip -d destination_folder Наш архив с сервером разархивируется в папку destination_folder Заходим в WinSCP жмём обновить. Перемещаем файлы куда нам нужно. Создание Mysql базы: Открываем Putty пишем mysql -p Вводим пароль от Mysql базы. CREATE DATABASE имя базы ; - не забудьте поставить точку с запятой и писать с заглавных букв. Посмотреть созданные базы: SHOW DATABASES; Настройка запуска Sh: Заходим в папку Loginserver cd server/loginserver Вводим chmod +rwx имя файла.sh cd - Перейти в root папку. cd server/gameserver Вводим chmod +rwx имя файла.sh Аналогично делаем с database_installer или другим инсталлером базы сервера. Устанавливайте права не только на gameserver.sh но и на другие находящиеся в папке файлы .sh Конвертируйте файлы .sh при помощи программы dos2unix для этого в консоле нужно набрать: dos2unix имя_файла.sh Увидим такую надпись dos2unix: converting file start.sh to Unix format ... Запуск сервера Переходим в папки и запускаем ./имя файла.sh Как сделать себя админом? Точно так же как и в win но для этого заходим в установленный нами phpmyadmin В браузерной строке набираем IP нашего сервера /phpmyadmin
-
1 баллАвтор: Juzzle Каждый задумывался как себя обезопасить от краха базы чаров, их предметов скиллов, да и вообще, базы всего сервера, но не знал как это делать. В данном мануале рассказано как создать файлы запуска резервного копирования Базы данных. 1. Для Windows создаем файл dump.bat в нем прописываем: *файл mysqldump.exe скопируйте в папку где лежит dump.bat теперь добавляем в авто загрузку заходим в Панель управления > Назначенные задания > Добавить задание жмем обзор, ищем свой файл устанавливаем флажёк на ежедневно время 00:10 (время лучше ставить с разбросом 5-10мин, чтоб задания не накладывались и не грузил сервер) заходим в свойства(прав. клик на файл) > расписание (закладка) > Дополнительно (кномпа) ставим флажек повторять задание каждые 1 часов выполнять в течении 24 час переходим в закладку параметры выполнять не дольше чем 5-15мин (если повиснет процесс, то винда процесс убьет) 2. Для Linux создаем папку dump (/home/dump) в ней создаем папку 2010 (/home/dump/2010) дальше создаем папки с месяцами (/home/dump/2010/01) и т.д. создаем файл dump.sh и проиписываем: дампим и сразу запихиваем в архив теперь файл dump.sh надо закинуть в crontab: каждый час в 50 мин (удобно перед осадами сохранять, за 10мин) в 5ч в 50 мин каждый день (лучше перед ежедневным ребутом за 30 мин)
-
1 баллДоброго времени суток. В этом мануале я научу вас делать бесконечные соски/стрелы (Выводим в конфиг). Буду показывать на сборке a-Cis. Бесконечные соски: Ищем класс по пути net\sf\l2j\gameserver\handler\itemhandlers: BeastSoulShot.java Добавляем следующий импорт: import net.sf.l2j.Config; Далее ищем: if (!activeOwner.destroyItemWithoutTrace("Consume", item.getObjectId(), activePet.getSoulShotsPerHit(), null, false)) { if (!activeOwner.disableAutoShot(item.getItemId())) activeOwner.sendPacket(SystemMessageId.NOT_ENOUGH_SOULSHOTS_FOR_PET); return; } Меняем на: if(!Config.DONT_DESTROY_SS) { if (!activeOwner.destroyItemWithoutTrace("Consume", item.getObjectId(), activePet.getSoulShotsPerHit(), null, false)) { if (!activeOwner.disableAutoShot(item.getItemId())) activeOwner.sendPacket(SystemMessageId.NOT_ENOUGH_SOULSHOTS_FOR_PET); return; } } Далее ищем класс по пути net\sf\l2j\gameserver\handler\itemhandlers: BeastSpiritShot.java Добавляем следующий импорт: import net.sf.l2j.Config; Далее ищем: if (!activeOwner.destroyItemWithoutTrace("Consume", item.getObjectId(), activePet.getSpiritShotsPerHit(), null, false)) { if (!activeOwner.disableAutoShot(itemId)) activeOwner.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS_FOR_PET); return; } Меняем на: if(!Config.DONT_DESTROY_SS) { if (!activeOwner.destroyItemWithoutTrace("Consume", item.getObjectId(), activePet.getSpiritShotsPerHit(), null, false)) { if (!activeOwner.disableAutoShot(itemId)) activeOwner.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS_FOR_PET); return; } } Далее ищем класс по пути net\sf\l2j\gameserver\handler\itemhandlers: BlessedSpiritShot.java Добавляем следующий импорт: import net.sf.l2j.Config; Далее ищем: if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), weaponItem.getSpiritShotCount(), null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS); return; } Меняем на: if(!Config.DONT_DESTROY_SS) { if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), weaponItem.getSpiritShotCount(), null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS); return; } } Далее ищем класс по пути net\sf\l2j\gameserver\handler\itemhandlers: SoulShots.java Добавляем следующий импорт: import net.sf.l2j.Config; Далее ищем: if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), ssCount, null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SOULSHOTS); return; } Меняем на: if(!Config.DONT_DESTROY_SS) { if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), ssCount, null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SOULSHOTS); return; } } Далее ищем класс по пути net\sf\l2j\gameserver\handler\itemhandlers: SpiritShot.java Добавляем следующий импорт: import net.sf.l2j.Config; Далее ищем: if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), weaponItem.getSpiritShotCount(), null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS); return; } Меняем на: if(!Config.DONT_DESTROY_SS) { if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), weaponItem.getSpiritShotCount(), null, false)) { if (!activeChar.disableAutoShot(itemId)) activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS); return; } } Далее ищем класс по пути net\sf\l2j: Config.java Ищем: /** Buffs */ public static boolean STORE_SKILL_COOLTIME; public static int BUFFS_MAX_AMOUNT; Добавляем ниже: /** Custom */ public static boolean DONT_DESTROY_SS; Ищем: BUFFS_MAX_AMOUNT = players.getProperty("MaxBuffsAmount", 20); STORE_SKILL_COOLTIME = players.getProperty("StoreSkillCooltime", true); Добавляем ниже: DONT_DESTROY_SS = players.getProperty("DontDestroySS", true); Далее ищем конфиг по пути gameserver\config: players.properties В любое место добавляем следующие параметры: #============================================================= # Custom #============================================================= # Не использовать соски ? DontDestroySS = true Бесконечные стрелы: Ищем класс по пути net\sf\l2j\gameserver\model\actor: L2Character.java Ищем: reduceArrowCount(); Меняем на: if(!Config.DONT_DESTROY_ARROWS) { reduceArrowCount(); } Далее ищем класс по пути net\sf\l2j: Config.java Ищем: /** Buffs */ public static boolean STORE_SKILL_COOLTIME; public static int BUFFS_MAX_AMOUNT; Добавляем ниже: /** Custom */ public static boolean DONT_DESTROY_ARROWS; Ищем: BUFFS_MAX_AMOUNT = players.getProperty("MaxBuffsAmount", 20); STORE_SKILL_COOLTIME = players.getProperty("StoreSkillCooltime", true); Добавляем ниже: DONT_DESTROY_ARROWS = players.getProperty("DontDestroyArrows", true); Далее ищем конфиг по пути gameserver\config: players.properties В любое место добавляем следующие параметры: #============================================================= # Custom #============================================================= # Не использовать стрелы ? DontDestroyArrows = true Специально для L2Maxi.
-
1 баллДанный мануал очень кстати для новичков. Для чего это нужно? Избежать брута админки. Избежать 100% фейла проекта. Увеличить свою безопасность. И так приступим: Заходим в свой FTP клиент. /home/httpd/site/движок. Находим папку admin меняем на допустим Jhwjehfw782hF Находим файл admin.php меняем название на "допусти" JHJgw3467auyJJHqgfQdffD.php сохраняем , ВНИМАНИЕ не каких символов только буквы - цифры. Находим папку dev , видим там файл boot.admin.php меняем название например на boot.HJqhfqu72gfsE.php Открываем наш файл админки был admin.php стал JHJgw3467auyJJHqgfQdffD.php Ищем в файле JHJgw3467auyJJHqgfQdffD.php Строку define( 'ADMINDIR', 'admin' ); Меняем строку define( 'ADMINDIR', 'admin' ); на define( 'ADMINDIR', 'Jhwjehfw782hF' ); Ищем строку define( 'ADMFILE', 'admin.php' ); меняем на define( 'ADMFILE', 'JHJgw3467auyJJHqgfQdffD.php' ); Ищем строку require DEVDIR.'boot.admin.php'; меняем на require DEVDIR.'boot.HJqhfqu72gfsE.php'; Сохраняем! Всё готово , теперь ваша админка доступна по адресу site.ru/JHJgw3467auyJJHqgfQdffD.php Спасибо за внимание!
-
1 баллИдём в папку: net/sf/l2j/gameserver/clientpackets/ и открываем файл UseItem.java Ищем там: if (Config.DEBUG) _log.finest(activeChar.getObjectId() + ": use item " + _objectId); if (item.isEquipable()) После чего вставляем данный код: if(!activeChar.isGM()) { if(item.getItem().getType2() == L2Item.TYPE2_WEAPON && item.getEnchantLevel() > Config.ENCHANT_WEAPON_MAX) { activeChar.setAccountAccesslevel(-999); activeChar.sendMessage("You have been banned for using an item wich is over enchanted!!"); activeChar.closeNetConnection(); return; } if(item.getItem().getType2() == L2Item.TYPE2_SHIELD_ARMOR && item.getEnchantLevel() > Config.ENCHANT_ARMOR_MAX) { activeChar.setAccountAccesslevel(-999); activeChar.sendMessage("You have been banned for using an item wich is over enchanted!!"); activeChar.closeNetConnection(); return; } if(item.getItem().getType2() == L2Item.TYPE2_ACCESSORY && item.getEnchantLevel() > Config.ENCHANT_JEWELRY_MAX) { activeChar.setAccountAccesslevel(-999); activeChar.sendMessage("You have been banned for using an item wich is over enchanted!"); activeChar.closeNetConnection(); return; } } Автор: la2vampir
-
1 баллАвтором данного мануала я не являюсь, но думаю он вам пригадится. РРедактирование XML поможет Вам в изменении "статов" скилов, брони, разного вида оружия и прочего. Так-же она пригодиться тем, кто занимается созданием магазинов и их редактированием. Для начала напишем небольшой пример[u] XML кода[/u] + комментарии к нему. ( Данные строчки можете использовать при [u]редактировании [/u]своих[u] xml файлов[/u]. ) <mul order="0x30" stat="mAtk" val="1.40"/> <!-- M atk +40% --> <mul order="0x30" stat="pDef" val="1.40"/> <!-- P. Def. +40% --> <mul order="0x30" stat="mDef" val="1.40"/> <!-- M. Def. +40% --> <mul order="0x30" stat="mAtkSpd" val="1.40"/> <!-- Casting Spd. +40% --> <mul order="0x30" stat="mCritRate" val="3.00"/> <!-- Magic Crit. Rate +300% --> <mul order="0x30" stat="gainHp" val="1.20"/> <!-- Heal +20% --> <mul order="0x30" stat="rShld" val="1.60"/> <!-- Shield Defense +60% --> <mul order="0x30" stat="regMp" val="2.00"/> <!-- MP Regeneration +200% --> <mul order="0x30" stat="regHp" val="2.00"/> <!-- HP Regeneration +200% --> <mul order="0x30" stat="regCp" val="2.00"/> <!-- CP Regeneration +200% --> <add order="0x40" stat="runSpd" val="50"/> <!-- Speed +50 --> <add order="0x40" stat="rEvas" val="10"/> <!-- Evasion +10 --> <add order="0x40" stat="accCombat" val="10"/> <!-- Accuracy +10 --> <add order="0x40" stat="reflectDam" val="30"/> <!-- Reflect damage by enemy +30% --> <add order="0x40" stat="maxMp" val="10000"/> <!-- Max MP +10000 --> <add order="0x40" stat="maxHp" val="10000"/> <!-- Max HP +10000 --> <add order="0x40" stat="maxCp" val="10000"/> <!-- Max CP +10000 --> <add order="0x40" stat="WIT" val="7"/> <!-- WIT +7 --> <add order="0x40" stat="CON" val="7"/> <!-- CON +7 --> <add order="0x40" stat="STR" val="7"/> <!-- STR +7 --> <add order="0x40" stat="MEN" val="7"/> <!-- MEN +7 --> <add order="0x40" stat="INT" val="7"/> <!-- INT +7 --> <add order="0x40" stat="DEX" val="7"/> <!-- DEX +7 --> <add order="0x40" stat="rootRes" val="200"/> <!-- Root Resistance +200% --> <add order="0x40" stat="earthRes" val="200"/> <!-- Earth Resistance +200% --> <add order="0x40" stat="derangementRes" val="200"/> <!-- Mental Reistance +200% --> <add order="0x40" stat="fireRes" val="200"/> <!-- Fire Resistance +200% --> <add order="0x40" stat="paralyzeRes" val="200"/> <!-- Paralysis Resistance +200% --> <add order="0x40" stat="sleepRes" val="200"/> <!-- Sleep Resistance +200% --> <add order="0x40" stat="rootRes" val="200"/> <!-- Hold Resistance +200% --> <add order="0x40" stat="poisonRes" val="200"/> <!-- Poision Resistance +200% --> <add order="0x40" stat="stunRes" val="200"/> <!-- Stun Resistance +200% --> <add order="0x40" stat="bleedRes" val="200"/> <!-- Bleed Resistance +200% --> <add order="0x40" stat="maxLoad" val="99999"/> <!-- Point at which a weight penalty is applied +99999 --> <add order="0x40" stat="cancel" val="300"/> <!-- Small decrease in chance of spell interruption - TO CHECK --> И так, поехали... 1. Введение Что такое XML? Этот формат, предназначенный для хранения структурированных данных, для обмена информацией между программами, а также для создания на его основе более специализированных языков разметки (например, XHTML), иногда называемых словарями. Первая строка XML-документа называется объявлением XML — это необязательная строка, указывающая версию стандарта XML (обычно это 1.0), также здесь может быть указана кодировка символов и внешние зависимости. <?xml version="1.0" encoding="UTF-8"?> Спецификация требует, чтобы процессоры XML обязательно поддерживали Юникод-кодировки UTF-8 и UTF-16. Но признаются допустимыми, поддерживаются и широко используются и другие кодировки. Так же в XML есть возможность добавления комментария. Комментарий может быть размещен в любом месте дерева. XML комментарии размещаются внутри пары тегов <!-- и -->. Два знака дефис (--) не могут быть применены ни в какой части внутр. комментария. Вот пример комментария: <!-- Текст коментария --> Не будем углубляться во все особенности XML, нас интересует только часть, которая касается Lineage 2. XML в сервере Lineage применяется для описания статов оружия, брони, скилов, аргументов, зон, магазинов, зон рестарта чаров и много другого. Для оружия это например параметры физ. и маг. атаки, для брони - защиты, для скилов - продолжительность действия, сила, эффект и т.д. А например в файле "servername.xml" хранятся имена серверов по умолчанию. Эти имена когут быть легко изменены. Но помимо изменений на серверной части необходимы и изменения со стороны клиента (со стороны клиента необходимо изменить файл "servername-e.dat". Изменяться *.dat файлы клиента могут с помощью специальных программ. В XML файлах зон хранятся параметры этих зон. Есть и XML файлы где к определенному предмету приписывается определенный скил(например ошейнику волка привязывается скилы вызова волка). 2. Основы Что нужно знать как основу для редактирования? 1) XML файлы по умолчанию хранятся в папках gameserver\data\ и открываются любым текстовым редактором что работыет с UTF кодировками. 2) Имена *.xml файлов даются по диапазону id статов, Например в файле с именем 0800-0899.xml будут статы от id=800 до id=899. Для быстродействия желательно (но не обязательно) в одном файле хранить не больше ста id. Надо сказать что в названиях могут быть исключения, файлы могут называться и без указания диапазона id которые в нем хранятся. Такое характерно для аргументов и зон и файла с итемами петов. 3) При использовании текста рекомендовано (но не обезательно) использовать латинские символы. 4) Параметр ID должен быть в диапазоне от 1 до 2ккк 3. Редактирование статов и скилов. В папке stats можно найти несколько папок которые отвечают за параметры брони, оружия, аргументов, скилов и некоторых других предметов (например банок для востоновления хп/цп/мп или свитков с бафовами). Формат записи одного стата следующий: <item id='числовой_идентификатор' name="Название стата"> <for> <add val='значение' order="приоритет" stat='название стата'/> <mul val='значение' order="приоритет" stat='название стата'/> <sub val='значение' order="приоритет" stat='название стата'/> <enchant val='значение' order="приоритет" stat='название стата'/> <set val='значение' order="приоритет" stat='название стата'/> </for> Все изменения в стате должны находится между тегами Теперь рассмотрим главные операции со статами. <add /> - добавление статов. Стат увеличится на указаную величину. <mul /> - умножение статов. То есть если вы оденете вещь или используете скил, ваши статы умножатся. Например если <sub /> - вычетание. То есть если вы оденете вещь(или заюзатете скил), ваши статы (или статы цели) уменьшатся. <enchant /> - увеличение/снижение при заточке. Роказывает, на сколько увеличится/уменшится стат при заточке еще на +1 <set /> - задание строгого значения. То есть если вы оденете вещь со значением 20, то тот стат, но который это значение влияет будет равен 20. Со скилами также. Главными параметрами этих операций являются: val="" - значение order="" - приоритет в формуле (подробно о приоритетах писать в этой статье не буду, это отдельная и сложна тема) stat="" - что собственно изменять Значения order могут быть следущие: 0x08 - set 0x10 - add/sub (оружие, броня, бижутерия) и (STR, CON, DEX, INT, WIT ,MEN) 0x20 - не используется (опционально) 0x30 - mul/div (masteries, buffs, debuffs, SA (специальные возможности оружия), бонусы брони) 0x40 - add/sub (masteries, buffs, debuffs, SA (специальные возможности оружия)) 0x50,0x60 - не используется (опционально) 0x0C - enchant Списки статов доступных для изминения: Этот список в разных сборках разный, но в большинстве случаев принято использовать следующие названия. Изменение максимального количества HP - maxHp Изменение максимального количества CP - maxCp Изменение максимального количества MP - maxMp Регенерация НР - regHp Регенерация СР - regCp Регенерация МР - regMp Эффективность хила - gainHp Умение хила - giveHp Бонус хила - bonusHp Физическая защита - pDef Магическая защита - mDef Физическая атака - pAtk Магическая атака - mAtk Скорость физической атаки - pAtkSpd Скорость магической атаки - mAtkSpd Скорость отката - mReuse Защита щитом- sDef Угол защиты щитом - shieldDefAngle Критический удар - cAtk Прибавка к критическому удару - cAtkAdd Физ. урон в пвп (например для Duel Might) - pvpPhysDmg Маг. урон - pvpMagicalDmg Урон скилом - pvpPhysSkillsDmg Уворот - rEvas Уворот от скилов- pSkillEvas Шанс блокировки щитом - rShld Шанс крита - rCrit Шанс Blow - blowRate Шанс Lethal - lethalRate Маг. крит. шанс - mCritRate (mCrit doesn't work!!) EXP,SP шанс - rExp Cancel - cancel Точность - accCombat Зона покрытия физ. атаки - pAtkRange (for fighters) Зона покрытия маг. атаки- mAtkRange (for mages) Угол атаки (только для воинов) - pAtkAngle Количество атакуемых - atkCountMax Откат физ. скилов - atkReuse Скорость бега - runSpd Скорость ходьбы - walkSpd STR - STR DEX - DEX WIT - WIT INT - INT MEN - MEN Уязвимости Агрессия - aggressionVuln Кровотечение - bleedVuln Яд - poisonVuln Стан - stunVuln Парализация - paralyzeVuln Удерживающие заклинания - rootVuln Сон - sleepVuln "Перекидывание" таргета - confusionVuln Движение - movementVuln Огонь - fireVuln Ветер - windVuln Вода - waterVuln Земля - earthVuln Святые атаки - holyVuln Темные атаки - darkVuln Резист к cancel - cancelVuln Дебаффы - debuffVuln Резист к криту - critVuln Резисты против оружия (тут думаю описание не нужно) noneWpnVuln swordWpnVuln bluntWpnVuln daggerWpnVuln bowWpnVuln crossbowWpnVuln poleWpnVuln etcWpnVuln fistWpnVuln dualWpnVuln dualFistWpnVuln bigSwordWpnVuln Отражение Процент отражаемого урона - reflectDam (pay attention! not reflectDmg!! reflectDam) Процент рассеиваемого урона - absorbDam Процент переносимого урона- transDam Отражение маг. скилов - reflectSkillMagic Отражение физ. скилов - reflectSkillPhysic Другое (для примера): Атака на гигантов - pAtk-giants Защита на нежить - pDef-undead Атака на животных - pAtk-animals Защита на монстрах - pDef-monsters Лимит инвентаря - inventoryLimit Лимит ВХ - whLimit Freight лимит - FreightLimit Лимит продажи. - PrivateSellLimit Лимит покупки - PrivateBuyLimit Лимит гномьего крафта - DwarfRecipeLimit Лимит common крафта - CommonRecipeLimit Потребление МР физ. скилами - PhysicalMpConsumeRate Потребление МР маг. скилами - MagicalMpConsumeRate Потребление МР дансами - DanceMpConsumeRate Потребление НР - HpConsumeRate Потребление МР - MpConsume Потребление соулшотов - soulShotCount Skill Мastery - skillMastery Время пребывания под водой - breath Дополнения для редактирования статов скилов Важно знать что любой скилл начинается с открывающего тега и заканчивается закрывающим тегом. В скилах есть 3 обязательных тега, без которых он не будет работать - это target, skilltype и operatetype. 1. target - тег, который показывает на кого будет браться таргет, что видно из названия. Принимает следующие значения: TARGET_SELF - обозначает, что скилл будет использоватся исключительно на его владельца (селф бафф типа Battle Roar или War Cry) TARGET_NONE - цель неопределена TARGET_ONE - обозначает, что цель вашего скилла - тот кто в таргете. TARGET_AREA - обозначает, что скилл будет массовым TARGET_AGGREMENT - обозначает, что целью будет тот, кто вас атакует 2. skilltype - тег, указывающий на тип скилла (бафф, дебафф) Принимает следующие значения: BUFF - бафф (оказывает положительное воздействие) DEBUFF - дебафф (оказывает негативное воздействие) 3. operatetype - этот тег служит для определения типа скилла (активный либо пассивный) OP_ACTIVE - активный скилл, может быть использован игроком OP_PASSIVE - пассивный скилл, скилл с таким operateType не может быть использован (действует всегда) Это были обязательные переменные, используемые в скилах. Теперь перейдем к остальным: -power - сила скилла -hitTime - скорость. Для баффа это скорость чтения заклинания, для физ. скилла - скорость атаки -reuseDelay - откат скилла -hpconsume , mpconsume - потребление МР, НР -castRange - это дальность использования того или иного скилла (дистанция) -isMagic, isDebuff, isBuff - это наводящие теги, могут иметь значение "true" и "false". К примеру, isBuff = true (это значит что скилл является баффом) -effectRange - радиус действия (для массовых скиллов) -agro - что такое агр, и что такое сила агра думаю объяснять не нужно. Надо сказать что в зависимости от сборки могут использоваться и другие теги, но так как этот мануал общий для всех сборок их приводить не будем. Тег effect в скиллах Lineage 2 встречается очень часто. Обычно тег используется для "добавления сложных действий" к скиллу. Если скилл имеет сложный вариант реализации то обычно в тег добавляют некоторые отдельные значения, которые реализованы в ядре сервера Lineage. Это самый важный тег для использования в скилах. Приведем пример использования тега : <for> <effect name="тип" val="значение" time="время действия" stackOrder="переменная" stackType="переменная ядра"> </effect> </for> </skill> Что это значит? name - это тип эффекта val - значение эффекта. Для дебаффов - шанс прохождения, для боевых скилов - сила. time - время действия эффекта StackOrder и stackType - это значения уже описаные в данном скиле и заданы в ядре сервера и в разных сборках могут называться по разному (или даже отсутствовать). 4. Зоны Довольно важным в игровом мире есть понятие зон. Например в городах мирные зоны в которых запрещены атаки других игроков (и иногда нпц). Или зоны арен где не насчитывается пвп/пк счетчик. Зоны, также как и статы/скилы принято задавать в xml файлах. Рассмотрим структуру описания зоны: <zone id="ID зоны" name="Имя зоны" type="Тип зоны"> <settings exitOnDeath="true" buffRepeat="true" affected="single" /> <skill applyEnter="ID эффекта, уровень эффекта" removeExit="ID эффекта" /> <shape type="Форма зоны" zMin="Минимум Z" zMax="максимум Z"> <point x="координата" y="координата"/> <point x="координата" y="координата"/> </shape> </zone> Параметры что используются при создании заны: id - идентификатор зоны. type - тип зоны (town, arena, jailzone, Boss). Например: Town - мирная зона (город), Arena - боевая зона (PVP). Также могут быть другие типы зон которые описаны в ядре сервера. shape type - это форма или вид зоны. Может быть двух типов: Poly(многоугольные зоны) и Rect(прямоугольные зоны). В разных сборках названия типов могут отличатся (напрмиер nPoly и Cupoid). Также в некоторых сборках может использоваться и тип Circle (круг), для задания этого типа указываются координаты центра и радиус. minZ - это минимально допустимая координата высоты (z) в данной зоне . maxZ - это максимально допустимая координата высоты (z) в зоне. minZ и maxZ используются для избежания прохождения через текстуры, провалов под них и т.д. name - зоне можно задать любое имя, но только из допустимых символов, используется для удобства работы с большим количеством зон point - задает координаты границ зоны. settings - дополнительные параметры зоны. В большинстве случаев не используются, хотя и делают игру чуть интересней. Подробное описание тега settings приводить не буду из за того что в разных сборках довольно большие различия при его использовании. В приведенном примере описания зоны в теге settings указано что после смерти игрок может покинуть зону и что в зоне на всех чаров что находятся без пати накладывается баф applyEnter указанного уровня и при выходе с зоны убирается. Повторюсь еще раз, в разных сборках это реализация этого тега происходит по разному. Так же внутри тегов можно использовать описание точек "респавна" чара в них. При указании нескольких точек "респавна" чар будет появляться в них рандомно. <stat name="spawnX" val="X координата"/> <stat name="spawnY" val="Y координата"/> <stat name="spawnZ" val="Z координата"/> 5. Магазины В линейдж есть особенный тип магазинов под названием multisell, изначально он был задуман для обмена вещей на вещи (впервые использоваться у рыбаков). В наше время этот магазин широко используется в на пвп серверах для создания ГМ шопов, хотя этом круг его использования не ограничивается. Названия XML файлов для магазинов такие как ID этих магазинов (но тут также есть небольшие исключения, есть магазины где название и id разные). Формат данных в магазине следующий: <item id="номер по возрастанию"> <production id="id предмета" count="количество"/> <ingredient id="id предмета" count="количество"/> </item> item id - номер предмета в ячейка магазина, используется для задания порядка отображения предметов в магазине. Обратите внимание что этот номер НЕ должен повтояться и для каждого предмета должен быть уникален в рамках одного магазина. production - предмет который покупается в магазине. в этом теге указывается id предмета и его количество. ingredient - предмет за который можно купить production в магазине. в этом теге указывается id предмета и его количество. В большинстве случаев используют адену, древнюю адену или колы, но предметом для покупки может быть любая вещь. Надо знать что в одном теге item может быть несколько тегов ingredient, это будет значить что при покупку production вам надо будет несколько указанных предметов. Напримиер при покупке заточек у мамона надо иметь древнюю адену и чистые скролы. Использование нескольких production также возможно, но крайне не рекомендовано создателями сборок. Также можно указывать дополнительные параметры покупки, например часто используется параметр enchant, который позволит покупать уже заточенную вещь. Например <production id="7575" count="1" enchant="10" /> - будет куплен драк лук +10. Еще довольно интересно: при задании параметра enchant у ошейников для вызова питомцев питомец будет уже прокачан до указанного в параметре enchant уровня. Кроме enchant можно использовать и параметры для камней стихий и т.п.
-
1 баллДанный мануал не учит перекрашивать, а также в нем не указано что и как импортировать или кодировать. Только как сохранять. Иконка: Если сохранять dds обычно - в dxt3 , то при сохранению - ошибок не будет. Но в игре при попытке перетаскивать иконку - вы замете размытую и разноцветную картинку, нечем не похожу на вашу иконку. Понимаю что это незначительная ошибка, но если уже делать все правильно, то нужно все таки исправить, займет это все - 2 минуты. После создания иконки ( а я напоминаю что размер иконки у нас 32х32 ) - просто сохраняем её в формате dds, с такими настройками: После этого импортируем в utx, который кодируем и впихиваем в клиент. После чего в датниках можно указывать путь к файлам. Текстуры с Альфа Каналом - это те текстуры, при неправильном сохранению которых - у нас обычно появляются новые, темные участки, которые выглядят некрасиво, и нам не нужны. Для того чтобы правильно сохранить dds'ку - нужно. 1) Взять прямой utx файл ( в котором ещё нету этих ненужных черных линий ). 2) Перекрасить его, или изменить.так как вам нужно ( часто это может быть сам размер dds файла, для уменьшения размера патча ). Дальше просто сохранить со следующими настройками: После чего - любым удобным способом впихиваем dds файл в utx - я использую UE, но также можно использовать l2tool. Примечание: Для правильного импорта с помощью unreal'a - иногда нужно при импорте поставить галочку возле 'masked' и выбрать формат dxt3 ( справа выпадающий столбик ). Если вы используете l2tool - то таких проблем обычно не возникает. Мануал строго не судить, писался с нуля. Никакого копипаста.
-
1 баллВступление. Как вам известно, после хроник Эпилога стало достаточно трудно менять текстуры модэли в игре, лишь истенные профи могут и дальше продолжать свое ремесло. А просмотр текстур так вообще стал проблемой и за несоотвествие кодировок файлов, поэтому знаменитые программы для просмотра текстур такие как L2ViewUtx и UTPT и даже фиксеры оказались после данных хроник безполезные. И так наша цель такова: Открыть любой файл текстур .utx с папки systextures, просмотреть все файлы их имена и их иконки и внедрить их в шаблоны страниц путем использование HTML кодов. Часть 1: Нужные файлы. Umodel http://www.gildor.or...ts/umodel#files Adobe Bridge http://www.adobe.com...cts/bridge.html (либо скачать пиратскую версию) Часть 2: Приступим к работе!!1 1. На диске C:/ Создаем папку umodel и разархивируем все файлы программы Umodel туда. 2. Копируем нужный вам .utx файл из папки systextures клиента в папку C:/Umodel, я взял для примера L2Font-e.utx 3. Открываем Notepad и пишем данную строку: umodel -export -all L2Font-e.utx Теперь вы имеете папку L2Font-e/textures где находятся все текстуры данного Utx файла в тарга формате. *Примечание. И за того что обычный просмотр изображений не поддерживает Targa файлы. (TGA) нам не удобно будет просматривать их. Я пробовал их открывать в фотошопе и тоже не удобно было...Но случайно открыл папку с текстурами из Adobe Bridge уже установленный у меня на компютере и меня озарило)) 4)Устанавливаем Bridge 5)открываем папку. радуемся виду. Часть 3 : Внедрение в игру Для примера возьмем страницу HTML любого свободного NPC Я взял также для примера текстуру map_cleft, но т.к размер слишком большой мы его просто урежем картинка не будет полностью входить в рамки но это же для примера) Тем более я делал это в комюнити И пишем следующий код: <html><body><center> <table border=0 cellpadding=0 cellspacing=0 > <tr><td width=512 height=512 background="L2Font-e.map_cleft"></td></tr> </table> </center></body></html> Вуаля! У НАС ПОЛУЧИЛОСЬ!!!111 P.S.Надеюсь информация не баян, и меня не забанят) Надеюсь вам это пригодилось!
-
1 баллДобрый день пользователи L2Maxi Видел на форуме несколько тем как сменить имя текстуре или закодировать в читаемый для клиента формат. Решил сделать мануал. Итак начнем: 1) Нам нужно: L2decrypt.exe, L2tool.exe ну и Unreal Editor 2 2) Сначала нужно раскодировать текстуру, для этого просто перетащим её на l2decrypt.exe и получим файл имя_текстуры.clear.utx , как вы видите на скрине: 3) Открываем файл имя_тектуры.clear.utx с помощью Unreal Editor'a 4) Сразу после открытия сохраняем файл с нужным нам именем 5) Осталось только закодировать файл с помощью L2tool в читаемый для клиента формат. Для этого открываем файл с помощью L2Tool.exe 6) Выбираем 121 кодировку ( нужно вписать вручную ) и нажимай на значок с крякозябрами 7) Вот и все, осталось только переписать .dat файлы Если же Вам нужно просто закодировать файл в читаемый для клиента формат - Нужно выполнить 5 и 6 пункты данного мануала. Будут вопросы - задавайте в теме. Любителям копипастить - пожалуйста указывайте автора.
-
1 баллЧасть 1) чтобы быть в курсе: Начнем с того, что же такое XML? Это текстовый формат, предназначенный для хранения структурированных данных, для обмена информацией между программами, а также для создания на его основе более специализированных языков разметки (например, XHTML), иногда называемых словарями. Первая строка XML-документа называется объявлением XML — это необязательная строка, указывающая версию стандарта XML (обычно это 1.0), также здесь может быть указана кодировка символов и внешние зависимости. <?xml version="1.0" encoding="UTF-8"?> Спецификация требует, чтобы процессоры XML обязательно поддерживали Юникод-кодировки UTF-8 и UTF-16. Признаются допустимыми, поддерживаются и широко используются и другие кодировки. Так же в XML есть возможность добавления комментария. Комментарий может быть размещен в любом месте дерева. XML комментарии размещаются внутри пары тегов <!-- и -->. Два знака дефис (--) не могут быть применены ни в какой части внутри комментария. Вот пример комментария: <!-- Текст --> Но мы не будем углубляться во все особенности XML, нас интересует только часть, которая касается Lineage 2 XML в сервере Lineage применяется для описания статов оружия, брони, скилов и т.д. Для оружия это например параметры физ. и маг. атаки, для брони - защиты, для скилов - продолжительность действия, сила, эффект и т.д. А например в файле "servername.xml" хранятся имена серверов по умолчанию. Эти имена могут быть легко изменены. Но помимо изменений на серверной части необходимы и изменения со стороны клиента (со стороны клиента необходимо изменить файл "servername-e.dat". Изменяться *.dat файлы клиента могут с помощью специальных программ - L2Dat_EncDec и L2 FileEdit. В следующей части я научу вас изменять статы вещей. Часть 2) Меняем статы вещей. Возьмем итем Shirt. Это неприметная НГ шмотка. На ее примере я поясню что, где и когда. Вот фрагмент XML кода: <item id='21' name="Shirt"> <for> <add val='36' order='0x10' stat='pDef'/> </for> </item> Для измения ее статов тут нам нужна только одна строчка: <add val='36' order='0x10' stat='pDef'/> Что бы было понятнее расшифрую: <add val="значение" order="место в формуле" stat="что собственно прибавлять, в нашем случае физ. защиту" /> Тег <add />означает прибавление и является переменной. На его месте могут так же быть, например, <sub />, <set />, <mul />, <enchant /> . И так. Что же означают эти значения? 1. <add /> - прибавление статов. То есть если вы оденете вещь, ваши статы увеличатся. Значение order будет 0x10. [color="#0000FF"]<add val='100' order="0x10" stat='pDef'/>[/color] Данный код значит что при одевании вещи вам прибавится 100 единиц стата (в данном случае P. Def). 2. <sub /> - вычитание статов. То есть если вы оденете вещь, ваши статы уменьшатся. order так же - 0x10. [color="#0000FF"]<sub val='100' order="0x10" stat='mDef'/>[/color] Данный код значит что при одевании вещи у вас отнимется 100 единиц стата (в данном случае M. Def). 3. <set /> - назначает вам строгое значение стата. То есть если вы оденете вещь со значением 20, то тот стат, но который это значение влияет будет равен 20. Order 0x08. [color="#0000FF"]<set val='100' order="0x08" stat='pDef'/>[/color] Данный код значит что при одевании вещи у вас станет 100 единиц стата (в данном случае P. Def). 4. <mul /> - умножение статов. То есть если вы оденете вещь, ваши статы умножатся. Order 0x30. [color="#0000FF"]<mul val='100' order="0x10" stat='mDef'/>[/color] Данный код значит что при одевании вещи значение стата умножится на 100 (в данном случае M. Def). 5. <enchant /> - показывает, на сколько увеличится стат при заточке еще на +1. Order 0x0C. [color="#0000FF"]<enchant val='100' order="0x0C" stat='pDef'/>[/color] Данный код значит что при заточке вещи еще на 1 ваши статы (в данном случае P. Def) увеличатся на 100. Ниже приведена таблица значений "order": 0x08 - set 0x10 - add/sub (оружие, броня, бижутерия) и (STR, CON, DEX, INT, WIT ,MEN) 0x20 - не нужно 0x30 - mul/div (masteries, buffs, debuffs, SA (специальные возможности оружия), бонусы брони) 0x40 - add/sub (masteries, buffs, debuffs, SA (специальные возможности оружия)) 0x50,0x60 - не нужно 0x0C - enchant Часть 3) Меняем скилы: Самая большая часть моей статьи Начну со значений, ибо вы должны знать что изменяете: Изменение максимального количества HP - maxHp Изменение максимального количества CP - maxCp Изменение максимального количества MP - maxMp Регенерация НР - regHp Регенерация СР - regCp Регенерация МР - regMp Эффективность хила - gainHp Умение хила - giveHp Бонус хила - bonusHp Физическая защита - pDef Магическая защита - mDef Физическая атака - pAtk Магическая атака - mAtk Скорость физической атаки - pAtkSpd Скорость магической атаки - mAtkSpd Скорость отката - mReuse Защита щитом- sDef Угол защиты щитом - shieldDefAngle Критический удар - cAtk Прибавка к критическому удару - cAtkAdd Физ. урон в пвп (например для Duel Might) - pvpPhysDmg Маг. урон - pvpMagicalDmg Урон скилом - pvpPhysSkillsDmg Уворот - rEvas Уворот от скилов- pSkillEvas Шанс блокировки щитом - rShld Шанс крита - rCrit Шанс Blow - blowRate Шанс Lethal - lethalRate Маг. крит. шанс - mCritRate (mCrit doesn't work!!) EXP,SP шанс - rExp Cancel - cancel Точность - accCombat Зона покрытия физ. атаки - pAtkRange (for fighters) Зона покрытия маг. атаки- mAtkRange (for mages) Угол атаки (только для воинов) - pAtkAngle Количество атакуемых - atkCountMax Откат физ. скилов - atkReuse Скорость бега - runSpd Скорость ходьбы - walkSpd STR - STR DEX - DEX WIT - WIT INT - INT MEN - MEN Уязвимости: Агрессия - aggressionVuln Кровотечение - bleedVuln Яд - poisonVuln Стан - stunVuln Парализация - paralyzeVuln Удерживающие заклинания - rootVuln Сон - sleepVuln "Перекидывание" таргета -confusionVuln Движение - movementVuln Огонь - fireVuln Ветер - windVuln Вода - waterVuln Земля - earthVuln Святые атаки - holyVuln Темные атаки - darkVuln Резист к cancel - cancelVuln Дебаффы - debuffVuln Резист к криту - critVuln Резисты простив оружия (тут думаю описание не нужно) noneWpnVuln swordWpnVuln bluntWpnVuln daggerWpnVuln bowWpnVuln crossbowWpnVuln poleWpnVuln etcWpnVuln fistWpnVuln dualWpnVuln dualFistWpnVuln bigSwordWpnVuln Отражение: Процент отражаемого урона - reflectDam (pay attention! not reflectDmg!! reflectDam) Процент рассеиваемого урона - absorbDam Процент переносимого урона- transDam Отражение маг. скилов - reflectSkillMagic Отражение физ. скилов - reflectSkillPhysic Другое (для примера): Атака на гигантов - pAtk-giants Защита на нежить - pDef-undead Атака на животных - pAtk-animals Защита на монстрах - pDef-monsters Лимит инвентаря - inventoryLimit Лимит ВХ - whLimit Freight лимит - FreightLimit Лимит продажи. - PrivateSellLimit Лимит покупки - PrivateBuyLimit Лимит гномьего крафта - DwarfRecipeLimit Лимит common крафта - CommonRecipeLimit Потребление МР физ. скилами - PhysicalMpConsumeRate Потребление МР маг. скилами - MagicalMpConsumeRate Потребление МР дансами - DanceMpConsumeRate Потребление НР - HpConsumeRate Потребление МР - MpConsume Потребление соулшотов - soulShotCount Skill Мastery - skillMastery Время пребывания под водой - breath Вроде все Любой скилл начинается с открывающего тега и заканчивается закрывающим тегом . В скилах есть 3 обязательных тега, без которых он не будет работать - это target, skilltype и operatetype. Давайте разберемся что это такое вообще 1. target - тег, который показывает на кого будет браться таргет, что видно из названия. Принимает следующие значения: TARGET_SELF - обозначает, что скилл будет использоватся исключительно на его владельца (селф бафф типа Battle Roar или War Cry) TARGET_NONE - цель неопределена TARGET_ONE- обозначает, что цель вашего скилла - тот кто в таргете. TARGET_AREA - обозначает, что скилл будет массовым TARGET_AGGREMENT - обозначает, что целью будет тот, кто вас атакует 2. skilltype - тег, указывающий на тип скилла (бафф, дебафф) Принимает следующие значения: BUFF - бафф (оказывает положительное воздействие) DEBUFF - дебафф (оказывает негативное воздействие) 3. operatetype - этот тег служит для определения типа скилла (активный либо пассивный) OP_ACTIVE - активный скилл, может быть использован игроком OP_PASSIVE - пассивный скилл, скилл с таким operateType не может быть использован (действует всегда) Это были обязательные переменные, используемые в скилах. Теперь перейдем к остальным: -power - сила скилла -hitTime - скорость. Для баффа это скорость чтения заклинания, для физ. скилла - скорость атаки -reuseDelay - откат скилла -hpconsume , mpconsume - потребление МР, НР -castRange - это дальность использования того или иного скилла (дистанция) -isMagic, isDebuff, isBuff - это наводящие теги, могут иметь значение "true" и "false". К примеру, isBuff = true (это значит что скилл является баффом) -effectRange - радиус действия (для массовых скиллов) -agro - что такое агр, и что такое сила агра думаю объяснять не нужно. Это основное что вам понадобится. Теперь расскажу вам о значении тега в скиллах. Тег в скиллах Lineage 2 встречается очень часто. Обычно данный тег используется для "добавления сложных действий" к скиллу. Если скилл имеет сложный вариант реализации то обычно в тег добавляют некоторые отдельные значения, которые реализованы в ядре ява сервера Lineage. Самый важный тег для использования здесь - это . Приведем пример использования тега и тега : <for> <effect name="тип" val="значение" time="время действия" stackOrder="переменная" stackType="переменная ядра"> </effect> </for> </skill> Что сие значит: name - Это тип эффекта val - Значение эффекта. Для дебаффов - шанс прохождения, для боевых скилов - сила. time - время действия эффекта StackOrder и stackType - это значения уже описаные в данном скиле. order и тип или же значения и переменные с ядра сервера.По скилам все вроде) Часть 4) Изменение зон: Для начала описания зон используется тег: <zone id="ID зоны" type="тип" shape="вид" minZ="минимальная Z координата" maxZ="максимальная Z координата"> <!--Комментарий--> </zone> Пройдемся по значениям: id - идентификатор зоны. type - тип зоны (town, arena, jailzone). Например: Town - мирная зона (город) Arena - боевая зона (PVP) JailZone - зона. Просто зона (извините за аллегорию ). По другому - тюрьма. В ней запрещены разговор и телепорт. shape - это форма или вид зоны. Может быть двух типов : -nPoly -Cupoid. minZ - это минимально допустимая координата высоты (z) в данной зоне . maxZ- это максимально допустимая координата высоты (z) в зоне. minZ и maxZ используются для избежания прохождения через текстуры, провалов под них и т.д. Зоне можно задать имя: Так же внутри тегов используется описание точек "респавна" чара в них. Приведем пример : <stat name="spawnX" val="X координата"/> <stat name="spawnY" val="Y координата"/> <stat name="spawnZ" val="Z координата"/> Эти координаты показывают где будет спауниться игрок находящийся в зоне. Спасибо за внимание
-
0 баллов<?php //======[ОСНОВНЫЕ НАСТРОЙКИ]====== //Префикс таблицы с IPB $prefix = ''; //Сколько тем выводить $num = 10; //Сколько символов оставить в названии темы после урезания $topic_num_sym = 65; //Имя папки с картинками текущего скина $img_path = '1'; //Формат времени $time = 'H:i'; //Форумы, которые мы не трогаем $forumexclude = '0'; //Сервер БД на котором висит база форума $host="localhost"; //Имя БД $database="имя БД"; //Логин БД $username="Логин БД"; //Пароль БД $password="Пароль"; //====[Если не знаем PHP - дальше ничего не трогаем ]========= $ipb_db = mysql_pconnect($host, $username, $password); mysql_select_db($database, $ipb_db); $rd = "SET CHARACTER SET utf8"; IF (!$result = mysql_query($rd)) { ECHO "ERROR!!!\n"; } $resultf = mysql_query("SELECT tid, title, state, posts, starter_id, last_poster_id, last_post, starter_name, last_poster_name, views, topic_hasattach FROM ".$prefix."topics WHERE (forum_id NOT IN ($forumexclude)) ORDER BY last_post DESC LIMIT $num",$ipb_db) or die(mysql_error()); $row_resultf = mysql_fetch_assoc($resultf); $totalRows_resultf = mysql_num_rows($resultf); do { $topicstrip = $row_resultf['title']; if (strlen($topicstrip) > $topic_num_sym) { $topicstrip = substr($topicstrip,0,$topic_num_sym); $topicstrip = $topicstrip."..."; } $status = ($row_resultf['state'] == "closed") ? "<img src=\"http://forum.ВАШ_САЙТ.ru/style_images/$img_path/f_closed.gif\" border=\"0\" alt=\"Тема закрыта\">" : ""; $attach = ($row_resultf['topic_hasattach'] == "1") ? "<img src=\"temp/A-Vector/images/files.gif\" border=\"0\" alt=\"В сообщении есть прикрепленные файлы\"> " : ""; $last_date = date($time,$row_resultf['last_post']); $starter_name = $row_resultf['starter_name']; $bt.= " <div class='forums'> <div class='theme_info'> <div class='theme_icon'></div> <div class='theme_title'><a href=\"http://forum.ВАШ_САЙТ.ru/index.php?showtopic=".$row_resultf['tid']."&view=getlastpost\"' title=\"".$row_resultf['description']."\" target='_blank'>$topicstrip</a></div> <div class='theme_more'><a href='/' target='_blank'>$starter_name</a> , $last_date </div> </div></div>"; } while($row_resultf = mysql_fetch_assoc($resultf)); mysql_free_result($resultf); echo $bt; return $bt; ?> ВАШ_САЙТ - Заменить на ссылку вашего сайта Создать в корне сайта файл latest_post.php добавить данный код в данный файл На странице сайте там ге хотите вывести Последние темы с форума пишем <?php include("latest_post.php");?> CSS для отображения в левой колонке сайта #left .forums_theme { width: 100%; margin: 0 auto; padding-top: 10px; } #left .forums_theme .forums { background: #211d1366; padding: 5px; position: relative; display: block; margin-bottom: 11px; } #left .forums_theme .forums { background: rgba(33, 29, 19, 0.4); padding: 5px; cursor: pointer; } #left .forums_theme .forums:hover { background: rgba(64, 63, 61, 0.4); } #left .forums_theme .forums DIV{ position: relative; } #left .forums_theme .forums .theme { height: 44px; background: url(../img/forum.png) no-repeat; padding-top: 10px; } #left .forums_theme .forums .theme_icon { width: 43px; float: left; min-height: 44px; background: url(../img/theme_icon.png) no-repeat; margin-left: 10px; margin-top: 5px; } #left .forums_theme .forums .theme_info { min-height: 40px; width: 100%; padding-bottom: 10px; } #left .forums_theme .forums .theme_title a { color: #d7d6d6; font-size: 11px; font-weight: 200; text-transform: uppercase; font-family: Tahoma, sans-serif; text-decoration: none; } #left .forums_theme .forums .theme_title a:hover { text-decoration: underline; } #left .forums_theme .forums .theme_title { padding: 7px; text-align: left; left: 10px; } #left .forums_theme .forums .theme_more { color: #847411; font-size: 10px; font-weight: 200; text-align: left; left: 10px; text-transform: uppercase; font-family: Tahoma, sans-serif; text-decoration: none; } #left .forums_theme .forums .theme_more a { color: #fab91a; }
-
0 балловhttps://youtu.be/rvH_IK95pOE
-
-1 балл