PDA

Просмотр полной версии : Надеюсь на помощь


Deffol
08.06.2011, 01:13
Приветствую, в общем в игре есть серии ударов, то есть если один скилл кастуешь, после него можно кастовать другим из этой серии...
Я решил сделать, чтоб самому не жать на серию, так, чтоб при посылке скила из первой серии, сразу посылался скилл из второй серии ударов!
Но у меня появилась проблема, вот допустим 1 скил на разных мобах:
('CF 57 6C 50 05 09 00 51 B8 1E 00 9B 02 05 E9 00 00')
('CF 57 6C 50 05 09 00 CE 93 1E 00 9B 02 05 E9 00 00')
первые 9 пар байтов - это ID скилла, после него идет ID моба, там еще что-то в пакете после ID моба, я не разобрался, но в принципе оно не нужно
Если послать только ID скилла, то на любом мобе он сработает нормально.
Вот я не знаю как при посылке скилла на разных мобах, объяснить скрипту, чтоб он ловил только ID скилла, ну а потом посылал бы ID другого скила, как послать я разберусь!
Подскажите какой командой ловить ID скилла, то есть первые 9 пар байтов

Добавлено через 26 минут
вот я сам попробовал:

begin
if FromClient and (pck[1]=#$CF) and (ReadH(4)=1360) then
begin
buf:=HStr('CF 57 6C 61 06 01 00');
SendToServer;
end;
end.

Вроде работает, может его можно чем то дополнить, или так оставить?

Добавлено через 18 минут
у меня почему-то 2й пакеот отправляется быстрей чем первый, как сделать, чтоб поочереди они шли?

Добавлено через 39 минут
в принципе, после того как идет чтение 2х байтов скила, можно послать этот же скил, затем тот, который дальше по серии, это будет правильно или можно проще сделать?

Вот скрипт:

begin
if FromClient and (pck[1]=#$CF) and (ReadH(4)=1360) then
begin
buf:=HStr('CF 57 6C 50 05 09 00');
SendToServer;
buf:=HStr('CF 57 6C 56 05 09 00');
SendToServer;
end;
end.

Добавлено через 1 час 6 минут
после каста скилла который читается с помощью Read, идет пакет на этот же скилл, это правильно? просто вроде на сервер посылается инфа о том, что я начал каст, а ним же опять посылается вроде этот пакет...я еще не проверял. Но если посылается 2 пакета на 1 скилл, можно сделать так, чтоб после Read, посылался 1й скилл, а потом уже 2й...а то палевно, что сначала у меня идет скилл второй по серии, а потом уже первый... и не хочется, чтоб на 1 скилл посылалось 2 пакета

SeregaZ
08.06.2011, 02:22
посылка 2-3-10 пакетов по идее не страшна, так как сервер должен думать, что ты зажал кнопку скила с панели и удерживаешь её.

я правда не совсем понял что именно ты спрашиваешь :)

Deffol
08.06.2011, 02:45
ну во первых, хочу спросить, верный ли скрипт... :)
и можно ли, чтоб после чтения первого скилла, он сначала послался, а потом бы уже посылался мой второй пакет?

Kilatif
08.06.2011, 02:48
Что бы отправить сначала отловленный пакет, а затем свой просто сделай так:
...
buf := pck;
SendToServer;

buf := //что-то чем ты его заполняешь
SendToServer;
...

Deffol
08.06.2011, 04:56
о спасибо))) блин, до самого скрипта додумался, а до этого нет!!

Deffol
16.06.2011, 22:02
привет всем еще раз, сегодня решил усовершенствовать свой скрипт.
в общем поиграл я так и решил, что палевно...по крайней мере палевно по логам, то есть видно в них время в которое приходил удар, а так как на сервер идет инфа так быстро как позволит комп, то в логах показывает что удары летят вплоть ( в плоть ) в одну милисикунду почти :) не суть..
Решил я сделать таймер, я пока его не сделал, но я осилю)) но вот я могу делать таймер только на одну серию скилов, а у меня скилов много!
можно ли в одном скрипте реализовать несколько серий ударов, которые вызываются разными пакетами?
например 3 пакета в каждой серии, мне надо чтоб таймер включался на каждую серию именно по конкретному пакету, чтоб не все вместе юзались :) возможно так??

