Если хотите разозлить программиста, покажите ему эту картинку

Я не программист, но даже меня немного коробит. ))
Я не программист, но даже меня немного коробит. ))
Привет. Я продолжаю разрабатывать сервер для Lineage 2 C1 на JavaScript Проект
Продолжая работать над скилами, заметил, что некоторые атакующие скилы можно направить на себя.
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Привет. Я продолжаю разрабатывать сервер для Lineage 2 C1 на JavaScript Проект
В первом же квесте Fighter's Tutorial (даёт SP и карту мира) столкнулся с любопытным моментом. Охота на внешне одинаковых NPC, но на деле разных!
Речь пойдет только о квесте для людей на острове Talking Island Village.
В чём подвох?
В мире Lineage есть два NPC с одинаковым именем - Bearded Keltir.
Внутри сервера это разные NPC: ID 12082(tuto_keltir) и ID 481(keltir).
По квесту Fighter's Tutorial надо добыть Keltir Fang.
Убивайте Bearded Keltir, пока не получите Keltir Fang x4.
Как различать Bearded Keltir?
У этих NPC есть несколько зон spawn'a. Некоторые зоны пересекаются и в одной зоне могут находиться разные Bearded Keltir.
Так например если вы решите проходить квест возле Talking Island Village то вот на что надо обратить внимание:
* Keltir Fang падает с шансом в 100%. Если не упал, то вы убили не того NPC.
* С нужного Bearded Keltir не падает дроп. Дроп у ID 12082(tuto_keltir) отсутствует.
Вывод
Лучше всего проходить квест возле Cedric's Training Hall так как там одна из зон появления Bearded Keltir они же ID 12082(tuto_keltir).
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Привет. Я продолжаю разрабатывать сервер для Lineage 2 C1 на JavaScript Проект
При добавлении SoulShot функционала не добавил проверку не только на наличие оружия, но и кто атакует — игрок или NPC. Как итог теперь все атакуют с помощью SoulShot.
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Привет. Я продолжаю разрабатывать сервер для Lineage 2 C1 на JavaScript Проект
Копаясь в серверных файлах наткнулся на пасхалку.
На острове Talking Island Village в храме Einhasad есть два NPC, которые стоят рядом друг с другом и имеют имена Harrys и Petron.
У каждого NPC на сервере есть цифровой ID и текстовый ID.
Так, например, для Harrys(ID 7035) его текстовый ID - Harry, а для Petron(ID 7036) - Potter
Таким образом, если сложить их ID, получится - Harry Potter
npc_beginguild_coach7035[harry]level=70...npc_end
npc_begin
guild_coach
7036
[potter]
level=70
...
npc_end
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Привет. Я продолжаю разрабатывать сервер для Lineage 2 C1 на JavaScript Проект
Хорошие новости: Теперь сервер не грузит всех NPC подряд, а только тех, кто рядом с игроком. Это значит:
* Меньше лагов – сервер не тратит силы на то, что далеко от игрока.
* Плавнее игра – особенно в городах и массовых сражениях.
* Стабильнее мир – больше NPC вокруг, но без нагрузки на клиент.
Как работает VisibilityManager?
Представьте радар на подлодке – он сканирует пространство вокруг и засекает только то, что действительно рядом.
* Каждые 3 секунды система проверяет, какие NPC или игроки находятся в зоне видимости.
* Неважно, кто к кому подходит – хоть игрок к мобу, хоть моб к игроку, если он в радиусе, сервер его "увидит" и сообщит игроку.
* Всё лишнее – выгружается – зачем держать в памяти то, что далеко и не влияет на игру?
Итог:
* Меньше тормозов – клиент не грузит 3D-модели тех NPC, которых игрок не видит.
* Экономия трафика – сервер не отправляет игроку данные о мобах на другом конце карты.
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
У проекта появилась чёткая архитектура управления сущностями. Теперь NPC, игроки, питомцы и другие объекты взаимодействуют в мире через систему менеджеров — рассказываю, как это работает.
В игровом мире есть разные типы сущностей: NPC, игроки (Player), питомцы (Pet) и другие. Каждая из них имеет свои состояния (движение, атака, бездействие) и требует управления.
Основные сущности и их поведение
• NPC – управляет собой (перемещение, атака, idle).
• Player – управляется игроком (те же состояния: ходьба, атака и т. д.).
• Pet – похож на NPC, но принадлежит игроку.
Менеджеры и их задачи
1. NpcManager – создаёт NPC, реагирует в случае смерти NPC.
2. PlayersManager – отвечает за вход игроков в мир.
3. PetsManager – управляет питомцами (аналогично NPC, но с привязкой к игроку).
4. EntitiesManager – главный координатор:
o Управляет NpcManager и PlayersManager.
o Обрабатывает взаимодействия (например, если игрок подошёл к NPC, оба получают информацию друг о друге).
5. VisibilityManager – отвечает за видимость объектов:
o Определяет, кто кого видит.
o Периодически обновляет списки видимости для оптимизации.
6. MovingManager – обновляет позиции всех подвижных объектов в мире.
Зачем это нужно?
Такая система позволяет:
• Эффективно управлять сотнями сущностей.
• Оптимизировать обновление состояний (движение, видимость, атака).
• Гибко добавлять новые типы объектов (монстры, питомцы, NPC-торговцы).
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Меня достаточно долгое время раздражала нелогичная скругленность интерфейса сайта. Несмотря на то, что так сейчас делают везде, это модно и соответствует передовым принципам дизайностроения, я остаюсь фанатом Windows 8/старых версий Windows 10/Dear ImGui в плане дизайна, с их идеально острыми углами. Некоторым извращенцам еще Windows Phone нравился. Плюс квадратность рож вомбатов определенно намекает, что рожа сайта тоже должна быть квадратной.
Помимо этого были обозначены дополнительные функции: скачивание видео и поиск по тегу. Они есть в TODO сайта и де-факто это можно делать вручную, но неудобно и не все знают/могут.
Первый день начался с... создания нового скрипта GreaseMonkey, вспоминания основ CSS и установки радиуса скругления на всех элементах страницы в 0. Сделано это было довольно быстро, после чего к основным блокам были добавлены рамки. Результат получился довольно неплохим (субъективно), хотя и не без проблем. Круговой индикатор загрузки превратился в 2 шпалы, решил не исправлять. Напоминает предыдущую итерацию дизайна Pikabu (2020) до скругления и удаления рамок.
Следующие две ночи я провел в попытках отследить все видео на странице и окна поиска. Получилось крайне колхозно и ненадежно (вероятно сломается при следующем обновлении), но оно работает. Зато загрузка видео выглядит так, как будто это родная функция. Еще нажатием с Alt можно скопировать прямую ссылку, хотя этого лучше избегать из-за возможного перемещения адреса сервера.
Поиск по тегу помимо уродского дизайна не учитывает одну большую проблему: теги регистрозависимые. То есть "кот" и "Кот" приведут к разным результатам, а еще "вомбат шаббат" и "вомбатшаббат". Решить с клиентской части это невозможно, а с серверной все равно создает много проблем и единственным вариантом я вижу слияние одинаковых тегов в разных регистрах и создание команды модераторов, которые будут приводить теги к единообразию. Но это уже не моя компетенция, в остальном поиск по тегу работает как и должен.
Меню настроек было написано в промежутке с 3 до 6 утра сегодняшнего дня, не вижу смысла заострять внимание. Почему разработчики GreaseMonkey не сделали нормальных штатных функций для этого - ХЗ.
Скачать или полюбоваться на чудеса говнокодостроения можно здесь. Требуется любой менеджер скриптов по вкусу (TamperMonkey (я использую его), GreaseMonkey, ViolentMonkey, т.д.). Chrome умеет устанавливать скрипты как расширения, но у меня используются специфичные функции, которые им напрямую не поддерживаются.
Просьба Он писался человеком, который впервые увидел JS и CSS3 после одиночного знакомства с CSS2 и HTML4 много лет назад. Плюс оно работает, а остальное уже не так важно (есть косяк с тем, что скрипт загружается раньше React и сбивает его с толку, но на работоспособность это вроде не влияет). Еще он должен работать в мобильном Firefox, но я не тестировал. Но поиск по тегам работать точно не будет, исправлю в следующей версии.сильно не бить за качество кода.
Активно поддерживать не обещаю (С), но пока я буду пользоваться сайтом, скрипт должен обновляться. Идеи по новым функциям, исправления или баги можно озвучить в комментариях
Помните как мы бегали по горам и не придавали значение тому как быстро спускались или поднимались на них?
Как мы знаем в реальной жизни перемещаясь на плоскости горизонтальная скорость у нас постоянная. Как только мы начинаем преодолевать горы и другие неровности то горизонтальная скорость у нас будет меньше. Но не в мире Lineage 2 где горизонтальная скорость всегда постоянная и нее зависит от неровностей. Связанно это с тем чтобы было проще синхронизировать персонажа на сервере и клиенте. Ведь на сервере нет точной модели мира, а лишь примерное очертание называемое geodata. А из-за того, что geodata приблизительно повторяет ландшафт клиента то было бы невозможно синхронизировать персонажа по Z оси. Поэтому синхронизация идет только по X и Y оси.
Видео:
1) Горизонтальная скорость на плоскости постоянная.
2) Как было бы в жизни. Взбираясь на гору горизонтальная скорость падает.
3) Как сделано в игре. Горизонтальная скорость постоянная.
4) Демонстрация из игры. Бежит словно нет никаких гор.
Блог про разработку сервера для Lineage 2 в телеге https://t.me/lineage2js
Я до этого выпускал курс «Python для тупых», многим такой формат понравился. Думаю пройтись по всем популярным языкам так — разжёвывать, давать простые задачки с решениями. В этот раз часть задачек с решениями будут платными, чтобы мне больше мотивации было не забросить.
Вообще этот курс должен был бы называться «...для чайников», «...для начинающих», но слишком много курсов, которые называются так, а на деле совсем не для чайников или начинающих.
В общем, если есть кто знакомый, кто осилил HTML/CSS, а в JavaScript совсем въехать не получатся, то вот оно.
Видео будут долгими, нудными, с повторениями одно по одному несколько раз, в каждом материала будет немного с точки зрения профессионала. И не будет монтажа. Местами будут даже ошибки и оговорки, но они в следующих видео будут закрываться. Чтобы ориентироваться в них, тайм-коды ниже. А вот ссылки на задачи и решения к первому занятию:
Тайм-коды из видео
00:00 Всё мне ясно стало теперь 00:12 Что за курс, для кого и как организован 3:15 Кто я, мой опыт преподавания и создания курсов 5:40 Первый проект на JS 10:04 Теоретическое объяснение 19:20 Второй проект — скрипт отдельно 26:19 Третий проект — больше кнопок и абзацев
Для тех, кто Ютуб не может смотреть, вот вам ВК-шечка:
Привет.
Я разрабатываю эмулятор сервера для Lineage 2 Chronicle 1: Harbingers of war на Node.js.
Столкнулся с проблемой синхронизации скорости персонажа на сервере с клиентом. Когда в игре вы нажимаете мышкой в то место, куда хотите перейти то происходит плавный переход с анимацией движения. На сервере в этот момент тоже происходит движение по таймеру, но не такое плавное.
Для примера я взял сборку написанную на java l2j-lisvus Сборок много. Но все они являются fork’ами проекта l2jserver https://l2jserver.com/И многое наследуется. В том числе и передвижение персонажа.
В l2j-lisvus, как и во всех сборках l2jserver перемещение персонажа на сервере идет при помощи таймера с приростом одинаковых значений.
Проблема проявляется, когда нам надо сделать какое-то действие после того, как персонаж добежал до пункта назначения. Например, нанести удар по NPC.
Как работает передвижение персонажа на сервере.
За основу взяты базовые характеристики персонажа. Скорость бега 126.
На данной схеме идет прирост координат персонажа каждые 1000мс на 126 unit’ов. Исходя из схемы выше пример кода для действий персонажем после достижения пункта назначения:
// Прироста координат нет. Просто считаем когда персонаж дойдет до конечных координат.
const distance = 1500;
const playerSpeed = 126;
const ticks = distance / playerSpeed; // 11.90
const time = ticks * 1000; // 11900mc
setTimeout(() => {
// действие персонажа после бега
}, time);
Зеленой зоной показана точка куда должна ступить нога персонажа если бы не было расхождений.
Рост скорости при развитии персонажа.
126 — это базовая скорость. И по мере развития персонажа будет расти и скорость передвижения. А значит расхождение будет больше. Но перед тем, как создать формулу надо подтвердить теорию, что скорость ходьбы влияет на расхождение.
Данные о характеристиках персонажа передаются от сервера к клиенту.
Пакет UserInfo.js 83 строчка.
writeD(player.runSpeed);
writeD(player.walkSpeed);
Базовые значения:
runSpeed: 126
walkSpeed: 88
Выставляю значения walkSpeed: 126. Если скорость ходьбы будет равна скорости бега, то расхождения должны пропасть.
Персонаж синхронизирован и начинает атаку вовремя. Теперь надо понять, как скорость ходьбы влияет на расхождения между клиентом и сервером.
Сколько же персонаж успевает пройти перед тем, как начинает бежать?
Надо поймать момент когда ходьба переходит в бег. Для этого передадим в клиент данные, где скорость ходьбы будет больше скорости бега. Из-за этой разницы будет виден переход и можно будет рассчитать пройденное расстояние при ходьбе.
runSpeed: 10
walkSpeed: 600
При скорости шага в 600 персонаж успевает пройти 250, прежде чем начинает бежать.
600 / 250 = 2.4
700 / 291 = 2.4
800 / 333 = 2.4
Из этого вывод, что персонаж перед тем, как начать бежать успевает пройти расстояние в 2.4 раза меньше, чем его скорость ходьбы.
Значит при скорости ходьбы 88 персонаж пройдет 36 unit’ов.
88 / 2.4 = 36
Решение
Формула для расчета времени:
сколько_прошли_на_старте = скорость_ходьбы / 2.4
(((дистанция_между_нпц_и_игроком - сколько_прошли_на_старте) / скорость_бега) * 1000мс) + время_которое_прошли
Для примера дистанция 1500.
Из них мы 36 прошли.
1500 - 36 = 1464 расстояние для бега.
Скорость бега 126 в секунду.
1464 / 126 = 11.61 (количество отрезков, которое мы пройдем за секунду).
11.61 * 1000 = 11610мс бега.
к 11610 надо прибавить время ходьбы
Скорость ходьбы 88 в секунду.
1000 / 88 = 11.36мс за 1 unit
36 unit * 11.36мс = 408мс
11610 + 408 = 12018мс
12018мс является точным временем от начала старта и до конца.
Сравниваем со старым временем 11900мс. Разница в 118мс.
setTimeout(() => {
player.attack(npc);
}, 12018);
Как видно выше разница положения ног при разных скоростях отсутствует, а значит решение работает.
Ссылка на проект: https://github.com/lineage2js
Ссылка на блог: https://t.me/lineage2js
Привет.
Занимаюсь разработкой сервера для Lineage 2 C1 на JavaScript(Node.js). Копался в клиенте игры и решил сделать перебор всего оружия для теста.
Ссылка на проект: https://github.com/lineage2js
Ссылка на блог: https://t.me/lineage2js
Решил немного попробовать себя в авторском контенте, а за одно и рассказать о своём видении расширений для браузера.
Многие из нас знакомы с расширениями(плагинами) для браузеров которыми они пользуются, в основном это блокировщики рекламы, вроде Адблока или Юблока. В наше время, как по мне блокировщик рекламы в браузере, это прям вещь необходимая, так как я лично на многие сайты просто зайти не могу без морального потрясения когда нет блокировщика. Серьёзно! Я понимаю что владелец сайта хочет заработать, но некоторый типа фандома, откровенно жадничают, количество рекламных блоков просто зашкаливает! Но суть не в этом.
Что такое вообще расширение для браузера? В примитиве это небольшой скрипт который производит некие манипуляции на странице сайта. В случае адблока, скрипт пробегает по странице сайта и скрывает все блоки которые в его "списке" помечены как рекламные.
Есть более сложные расширения такие как ВПН, которые взаимодействуют не просто со страницей, а уже с настройками браузера и т.д., но речь сегодня не о них.
Мне больше нравится сама идея того что есть возможность расширить или модифицировать свой браузер эдаким изящным апплетом.
Например когда на ютюбе скрыли дизлайки, некто написал расширение которое при загрузке страницы улавливает параметр количества дизлайков ил "потрохов" сайта и не смотря на то что администрация ютюба это дело скрыла, плагин сам генерирует кусочек html кода и через JavaScript вставляет его в нужное место!
В этом мне нравится сама идея избавления от каких то идей которые нам хочет так или иначе навязать администрация сайта! (Цифровая диктатура как сейчас модно говорить)
Самое простое что можно сделать через расширения это скорректировать дизайн того или иного сайта под себя (или сразу всех), создать какую то свою интересную тему. Например заменить общий фон тела страницы на какой то узор, и сделать цвет текста мягче.
Работа расширений как и их создание (и размещение) очень просты, всем управляет JavaScript, а какие то вещи вроде меню настроек которые открываются при нажатии на его иконку, это просто небольшая html страничка.
По сути расширение это такая папочка с файлами, которая в случае firefox запаковывается в zip, после чего расширение у файла с zip меняется xpi и расширение готово к установке в браузер. В случае с браузерами на движке Chromium (chrome,opera,eadge,yandex e.t.c.) ничего запаковывать и вовсе не нужно, в настройках можно выбрать установку расширения из папки.
А что в папке?
Во первых файл manifest.json - это грубо говоря "паспорт" расширения, документ в котором написано, что это за расширение, кем создано, какая версия, какая у него иконка стоит, какие оно запрашивает разрешения у браузера (например возможность работать как раз с контентом страницы), указания того что за страничка будет открываться при нажатии на иконку, а так же указание какой скрипт нужно выполнять на сайтах при работе.
Далее естественно сама страничка index.html - которая показывается при нажатии на иконку, там обычно размещают какие то настройки, переключатели состояния. Это все легко верстается на html тэгах, а стили задаются в отдельному css файлике, ну или если лень то прям среди html тэгов.
Ну и раз есть настройки то нажатие на них нужно как то регистрировать? Здесь нам поможет файлик main.js - в котором мы пропишем логику того что будет происходить когда пользователь нажимает например на наши кнопочки в меню. Грубо говоря там будут инструкции в стиле "нажал на кнопку > происходит следующее"
И если мы пишем расширение которое работает с чем то на открытых нами сайтах то и скрипт background.js - в котором будут уже инструкции о том что будет расширение делать на открытых нами сайтах.
Так же тут находятся сопутствующие папочки вроде img или icons где у нас лежат какие то изображения и графика которую мы используем и иконка самого расширения.
по итогу у нас получается примерно такая вот структура:
Как это работает: человек кликает на иконку приложения в шапке окна браузера, ему показывается index.html в котором какие то настройки, при клике по настройкам файл main.js их обрабатывает, например сохраняет их значение в память браузера. А далее файл background.js который запускается на каждом открытом нами сайте, в начале получает из памяти браузера настройки которые натыкал пользователь, а затем на их основе проводит какие то манипуляции, например заменяет все изображения на странице на фото Николаса Кейджа, с той прической которая похожа на птицу.
Самое интересное для меня что в теории любой может на досуге попробовать в плане "поиграть", написать что то подобное для себя. В сети полно бесплатных мануалов и уроков, да и сейчас тот же chatGpt если задавать правильные вопросы может наглядно показывать подробные примеры кода и объяснять их работу.
Я постарался максимально простым языком описать работу расширений, без лишней терминологии что бы любой заинтересованный (надеюсь) смог примерно понять как это работает)
Надеюсь было интересно, за ошибки прошу прощения, я больше по части языков на котором говорят машины😁
Привет, с вами самый неспешный преподаватель программирования Вячеслав Романьков.
Во-первых, пока по подпрограммам (функциям) всё, три видео:
https://youtube.com/playlist?list=PLmn7h9eyDeMMCBonuyVVD8Llg...
Стримы по основам ООП в Python «для тупых» уже есть видео, продолжим наши стримы-вебинары по этой теме в этот четверг, 20:15 по московскому времени, а пока вот уже записанное:
https://youtube.com/playlist?list=PLmn7h9eyDeMPDX-7Sq7SCp7kT...
Кстати, предлагаю всем бесплатную диагностику по программированию — как взрослым, так и детям:
- люди, кто вообще с программированием не имел дела
- люди, кто думают, что программирование не для них
- люди, которые уже обучаются какое-то время, но упёрлись в потолок и хотят понять, из-за чего
- дети, которые не знакомы с программированием
- дети, которые «гуманитарии», «творческие люди» и программирование не для них — покажу, что для таких людей уже тоже есть полезные программируемые технологии
- дети, которые где-то учатся, и родители хотели бы стороннюю экспертизу — «А они там вообще чему-то учатся?»
- и т.д. и т.п.
Длится онлайн, 30-60 минут. Какие-то вещи нужно рассказать и подготовить заранее. Кому интересно, пишите.
На волне этого верну тему обучения программированию детей, довольно интересные открытия и наблюдения накопились.
Планирую курс «JavaScript „как для тупых“», так же основы, но понятно, на пальцах и с практическими примерами доступными. Будет он для тех, кто уже HTML и CSS изучил более-менее, но никак не может понять, как с помощью JavaScript управлять данными в HTML. Будет ещё более поверхностным, но «движок заведётся», что-то уже в голове уляжется и кое-что сможете делать.
По Python уже многое в формате «Для тупых» рассказано, допубликую пару материалов, думаю выпустить курс для тех, кто уже отзанимался, о типичных пробелах в знаниях, умениях и навыках уже продолжающих обучение. Будет о том, как их проверить и исправить. Курс основной, с домашними заданиями и т.д. — не знаю пока, застрял на заданиях к одной из тем, тема важная, не хочется выпускать то, что по моему мнению не очень, хочется вау-задания с решениями дать.
На этом пока всё, до связи. Оптимистично верю, что раньше, чем ещё через три месяца :-)
Дело было вечером, делать было нечего. Наткнулся на статью, где описывался алгоритм построения треугольника Серпинского, и решил реализовать и максимально сжать.
Создать файл html и вставить туда код:
<canvas id=c><script>a=[],s=400,t=0,u=3,M=Math;for(i=-0.5;i<u;))}e=document.getElementById("c");e.width=e.height=2*s;c=e.getContext("2d");c.beginPath();a.forEach(q=>c.lineTo(q.x,q.y));c.stroke();q=()=>a[M.round(M.random()*u)],v=(a,b)=>b+(a-b)/(u-1),p=q(),e.onclick=n=()=>;c.fillRect(p.x,p.y,1,1)})};n()</script>
u - количество углов (можно увеличить)
при нажатии анимация останавливается и восстанавливается.
Уменьшить размер не потеряв функциональность пока не получилось