#3) Учимся одностороннему общению сервер>клиент без особых заморочек (IT-??)

Тут научимся кидать данные с сервера в клиент парой окольных путей.​

  • Путь №1 - использование HTML файлов для передачи параметров.
Клиент получает всё наполнение HTML файла на сервере. Зная это, мы можем воспользоваться умением клиента парсить данные с текста (ParseInt, ParseString, ...)

Возьмём простейшую хтмлку и докинем ей пару параметров:
HTML:
<html><head><body>You are either not on a quest that involves this NPC, or you don't meet this NPC's minimum quest requirements.
</body></html>
ParameterInt=123
ParameterString=text

Пора зайти в интерфейс, класс NPCDialogWnd.uc. Конкретно нас интересует функция HandleLoadHtmlFromString.

Находим кусочек:
C:
ParseString(param, "HTMLString", htmlString);

Это и есть наша стринга, которая уже содержит вышеуказанные параметры. Да, можно парсить новые параметры сразу с param, как хотите, в целом и так и так будет работать.

Далее всё просто - мы ещё раз парсим эти данные, указав тип и имя параметра.
C:
local int int_param;
local string string_param;

ParseInt(htmlString, "ParameterInt", int_param);
ParseString(htmlString, "ParameterString", string_param);
На выходе переменные будут равны:
int_param = 123
string_param = text

Самое простое для чего это используется - изменение размеров окна хтмлки. Что бы работало корректно, необходимо маленько скорректировать абсолютные размеры элементов.

  • Путь №2 - UIEvent, AITimer или как я "придумал" систему эвентов в системе эвентов
Сразу скажу, что понятия не имею "чётамвявах", данные опыты только с PTS'ом. Говорю я о функции SendUIEvent(talker, ...) в АИ.
Позволяет она швырнуть 2(3) ИНТа + 6 стрингов, но блоки стрингов ограничены размером пакета, так что бесконечные тексты туда не засунешь

В клиент уходит запрос, который состоит, из:
  • 90000 - выдуманный нами и уникальный ИД эвента, что бы разделять то, что мы шлём
  • 100, 200 и text - полноценная информация, которую мы будем использовать
C:
SendUIEvent(talker, 90000, 100, 200, "text", "", "", "", "", "");


Далее снова переходим в клиент и начинаем допихивать куски, которые помогут принимать этот пакет в любом окне:
C:
RegisterEvent( EV_AITimer );
function OnEvent(int Event_ID, string param)
{  
        case EV_AITimer:
            AIOnEvent(Param);
        break;      
    }      
}
А теперь к тому, почему это система эвентов в системе эвентов - мы приняли её в стандартном OnEvent и перекинули с самодельный, который по сути займётся тем же - спарсит ИД и пойдёт выполнять нужное действие.
C:
function AIOnEvent(string Param)
{
    local int     Event;
    local int i1, i2;
    local string s1;
    Parseint(Param, "EventID", Event);
   
    switch(Event)
    {      
    case 90000:
        Parseint(Param, "Ask", i1);
        Parseint(Param, "Reply", i2);
        ParseString(Param, "Param1", s1);
        break;
    }
}

Где переменные в клиенте заполнились тем, что мы в них кинули из сервера:
i1 = 100
i2 = 200
s1 = text

Как использовать - решайте сами.
 

Сразу скажу, что понятия не имею "чётамвявах", данные опыты только с PTS'ом. Говорю я о функции SendUIEvent(talker, ...) в АИ.
Позволяет она швырнуть 2(3) ИНТа + 6 стрингов, но блоки стрингов ограничены размером пакета, так что бесконечные тексты туда не засунешь
В "явах" еще проще - это все шлется через пакет ExSendUIEvent, который так же можно слать как душе угодно и откуда угодно.
Вобще, в теории, можно по идее отослать до 10 стрингов, как 5 параметров для каждого из двух сисстрингов, ид которых отсылаются в пакете + как уже выше сказано просто 2 инта, которые шлются там же отдельно.
Java:
    @Override
    protected void writeImpl()
    {
        writeEx(Opcode.ExSendUIEvent);
        writeD(_objectId);
        writeD(_style);
        writeD(0x00); // unk
        writeD(0x00); // unk
        writeS(String.valueOf(_mode));

        if (_mode >= 0 && _style < 6)
        {
            writeS(String.valueOf(_value1 / 60));
            writeS(String.valueOf(_value1 % 60));
            writeS(String.valueOf(_value2 / 60));
            writeS(String.valueOf(_value2 % 60));
        }
        else
        {
            writeS(String.valueOf(_value1)); // 1-й инт
            writeS(String.valueOf(_value2)); // 2-й инт
            writeS(String.valueOf(_sysStringId1));
            writeS(String.valueOf(_sysStringId2));
        }

        writeElements(); // параметры для сисстрингов
    }
 