Добавлено через 27 минут
вот наглядно таймер со скилами
const
name='Deffol';
var
Timer:TTimer;
TimerMyPck:byte;
procedure Init;
begin
TimerMyPck:=1;
Timer:=TTimer.Create(nil);
Timer.OnTimer:=@OnTimer;
Timer.enabled:=false;
Timer.interval:=1;
end;

procedure Free;
begin
Timer.free;
end;

procedure OnTimer(Sender: TObject);
begin
case TimerMyPck of
1:
begin
buf:=HStr(''); //первый скил в серии
SendToServer;
Inc(TimerMyPck);
end;
2:
begin
buf:=Hstr(''); //второй
SendToServer;
Inc(TimerMyPck);
end;
3:
begin
buf:=HStr(''); //третий
SendToServer;
Timer.interval:=1; //не придумал еще время
end;
end;
end;

begin
//первый скил в серии
if FromClient and (pck[1]=#$CF) and (ReadH(4)=123) and (ConnectName=name) then
Timer.enabled:=true;
Timer.enabled:=false;
end.
ну так вот такие таймеры например мне на 3 скила, всего 3 таймера, а я хочу совместить их, чтоб места не занимали, а то у мну этих скриптов...я уже в них запутался :)

Добавлено через 6 минут
сорь забыл в процедуре таймера Ex(name) в посылку добавить, ну это не суть :)

NLObP
17.06.2011, 16:21
например 3 пакета в каждой серии, мне надо чтоб таймер включался на каждую серию именно по конкретному пакету, чтоб не все вместе юзались возможно так??

Каждую серию в отдельный таймер засунь. И проверки сделай чтобы одновременно не запускались.

Deffol
17.06.2011, 17:41
на счет отдельного таймера я осилю, не смотрите что скрипт кривой, я для наглядности писал :)
а как сделать проверку?

SeregaZ
17.06.2011, 23:51
эм... я бы наверное сделал фиксацию времени использования последнего скила, потом при срабатывании таймера сравнение текущего времени с тем, которое время срабатывания. и если разница получится меньше 2 секунд к примеру, то чтобы скилы не стартанули.

Deffol
20.06.2011, 18:46
привет все еще раз!
помогите со скриптом. в общем у меня таймер, мне надо, чтоб когда приходил пакет типа #$2E активировался таймер и главное, чтоб с этого пакета как то взять 4 байта в середине, и засунуло их в отправку пакета уже в таймере который :)
вот например пакет:
2E 54 CD 85 7B BD 44 CD D4 EF 44 27 B1 78 43 B5 D0 18 00 00 00 00 00 37 1E 06 00 01 00 2F A2 B6 0A 00 00 00 00 00 00 00 64
Каждый раз он меняется, но это не важно, мне нужен ID таргета, который обозначен красным и вставить этот ИД вот сюда:
B5 57 72 xx xx xx xx
в таймере я разберусь, помогите с тем, как реализовать эту вставку ID таргета

Breadfan
20.06.2011, 20:49
............
_var:integer;
..................
if fromserver and (pck[1]=#$2E) then begin
_var:=ReadD(16);//если с сервера пакет 2Е, то - считали dword значение с 16ой позиции
timer.enabled:=true;//включить таймер;
end;
..........................................
//в таймере:
buf:=hstr('B5 57 72'); //в буф - начало требуемого пакета
WriteD(_var); //к находящемуся в буф - дописать ранее считаное значение
Sendtoserver;//отправить
..................

Deffol
20.06.2011, 21:18
блин, спасибо огромное :) ваще...я свой скриптовый бот написал на айон по сбору ресов почти :D

Добавлено через 20 минут
а он разве не сохранит весь пакет с 16й позиции? ведь нигде не обозначено что мне нужно именно 4 байта следующие и все

