Search the Community
Showing results for tags 'aionemu'.
-
Многим известно, что шанс отразить магическую атаку равен: шанс % = (маг. защита цели - маг. точность атакующего)/10 почти верно), но есть ньюансы Оригинальная формула выглядит так: int resistChance = (int) ((float)((int) ((float)((targetMagResist - attackerHitAcc) * 1) + magResistLvlAdj)); if (resistChance > 900) { resistChance = 900; } else if (resistChance < 0) { resistChance = 0; } return RandomUtil.getIntInRange(1, 1000) > resistChance; Как видно из формулы шанс отразить маг атаку не может превышать 90% Но самое интересно здесь это разница в уровне, при чём оно не зависит игрок или НПС int lvlDiff = target.getCreatureStats().getLevel() - attacker.getCreatureStats().getLevel(); if (4 < lvlDiff) { return (lvlDiff - 4) * 100; } if (lvlDiff < -4) { return (lvlDiff + 4) * 100; } return 0; Так же не стоит забывать, что если цель игрок, то точность атакующего меняется следующим образом if (attacker instanceof Player) { attackerHitAcc += hitAccMod; } где hitAccMod - это мод который прописан в скилах <effect_acc_mod1/2>
-
Пакет CM_CASTSPELL в конце имеет 4 байта недочитанного буфера Пример: 65a20000 Это checkSum скила, основанного на: move_casting charging_delay motion_name motion_play_speed no_jump_cancel При определённой формуле вычисляется чек-сумма, и сравнивается с тем, что присылает клиент. На основе этого можно делать защиты от "подмены" скилов... Формулу не выложу, но чек-сумму могу скинуть на любую версию)))
-
Итак) самая незаконченная тема разработки эмулятора aion это motion_time Как оказалось всё гораздо проще чем на самом деле казалось! Из клиента берутся следующие файлыСкрытый контент.Далее) В файле client_skills.xml есть атрибут motion_name пример: <motion_name>spindash</motion_name> Так вот, берём это значение добавляемСкрытый контент.Благодарности принимаю в виде пожертвований в "фонд рукожопых программистов"))
-
Клиент Сервер
-
Тема для размышлений. То есть тут публикуется какая-то идея, частично и полностью реализована в моих работах. Ни чего из ниже описано не будет выпущено в открытый доступ. Новое сетевое ядро основано на фреймворке Netty последней версии. Пример на логин сервере. Под капотом netty конечно же nio, но всю обработку он берет на себя. Код становится лаконичнее и приятнее. Обо всех преимуществах netty вы можете почитать на просторах гугла), но из особенностей можно выделить полный контроль на сетью, и дополнительные плюшки при запуске сервера на linux машинках. Пример код: public class NettyServer { private static NettyServer INSTANCE; private NettyServer() throws Exception { runServer(MainConfig.LOGIN_BIND_ADDRESS, MainConfig.LOGIN_PORT); } public static NettyServer getInstance() throws Exception { if (INSTANCE == null) { INSTANCE = new NettyServer(); } return INSTANCE; } private static final EventLoopGroup bossGroup = new NioEventLoopGroup(); private static final EventLoopGroup workerGroup = new NioEventLoopGroup(); private static ChannelFuture runServer(String ip, int port) throws Exception { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new ClientChannelHandler()); } }); ChannelFuture f = b.bind(ip, port).sync(); return f; } } Все обработки происходят в классе ClientChannelHandler, и всё. То есть читаете пакет и по op коду уже отправляете в нужное русло. Никаких вспомогательных классов, такие как Dispatcher и т.д. не нужно. То есть вот это всё уже просто удаляется, не считая того, что в самом Логин сервере. Тесты производительности будут позже, как только откроется сервер на основе этого ядра. Но пока можно ощутить стабильность пинга при большой сетевой активности. Пример когда вокруг много мобов, и тебя бьют порядка 10 мобов. В этот момент происходит огромный спам пактов SM_MOVE, SM_ATACK, SM_SPELL и так далее. Пример когда вокруг нет никого, и сетевые пакеты почти не активны.