02-16-2018, 03:53 PM
В данной теме разберём серверные и клиентские пакеты, а так же структуру кеша магазина.
Структура серверных пакетов магазина
Для построения списка товаров, предметов и их связей используются пакеты:
Начиная с 3 версии клиент стал кешировать полученные данные в файл Shop.dat.
Структура кеша Shop.dat
Для проверки актуальности данных клиент отправляет пакет PROTOCOL_SHOP_GET_SAILLIST_REQ (1029) c md5 хешем файла Shop.dat и в ответ ожидает PROTOCOL_SHOP_GET_SAILLIST_ACK (1030) со следующей структурой:
Если хеш отличается, то необходимо отправить 4 пакета описанные ранее.
Примеры работы с данными
Рассмотрим пример добавления товара включающем в себя SG 550 Ext. с ограничением по количеству боёв. Я буду использовать json, вы же можете использовать xml или базу данных.
Обратите внимание на идентификатор товара (10300101), он состоит из ItemId * 100 + n (есть исключения, но об этом как-то в другой раз), это необходимо для группировки предметов, дальше вы поймёте о чём я.
После отправки пакетов в магазине появится 1 товар на 100 боёв стоимостью в 10000 очков.
![[Изображение: PBShop-1.png]](https://image.zone-game.info/images/2018/02/16/PBShop-1.png)
Теперь разберёмся с группировкой. Если добавить второй товар с идентификатором 10300102 и тем же предметом, но отличающимся ценой или количеством, то у пользователя появится возможность выбора предмета:
Результат.
![[Изображение: PBShop-2.png]](https://image.zone-game.info/images/2018/02/16/PBShop-2.png)
Также вместо количества боёв - мы может указать количество дней в секундах (86400 * n дней), ниже в примере предмет на 7 дней.
![[Изображение: PBShop-Donat-7d.png]](https://image.zone-game.info/images/2018/02/16/PBShop-Donat-7d.png)
Пока всё, буду дописывать по мере появления желания. kappa
Появились вопросы и дополнения касательно магазина PB - пожалуйста, пишите их в этой теме.
Структура серверных пакетов магазина
Для построения списка товаров, предметов и их связей используются пакеты:
PROTOCOL_AUTH_SHOP_ITEMLIST_ACK (1038)
Предметы зарегистрированные в магазине.
Код:
// int всего предметов
// int предметов в этой партии
// int количество отправленных предметов
foreach {
// int itemId
// byte ItemAuthType (см. ниже)
// byte ItemExpirationType (см. ниже)
// byte всегда 2 ?
// byte необходимый уровень звания или достижения
// byte ограничение: 0 - нет, 1 - достижение, 2 - звание
// short идентификатор достижения
}
// int уникальный идентификатор магазинаPROTOCOL_AUTH_SHOP_GOODSLIST_ACK (1036)
Товары зарегистрированные в магазине.
Код:
// int всего товаров
// int товаров в этой партии
// int количество отправленных товаров
foreach {
// int goodsId
// byte всегда 1 ?
// byte 1, 2, 4 ?
// int стоимость в поинтах
// int стоимость в донат монетах
// int всегда 0 ?
// byte SaleType (см. ниже)
// byte[39] // не исползуется
}
// int уникальный идентификатор магазинаPROTOCOL_AUTH_SHOP_REPAIRLIST_ACK (1070)
Предметы которые можно восстанавливать, может игнорироваться в различных регионах.
Код:
// int всего предметов
// int предметов в этой партии
// int количество отправленных предметов
foreach {
// int itemId
// int стоимость восстановления 1% в поинтах
// int стоимость восстановления 1% в донат монетах
// int максимальная прочность (100)
}
// int уникальный идентификатор магазинаPROTOCOL_AUTH_SHOP_MATCHINGLIST_ACK (1040)
Пакет связывает предметы с товарами.
Код:
// int всего связей
// int связей в этой партии
// int количество отправленных связей
foreach {
// int goodsId
// int itemId
// int прочность, количество или время в секундах для приобретаемого предмета
// int всегда 0
}
// int уникальный идентификатор магазинаНачиная с 3 версии клиент стал кешировать полученные данные в файл Shop.dat.
Структура кеша Shop.dat
Код:
// int уникальный идентификатор магазина
// int количество товаров
// int количество предметов
// int количество восстанавливаемых предметов
// int количество связей
// byte[количество товаров * 58]
// byte[количество предметов * 11]
// byte[количество восстанавливаемых предметов * 16]
// byte[количество связей * 16]Для проверки актуальности данных клиент отправляет пакет PROTOCOL_SHOP_GET_SAILLIST_REQ (1029) c md5 хешем файла Shop.dat и в ответ ожидает PROTOCOL_SHOP_GET_SAILLIST_ACK (1030) со следующей структурой:
Код:
bool // true если кеш отличается от актуального
int // дата последней проверки в формате yyMMddhhmmЕсли хеш отличается, то необходимо отправить 4 пакета описанные ранее.
Примеры работы с данными
Рассмотрим пример добавления товара включающем в себя SG 550 Ext. с ограничением по количеству боёв. Я буду использовать json, вы же можете использовать xml или базу данных.
Класс Item и необходимые пречисления
[SRC="csharp"]class Item
{
public int Id { get; set; }
public ItemAuthType Type { get; set; }
public ItemExpirationType ExpirationType { get; set; }
public byte Unk { get; set; }
public bool Repairable { get; set; }
public int RepairPoints { get; set; }
public int RepairCash { get; set; }
public ItemRestrictionType RestrictionType { get; set; }
public byte AchievementOrTitleLevel { get; set; }
public short AchievementId { get; set; }
}
[/SRC]
[SRC="csharp"]enum ItemAuthType : byte
{
None,
Expirable,
Temporal,
Permanent,
PcCafeRegular,
PcCafePremium,
Special
}
[/SRC]
[SRC="csharp"]enum ItemExpirationType : byte
{
None,
Durable,
Temporary,
Permanent
}
[/SRC]
[SRC="csharp"]enum ItemRestrictionType : byte
{
None,
Achievement,
Title
}
[/SRC]
{
public int Id { get; set; }
public ItemAuthType Type { get; set; }
public ItemExpirationType ExpirationType { get; set; }
public byte Unk { get; set; }
public bool Repairable { get; set; }
public int RepairPoints { get; set; }
public int RepairCash { get; set; }
public ItemRestrictionType RestrictionType { get; set; }
public byte AchievementOrTitleLevel { get; set; }
public short AchievementId { get; set; }
}
[/SRC]
[SRC="csharp"]enum ItemAuthType : byte
{
None,
Expirable,
Temporal,
Permanent,
PcCafeRegular,
PcCafePremium,
Special
}
[/SRC]
[SRC="csharp"]enum ItemExpirationType : byte
{
None,
Durable,
Temporary,
Permanent
}
[/SRC]
[SRC="csharp"]enum ItemRestrictionType : byte
{
None,
Achievement,
Title
}
[/SRC]
Классы Goods, GoodsItemMatching и перечисления
[SRC="csharp"]class Goods
{
public int Id { get; set; }
public byte Unk1 { get; set; } = 1;
public byte Unk2 { get; set; } = 1;
public SaleType SaleType { get; set; } = SaleType.Regular;
public int Points { get; set; }
public int Cash { get; set; }
public ICollection<GoodsItemMatching> Matching = new HashSet<GoodsItemMatching>();
}
[/SRC]
[SRC="csharp"]enum SaleType : byte
{
Regular,
LatestOffer,
BestSeller,
Event,
PCCafe,
Discount
}
[/SRC]
[SRC="csharp"]class GoodsItemMatching
{
public int GoodsId { get; set; }
public int ItemId { get; set; }
public int Quantity { get; set; }
}
[/SRC]
{
public int Id { get; set; }
public byte Unk1 { get; set; } = 1;
public byte Unk2 { get; set; } = 1;
public SaleType SaleType { get; set; } = SaleType.Regular;
public int Points { get; set; }
public int Cash { get; set; }
public ICollection<GoodsItemMatching> Matching = new HashSet<GoodsItemMatching>();
}
[/SRC]
[SRC="csharp"]enum SaleType : byte
{
Regular,
LatestOffer,
BestSeller,
Event,
PCCafe,
Discount
}
[/SRC]
[SRC="csharp"]class GoodsItemMatching
{
public int GoodsId { get; set; }
public int ItemId { get; set; }
public int Quantity { get; set; }
}
[/SRC]
Items.json
Код:
[
{
"Id": 103001,
"Type": "Expirable",
"ExpirationType": "Durable",
"RestrictionType": "None"
}
]Goods.json
Код:
[
{
"Id": 10300101,
"SaleType": "Regular",
"Points": 10000,
"Matching": [
{
"ItemId": 103001,
"Quantity": 100
}
]
}
]Обратите внимание на идентификатор товара (10300101), он состоит из ItemId * 100 + n (есть исключения, но об этом как-то в другой раз), это необходимо для группировки предметов, дальше вы поймёте о чём я.
После отправки пакетов в магазине появится 1 товар на 100 боёв стоимостью в 10000 очков.
![[Изображение: PBShop-1.png]](https://image.zone-game.info/images/2018/02/16/PBShop-1.png)
Теперь разберёмся с группировкой. Если добавить второй товар с идентификатором 10300102 и тем же предметом, но отличающимся ценой или количеством, то у пользователя появится возможность выбора предмета:
Goods.json
Код:
[
{
"Id": 10300101,
"SaleType": "Regular",
"Points": 6000,
"Matching": [
{
"ItemId": 103001,
"Quantity": 50
}
]
},
{
"Id": 10300102,
"SaleType": "Regular",
"Points": 10000,
"Matching": [
{
"ItemId": 103001,
"Quantity": 100
}
]
}
]Результат.
![[Изображение: PBShop-2.png]](https://image.zone-game.info/images/2018/02/16/PBShop-2.png)
Также вместо количества боёв - мы может указать количество дней в секундах (86400 * n дней), ниже в примере предмет на 7 дней.
Items.json
Код:
[
{
"Id": 103001,
"Type": "Temporal",
"ExpirationType": "Durable",
"RestrictionType": "None"
}
]Goods.json
Код:
[
{
"Id": 10300101,
"SaleType": "Regular",
"Cash": 100,
"Matching": [
{
"ItemId": 103001,
"Quantity": 604800
}
]
}
]![[Изображение: PBShop-Donat-7d.png]](https://image.zone-game.info/images/2018/02/16/PBShop-Donat-7d.png)
Пока всё, буду дописывать по мере появления желания. kappa
Появились вопросы и дополнения касательно магазина PB - пожалуйста, пишите их в этой теме.