Breadfan
20.06.2011, 21:43
ReadD - указывает что читать - 4 байта.
ReadC - 1, ReadH - 2

wimax
21.06.2011, 08:20
интересно у человека паметь отшибло?))
http://coderx.ru/showpost.php?p=162964&postcount=1757

Deffol
21.06.2011, 12:00
нет, просто тогда я имел ввиду, изменить полностью вид пакета, зашифровать его допустим, а при отправке чтоб пнх его посылал в нормальном виде. вот у меня и осталась ассоциация другая на тот вопрос :) спасибо, что ткнул

Deffol
23.06.2011, 19:03
Здрасте еще раз :)
помогите))

не могу понять как сделать блокировку пакета, по команде
в общем на сервер идет один пакет, я хочу его блокировать например по слову в чат
потом когда мне надо, написать так же в чат, чтоб этот пакет больше не блокировался
подскажите как сделать):)

Breadfan
23.06.2011, 19:30
var
blocked:boolean;
........
procedure init;
blocked:=false;
........
if (команда в чат на блок) then blocked:=true;
if (команда в чат на разблок) then blocked:=false;
if fromclient and (какой там нужно пакет блокировать) and blocked then pck:='';

Deffol
25.06.2011, 18:28
хочу спросить на счет скрипта который на 1й странице, в общем когда выполняю скрипт, и бью скилом все нормально, безупречно отрабатывает, когда 2й раз бью скилом посылается пакет последний в таймере, то есть 1, 2 не посылаются. только тот который активируется и последний

const
name = 'Deffol';
var
Timer:TTimer;
TimerStep:integer;

procedure Init;
begin
TimerStep:=1;
Timer:=TTimer.Create(nil);
Timer.OnTimer:=@OnTimer;
Timer.enabled:=false;
Timer.interval:=400;
end;

procedure Free;
begin
Timer.free;
end;

procedure OnTimer(Sender: TObject);
begin
case TimerStep of
1:
begin
buf:=HStr('CF 57 6C 5C 03'); //Удар зверя III
SendToServerEx(name);
Inc(TimerStep);
end;
2:
begin
buf:=HStr('CF 57 6C 51 03'); //Бросок зверя I
SendToServerEx(name);
Inc(TimerStep);
end;
3:
begin
buf:=HStr('CF 57 6C 39 08'); //Чудовищный шрам III
SendToServerEx(name);
Timer.interval:=500;
Timer.enabled:=false;
end;
end;
end;

begin
if FromClient and (pck[1]=#$CF) and (ReadH(4)=875) and (ConnectName=name) then
Timer.enabled:=true;
end.

не могу понять в чем причина, думаю в том, что я таймер не правильно выключаю

//Breadfan: попробуй так: procedure OnTimer(Sender: TObject);
begin
case TimerStep of
3:
begin
buf:=HStr('CF 57 6C 39 08'); //Чудовищный шрам III
SendToServerEx(name);
Timer.interval:=500;
Timer.enabled:=false;
Inc(TimerStep);
end;
2:
begin
buf:=HStr('CF 57 6C 51 03'); //Бросок зверя I
SendToServerEx(name);
Inc(TimerStep);
end;
1:
begin
buf:=HStr('CF 57 6C 5C 03'); //Удар зверя III
SendToServerEx(name);
Inc(TimerStep);
end;
end;
If (TimerStep=4) then TimerStep:=1;
end;

Добавлено через 13 часов 52 минуты
пасиб :) а ничего, что я вернул степ на первое место после последнего пакета, вот так:

buf:=HStr('CF 57 6C 39 08'); //Чудовищный шрам III
SendToServerEx(Connectname);
Step:=1;


и еще я заметил, что таймер который обозначен в процедур инит, работает на весь скрипт, не смотря на то, что у меня внутри таймера еще один интервал обозначен, сначала думал показалось потом проверил и правда так

