Четверг, 09.01.2025, 12:13
| RSS
F.O.R.U.M.
Главная | Описание класса net_packet - Форум
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Описание класса net_packet
frontДата: Вторник, 13.10.2009, 16:33 | Сообщение # 1
Admin
Группа: Администраторы
Сообщений: 152
Репутация: 229
Статус: Оффлайн
net_packet - это один из вспомогательных классов. Представляет собой буфер размером ровно 8 кбайт (т.е. 8192 байта). Из буфера можно последовательно читать и записывать данные, используя методы класса. Имеется текущая позиция чтения и записи. Теперь подробности.


 
frontДата: Вторник, 13.10.2009, 16:33 | Сообщение # 2
Admin
Группа: Администраторы
Сообщений: 152
Репутация: 229
Статус: Оффлайн
Я немного изменил описание по сравнению с оригинальным из lua_help.script. Добавил типы возвращаемых значений, перегруппировал и убрал некоторую шелуху.

Более подробно о методах класса:
net_packet() - конструктор, вызывается в виде глобальной функции так:
local packet = net_packet()
созданный пакет по умолчанию имеет позиции чтения и записи установленные в 0
Не всегда надо создавать свой пакет. Часто приходится иметь дело с уже готовым пакетом (см. следующую статью об использовании нетпакетов)

w_tell() - возвращает текущую позицию записи
r_tell() - возвращает текущую позицию чтения
r_advance(shift) - смещает позицию чтения на shift байт. Смещение может быть отрицательным.
r_seek(pos) - устанавливает позицию чтения в pos
r_elapsed() - возвращает w_tell() - r_tell()
r_eof() - возвращает true, если r_tell() < w_tell(), иначе false

w_begin(number) - пишет двухбайтовое число в начало пакета и устанавливает позицию записи равной 2. Единственным другим способом начать запись с начала пакета - это создать новый пакет, у которого позиция записи установлена в 0.
r_begin(number&) - Непонятный метод. По аналогии с w_begin должен читать с начала пакета два байта и устанавливать позицию чтения в 2. Однако у меня приводит к вылету. Ну, в любом случае можно обойтись и без него.

Важный момент! Нет никакого способа узнать, что в процессе чтения или записи позиция чтения или записи вышла за пределы пакета. При чтении подразумевается, что прочитать можно столько, сколько записано. Для этого и есть функции r_elapsed() и r_eof(). А вот при записи никакой границы сверху нет, поэтому можно запросто записать больше, чем 8 кбайт. Ясно, что при этом произойдёт переполнение буфера с почти обязательным последующим вылетом игры. Так что надо самостоятельно следить за размером позиции записи и проверять, чтобы при последующей записи она не вышла бы за размеры пакета. Для этого надо знать, сколько мы запишем, ещё до того, как запишем. В особенности это важно для строк, которые имеют переменную длину. Поступаем примерно так:
Код
if string.len(s) + 1 + packet:w_tell() > 8192 then
-- здесь делаем что-то, например крашим игру и выводим сообщение, что не надо жадничать =)
end
packet:w_stringZ(s)Обратите внимание на "+ 1" в вычислении новой позиции записи. Строки имеют дополнительный невидимый нулевой символ в конце, и их физическая длина на один больше, чем длина в символах, которую возвращает функция string.len().