который так же можно слать как душе угодно и откуда угодно.
размышлял над этим, действительно в яве способ ещё более интересный получается, т.к. с сорцом сервера всё ограничивается лишь фантазией (откуда кидать), в то время как пэтос - костыли на нпц, ну или анальные допилы
 
  • Мне нравится
Реакции: kick
А теперь при отсылке большого количества стрингов- вы будете в клиенте получать не слабый такой залаг.
Потому что стринг в байтовом выражении самый большой объем занимает.
 
Ну разве что флудить пакетом ну я хз, сотнями раз в секунду.
Ну и я вобще-то сомневаюсь что будут в этом пакете слать простыни текста в несколько килобайт хотя бы.
 
Ну разве что флудить пакетом ну я хз, сотнями раз в секунду.
Ну и я вобще-то сомневаюсь что будут в этом пакете слать простыни текста в несколько килобайт хотя бы.
Поверьте встречались клиенты которые там почти сборники Достоевского пытались отсылать. Ведь все зависит от того что именно вам нужно отсылать. А вдруг к примеру кучу айтемов. Бывают и такие запросы- причем айтемы кастомные.
 
А теперь при отсылке большого количества стрингов- вы будете в клиенте получать не слабый такой залаг.
Потому что стринг в байтовом выражении самый большой объем занимает.
скажем так: наше дело реализация, а оптимизаций пусть занимается кто-то другой
 
Последнее редактирование:
Не, в принципе, если отправлять небольшой объем данных и редко - очень даже вариант, хотя и костыль, если же слать длинную строку - парс этой строки уже будет лагать
 
Кстати, я чего тут подумал - есть же по идее еще удобный пакет для отправки чего-то клиенту в интерфейс.
Я про ExBR_BroadcastEventState, позволяющий отправить клиенту 6 числовых значений + 2 строки.
Точнее числовых значений можно отправить 7, но на _eventId логичней просто повесить какое-то определенное значение, по которому будет детектиться что в пакете пришли нестандартные данные для использования в чем-то своем.
Java:
    @Override
    protected void writeImpl()
    {
        writeEx(Opcode.ExBR_BroadcastEventState);
        writeD(_eventId);
        writeD(_eventState);
        writeD(_param0);
        writeD(_param1);
        writeD(_param2);
        writeD(_param3);
        writeD(_param4);
        writeS(_param5);
        writeS(_param6);
    }
 
В обратную сторону из интерфейса можно слать произвольный String до 1024 символов через функцию:
RequestPCCafeCouponUse(string);

На сервер уходит пакет: D0:19(для 273 ХФ) с этой строкой.
Удобно, т.к в большинстве случаев этот пакет почти не используется, ну и + строка, это строка.
 
А еще можно не заморачиваться с отправкой на сервер в особых пакетах, а просто слать в Say2 строку, задавая ей какой-то особый префикс, чтобы такие строки не в чат выводило, а по особому обрабатывало.
Вобщем тот же принцип что и с войсед командами, начинающимися с точки.
 
А еще можно не заморачиваться с отправкой на сервер в особых пакетах, а просто слать в Say2 строку, задавая ей какой-то особый префикс, чтобы такие строки не в чат выводило, а по особому обрабатывало.
Вобщем тот же принцип что и с войсед командами, начинающимися с точки.
да и игрокам на стороне ифейса не забыть запретить использование этого префикса)
 
Я как истинный бот не понял по первому пункту где мы реализуем размер окна?
 
Назад
Сверху Снизу