Добавлено через 13 минут
даже точней, первый раз работает первый интервал, в след раз всегда работает только последний интервал, а я хочу, чтоб таймер включался через допустим 200, а пакеты посылались через 500

dyh9l
25.06.2011, 18:37
дак по ходу действий меняй интервал

Deffol
25.06.2011, 18:53
после каждого пакета?

dyh9l
25.06.2011, 19:57
как надо так и меняй

Deffol
25.06.2011, 20:25
вот так правильно будет? и еще процедуре инит тож интервал стоит

procedure OnTimer(Sender: TObject);
begin
case step of
1:
begin
buf:=HStr('CF 57 6C 5C 03'); //Удар зверя III
SendToServerEx(Connectname);
Inc(Step);
Timer.interval:=300;
end;
2:
begin
buf:=HStr('CF 57 6C 51 03'); //Бросок зверя I
SendToServerEx(Connectname);
Inc(Step);
Timer.interval:=600;
end;
3:
begin
buf:=HStr('CF 57 6C 39 08'); //Чудовищный шрам III
SendToServerEx(Connectname);
Step:=1;
Timer.enabled:=false;
end;

Kilatif
25.06.2011, 22:31
тебе нужео что бы 3 действия выполнились не сразу, а через определенный, равный промежуток времени и лишь 1 раз? Если да, то убери в кейсах изменение интервала, достаточно того что ты увеличиваешь step. Если надо, могу пояснить, но это если я тебя правильно понял )

Deffol
25.06.2011, 23:37
мне надо именно с таким интервалом, какой я поставил, просто спросил верно ли там все

Kilatif
25.06.2011, 23:46
каждый case должен закрываться end'om. ну и сама процедура ендом не закрыта. а так все верно

Deffol
26.06.2011, 07:21
ну это просто вырезка! так нужно на каждую поцедуру кейз писать?

Добавлено через 4 часа 52 минуты
спасибо вам! разобрался :)

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

wimax
26.06.2011, 16:36
хроники какие?

Deffol
26.06.2011, 17:19
да проблема в том, что это не л2 :pardon:
Айон

Kilatif
26.06.2011, 17:36
Deffol, ну для начала нужно понять структуру пакета, который отвечает за то что тебе нужно. Т.е. разобрать в каком месте пакета можно найти допустим ник или лвл... Если l2phx уже показывает тебе структуру, тогда пришли ее сюда. Но, ты вроде говорил что там все плохо и структуру пакетов ты не видишь. Тогда разбирай пакет самостоятельно и пытайся выделить все части. А потом когда его разберешь, тебе нужно по количеству байт читать с пакета. Да, нужно разные переменные для себя выделять, типа ника, лвла и т.д. В общем, те, которые тебе нужно. А потом читаешь с помощью Read эти переменные. Допустим, есть у тебя пакет с такой структурой:
Name(S)ObjectID(D)Race(C)Lvl(C)x(d)y(d)z(d)

и тебе нужно из этого только имя, ObjectID и координаты. Тогда ты делаешь так:
Объявляешь нужные переменные:
var Name : string;
ObjectID : integer;
x, y, z : integer;

и потом уже где нужно ловишь пакет и считываешь через Read'ы:
pos := 2; //пропускаешь тип пакета (я только не знаю как в аионе, в ла2 это 1 байт обычно)
Name := ReadS(pos);
ObjectID := ReadD(pos);
pos := pos + 2;// пропускаем 2 байта Race(C)Lvl(C)
x := ReadD(pos);
y := ReadD(pos);
z := ReadD(pos);

Для справки:
C - 1 байт
D - 4 байта
S - строка (не фиксированное кол-во байт)

Надеюсь ты уловил мою мысль =)

P.S. Когда будешь получать структуру пакета, можешь даже не полностью ее получать, а выделить только то, что тебе нужно, главное что бы это нужное всегда было на том месте, с которого ты можешь определить программно. Допустим в моем примере ты мог получить структуру:
Name(S)ObjectID(D)??(2 байта)x(d)y(d)z(d)