Остальные методы предназначены собственно для чтения и записи. Описывать их все в подробностях нет смысла, только общий принцип. Читаем так:
local value = packet:r_XXX()
здесь XXX - это тип значения, которое читается. Значение читается из буфера начиная с текущей позиции чтения, а позиция чтения увеличивается на размер читаемого значения. В переменную value будет помещено значение того типа, которое прочитано.
аналогично пишем в буфер:
packet:w_XXX(value)
Значение пишется начиная с текущей позиции записи, а позиция записи увеличивается на размер типа XXX.
для целых типов:
u - знаковое значение
s - беззнаковое значение
8, 16, 24, 32, 64 - один, два, три, четыре, восемь байт соответственно
Обратите внимаение, что для типа s8 (знаковый байт) нет метода записи. Подозреваю, что вместо него можно использовать соответствующий метод для беззнакового типа.
float - число с плавающей запятой одинарной точности, 4 байта
stringZ - строка (размер равен длине + 1 байт)
bool - логическое значение (1 байт)
vec3 - объект типа vector - вектор из трёх float (12 байт)
matrix - объект типа matrix. Состоит из 4-х векторов (48 байт)
sdir - ? непонятно, на запись берёт вектор и пишет 6 байт
dir - ? аналогично, но пишет 2 байта
angle8 - ? берёт float и пишет 1 байт
angle16 - ? аналогично, но пишет 2 байта
четыре последних метода при чтении у меня вызывают вылет. зачем нужны, неизвестно.
ClientID - объект класа ClientID. Судя по всему, это надо для сетевой игры.
float_q8, float_q16 - пока непонятно
Назначение методов с w_chunk_ вообще непонятно, тем более, что для них отсутствуют соответствующие методы на чтение.


 
frontДата: Вторник, 13.10.2009, 16:34 | Сообщение # 3
Admin
Группа: Администраторы
Сообщений: 152
Репутация: 229
Статус: Оффлайн
"Использование объектов класса net_packet"
Собственно, законное использование нетпакетов - это буфер, в котором объект сохраняет своё состояние. Скорее всего это используется в первую очередь при передаче данных по сети. Потому и net_packet, т.е. буквально "сетевой пакет". Сначала объект записывает себя в пакет, затем он отправляется по сети. Похоже, однако, что используется не только при передаче по сети, но и для сохранения объектов вообще.
Теперь конкретнее.
1. Сохранение состояния серверного класса
На серверной стороне есть классы, унаследованные от cse_abstract. У них есть методы STATE_Read и STATE_Write.
метод STATE_Read вызывается при загрузке состояния объекта из сохранёнки, в нём данные читаются из переданного методу пакета. STATE_Write вызывается при сохранении объекта, в нём данные объекта сохраняются в пакет.
Если создать свой класс и перегрузить эти методы, то увидим такую картину:
Код
class "se_my_server_class" (<имя_базового_класса>)

function se_my_server_class:STATE_Write(packet)
<имя_базового_класса>.STATE_Write(self, packet) -- базовый класс сохраняет свои данные
-- здесь можно сохранить какие-то данные, в дополнение к данным базового класса
packet:w_stringZ("моя строка")
end

function se_my_server_class:STATE_Read(packet, size)
<имя_базового_класса>.STATE_Read(self, packet) -- здесь базовый класс читает своё состояние из пакета
-- здесь можно прочитать состояние своего класса, которое было сохранено ранее
local s = packet:r_stringZ() -- получим строку "моя строка"
end
2. Сохранение состояния клиентского класса
На клиентской стороне также имеется нечто подобное. Это реализуется методами биндера save и load. При создании биндера (см. мою статью насчёт класса object_binder) можно в этих методах что-то сохранить. Однако, нетпакет используется для сохранения в методе save. в этом он подобен методу STATE_Write серверного класса. А вот при загрузке почему-то вместо нетпакета передаётся поток на чтение (класс reader). Таким образом трюкачество, описанное в следующем пункте для клиентских объектов не выйдет.

3. Перепаковка серверных объектов с целью изменения их параметров
Предыдущие два варианта использования нетпакетов - это так сказать "законное" их использование. Но это не всё. Ничто не мешает вызывать методы STATE_Read и STATE_Write в произвольный момент времени, имитируя процесс сохранения и загрузки объекта. При этом можно сделать следующее:
Код
local packet = net_packet() -- создаём пустой пакет
sobj:STATE_Write(packet) -- загрузили в наш пакет состояние серверного объекта
-- используя методы класса net_packet меняем нужные нам значения.
sobj:STATE_Read(packet, packet:w_tell()) -- записали в объект изменённое состояние обратно, имитируя процесс его загрузки
Несколько замечаний:
- Все эти манипуляции надо проводить над объектами в оффлайне, поскольку онлайновый объект регулярно обновляет серверную часть и полностью его переписывает, так что любые изменения такого рода будут потеряны.
- Надо знать структуру нетпакета для того объекта, который Вы собираетесь изменить. При таких хирургических операциях запросто можно всё испортить.


 
lulu2486Дата: Суббота, 15.06.2013, 20:00 | Сообщение # 4
Рядовой
Группа: Пользователи
Сообщений: 2
Репутация: 0
Статус: Оффлайн
ВсемПривет!ВамНуженхороший доход!??? 
ЯпредлагаюВамвещь, к которой и сама 
относиласьпоначалускептически.
  

ЭТА работачерез 
интернетбезвложений, но я так написала 
потомучто80 рублей не вложения и рискнуть 
такоймаленькойсуммой стоит, хотя риска 
тутнет.
  