И в этом случае мой пример все равно работает, потому что на эти неизвестные 2 байта я смещаюсь и это количество никогда не измениться.

Deffol
26.06.2011, 18:35
спасибо, это очень поможет...буду разбираться, на счет структуры, думаю она должна быть одинакова, я сравнивал 3 пакета, если ник меньше, то до названия легиона идут 00 до определенного байта.
а вот еще хотел спросить на счет x,y,z я где-то видел, что их не интежером обзывали, а real, почему?

Kilatif
26.06.2011, 18:50
потому что обычно координаты - это числа не целые, а дробные. А тип integer - это целый тип, real - дробный. А я лишь для примера их интежером обозвал, на самом деле обычно это real и обычно они формата не D (4 байта), а F (8 байт)

Deffol
27.06.2011, 00:56
на разборку пакета я понял, придется делать свою процедуру со своими переменным, но как мне написать
prodedure (pck[1]=#$1F);
так что ли?

NLObP
27.06.2011, 01:08
потому что обычно координаты - это числа не целые, а дробные. А тип integer - это целый тип, real - дробный. А я лишь для примера их интежером обозвал, на самом деле обычно это real и обычно они формата не D (4 байта), а F (8 байт)


В Айоне координаты n(4 байта).

Kilatif
27.06.2011, 03:03
Deffol, что бы получить структуру пакета, ты его сначала ручками разбери =) Т.е. отлавливай разные пакеты, смотри аналогии и прочее.

Deffol
27.06.2011, 05:09
да то дело будет замалым :) главное понять структуру скрипта, а этом я разберусь, там не так сложно.
чтоб написать процедуру разбора для пакета, нужно как то его обозвать, мне логика не позволяет придумать :) нужен ведь сам пакет который приходит на клиент, потом его уже разбирать в процедуре. как можно присвоить имя пакету чтоб процедуру обозвать типа
procedure MyPck; ? :)

dyh9l
27.06.2011, 05:24
какие процедуры)))))) пакеты разбирает инишка в пакетнике
вот как пример
01=MoveBackwardToLocation:d(targetX)d(targetY)d(ta rgetZ)d(originX)d(originY)d(originZ)d(moveByMouse)

Deffol
27.06.2011, 06:13
процедуру в смысле, достать нужное из пакета и послать сообщение либо в пм, либо в инфу, хочу сделать, чтоб приходил мсдж как от админа :)
а можно ведь как захочу обозвать процедуру например MyPck, потом просто ее добавить в

if FromServer and (pck) then
begin
MyPck;
?

dyh9l
27.06.2011, 06:57
сначало надо написать процедуру пишущую клиенту как админ)

Deffol
27.06.2011, 08:57
написал уже :)


procedure AdminMsg(s:string);
begin
WriteC($17);
WriteH(54356);
WriteC(35);
WriteC(0);
WriteD(0);
WriteH(0);
WriteS(s);
SendToClient;
end;


Добавлено через 1 час 4 минуты
ну потом в процедуре разбора пакета, просто вставить в мсдж данные, лвла, ника и т.д., тока лвл не могу найти в пакете :)

Добавлено через 36 минут
подскажите как можно пакет обозвать :) который приходит на сервер, чтоб процедуру на него написать

Kilatif
27.06.2011, 15:28
Deffol, ну это уже дело твое =) Как тебе удобнее, так и обзывай =)

Deffol
23.07.2011, 20:44
в этом случае мой пример все равно работает, потому что на эти неизвестные 2 байта я смещаюсь и это количество никогда не измениться.
а, что делать если кол-во изменяется, то есть вначале какая-то инфа постоянно меняется, я не могу понять, что это...на разных персах ник, то после 26-го байта, то после 40-го примерно и т.д., как быть в этой ситуации?

Kilatif
24.07.2011, 16:36
Deffol, значит перед ником есть еще какие-то данные не статические, это скорее всего строка (по крайней мере мне не известно больше других не статических данных в пакетах). Тебе нужно найти эту строку и считывать ее, что бы сместиться на нужное кол-во байт.