Читаяэтустатью и думаете, что это 
очереднойразводили лохотрон, но не 
спешитезакрыватьмою статью, уделите 
5 минутсвоеговремени !!!
 

Внимание!!!Прочитайтеинструкциюочень внимательно 

Шаг№1.Скопируйте этот текстовый документ 
себенакомпьютер Как зарабатывать 
деньгияндекс,отредактируйте для 
последующейработыс ним. Его придется 
рекламироватьиразмещать на форумах 
идаватьобъявления.
  

Шаг№2.Регистрация кошелька яндекс денег. 
Есливыне зарегистрированы на
сайте 
Яндекссоответственно у васне может 
бытьего кошелька. Вамнужно это сделать, 
какэто сделатьможете узнать здесь.
  

Шаг№3.Пополняем свой кошелек яндекс
денег 
насумму 80 рублей. Это можносделать в 
любомтерминале, но лучшев Евро сети 
так неберуткомиссии.
  

Шаг№4.Переводим деньги на
указанные 
номера 
кошельков.
  

Наэтомразделея остановлюсь подробно и 
вамследуетотнестись к нему серьезно. 
Именновэтом и вся фишка, как
зарабатывать 
деньгияндекс.
  

1.Зайдитенасайт https://money.yandex.ru/ вводите 
свойлогини пароль, и жмете на кнопку 
«Перевести».Выпопадаете на страницу 
переводаденег.
  

2.Вполе«Название платежа для истории» 
необходимонаписать«Пожалуйста, внесите 
меня всписокЯndex — кошельков».
  

Итакнужносделать 7 платежей на номера 
кошельков,которыеуказаны ниже.
  

Вполя«Здесьможно написать что-нибудь 
получателю»можетевписать имя, 
электронный адресилиадрес сайта 
человека от котороговыузнали о этой 
работе. Это нужнодлястатистики, да
и 
только.
  

Запомнитеиусвойте,чтобыполучать прибыль‚ 
необходимоотправитьНА КАЖДЫЙ из этих 
7 кошельковпо 10руб. — иначе‚ сетевыми 
модераторамиЯndex-кошельков‚вы просто 
не будетевключены всистему и не сможете 
произвестиобналичиваниевашего 
дохода.
  

Итак,отправьтепо10 руб. на каждый
из 
следующих 
Счетов:
  
1.410011218635379  

2.410011274789402  

3.410011361137687  

4.410011382689565  

5.410011480241341  

6.410011001981776  

7.410011908020198 

Шаг№5.Рассылаем объявления.  

1.Послетого‚как вы выполнили все 
предыдущиешаги‚удалите в текстовом 
документе,которыйвы скачали в Шаге № 
1, из спискакошельковпервый и переместите 
второйкошелёкна место первого‚ который 
выстерли‚третий на место второго и 
такдалее.А в седьмой номер‚ который 
оказалсяпустым‚пишите номер своего 
кошелька!Вниманиена картинку.
  

 ЗАПОМНИТЕЧЕМ БОЛЬШЕвы разместите, ТЕМ ВЫШЕ БУДЕТ
ВАШ ДОХОД. И этот доход будет НАПРЯМУЮЗАВИСЕТЬ
ОТ ВАС. Размещение этой статьи на 200
форумах, даже на самыхмалопосещаемых,
ГАРАНТИРУЕТ Вам доход 15000 руб - ЭТО
МИНИМУМ!!!, втечение двух месяцев!!! БОЛЬШЕ
РАЗМЕЩЕНИЙ – БОЛЬШЕ ДОХОД (при том
вГЕОМЕТРИЧЕСКОЙ ПРОГРЕССИИ). ИТАК, КОГДА
ВЫ ДОСТИГНЕТЕ ПЕРВОЙ ПОЗИЦИИ ВСПИСКЕ,
ВЫ БУДЕТЕ ИМЕТЬ ТЫСЯЧИ РУБЛЕЙ ПРОСТО
КАК СОЗДАТЕЛЬ СПИСКА !!!!!!!ЭТО СТОИТ 70-ти
рублей и СОВСЕМ НЕ ТРУДНОЙ РАБОТЫ!
ГЛАВНОЕ – ЭТОРАБОТАЕТ!!!
 
  • Страница 1 из 1
  • 1
Поиск:

Для добавления необходима авторизация

Copyright Front Сайт оптимизирован под браузер Opera © 2025