Попробую спасибоПосмотрите реализацию в high five, там была настройка для переключения в клиенте вариантов получения подарка.
Тут возможно пакет поменялся, на новых хрониках он должен быть в клиенте на сколько знаю как подсказка для реализации в сервере.
Может кто более точно подскажет
Ага понял буду пробовать ото уже замучался уже неделю бьюсь над этимДля инвентаря подарков надо в клиенте включить в инишке UseGoodsInventory
Ну и реализовать пакеты работы с этим инвентарем, если они не реализованы:
- клиентские: RequestGoodsInventoryInfo, RequestUseGoodsInventoryItem
- серверные: ExGoodsInventoryInfo, ExGoodsInventoryResult, ExGoodsInventoryChangedNotify
Буду благодарен тема интересная )Ну так реализуй - пакеты там простые, главное продумать саму систему работы с этим всем.
У меня к примеру этот инвентарь отдельной сущностью идет и првиязан к аккаунтам, а не к конкретным персонажам, ну т.е. для всех персов на акке он общий.
Ну и он кстати удобней обычного инвентаря прем. товаров тем что тут можно выдавать сразу наборы предметов паком.
типа вот
Посмотреть вложение 85134
Структуры пакетов, как они выглядят в хомке, могу тут выложить если надо, но остальное уже реализовывай сам
EX_GOODS_INVENTORY_CHANGED_NOTI(0xFE, 0x10C),
EX_GOODS_INVENTORY_INFO(0xFE, 0x10D),
EX_GOODS_INVENTORY_RESULT(0xFE, 0x10E),
package l2p.gameserver.network.s2c.goods;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
import l2p.gameserver.holders.items.ItemData;
import l2p.gameserver.holders.items.PremiumItem;
import l2p.gameserver.managers.GoodsManager;
import l2p.gameserver.model.Player;
import l2p.gameserver.network.components.ServerPackets;
import l2p.gameserver.network.s2c.L2GameServerPacket;
public class ExGoodsInventoryInfo extends L2GameServerPacket
{
private int _mode;
private Collection<PremiumItem> _goods = Collections.emptyList();
private Collection<PremiumItem> _items = Collections.emptyList();
public ExGoodsInventoryInfo(Player player, int mode)
{
_mode = mode;
_goods = GoodsManager.getInstance().getGoods(player).values().stream().limit(100).collect(Collectors.toList());
_items = player.getPremiumItems().getItems().values().stream().limit(100 - _goods.size()).collect(Collectors.toList());
}
@Override
protected void writeImpl()
{
writeId(ServerPackets.EX_GOODS_INVENTORY_INFO);
writeH(0);
writeH(_goods.size() + _items.size());
for (PremiumItem goods : _goods)
{
writeC(0x01);
writeQ(goods.getUid());
writeD(goods.getIconId()); // номер иконки из GoodsIcon.dat
writeS(goods.getGoodsName()); // название товара
writeS(goods.getGoodsDesc()); // описание товара
writeQ(_mode == 0 ? 60 : 0); // время автоматического обновления списка (в секундах)
writeC(0x02); // цвет названия товара (2 - желтый если предыдущий параметр > 0, другие значения - белый)
writeC(!goods.getSenderName().isEmpty()); // 1 - показать информацию об отправителе, 0 - не показывать
writeS(goods.getSenderName()); // имя отправителя
writeS(goods.getSenderMessage()); // сообщение от отправителя
writeQ(Long.MAX_VALUE); // возможно время, когда товар исчезнет?
writeH(goods.getItems().size()); // количество вещей в товаре
for (ItemData item : goods.getItems())
{
writeD(item.getId());
writeD((int) item.getCount());
}
}
for (PremiumItem item : _items)
{
writeC(0x00);
writeQ(item.getUid());
writeC(!item.getSenderName().isEmpty()); // 1 - показать имя отправителя, 0 - не показывать
writeS(item.getSenderName()); // имя отправителя
writeD(item.getItem().getId()); // id вещи
writeQ(item.getItem().getCount()); // количество
}
}
}
package l2p.gameserver.network.s2c.goods;
import l2p.gameserver.network.components.ServerPackets;
import l2p.gameserver.network.s2c.L2GameServerPacket;
public class ExGoodsInventoryChangedNotify extends L2GameServerPacket
{
public static final L2GameServerPacket STATIC = new ExGoodsInventoryChangedNotify();
@Override
protected void writeImpl()
{
writeId(ServerPackets.EX_GOODS_INVENTORY_CHANGED_NOTI);
}
}
package l2p.gameserver.network.s2c.goods;
import l2p.gameserver.network.components.ServerPackets;
import l2p.gameserver.network.s2c.L2GameServerPacket;
public class ExGoodsInventoryResult extends L2GameServerPacket
{
public static final L2GameServerPacket NOTHING = new ExGoodsInventoryResult(1);
public static final L2GameServerPacket SUCCESS = new ExGoodsInventoryResult(2);
public static final L2GameServerPacket ERROR = new ExGoodsInventoryResult(-1);
public static final L2GameServerPacket TRY_AGAIN_LATER = new ExGoodsInventoryResult(-2);
public static final L2GameServerPacket INVENTORY_FULL = new ExGoodsInventoryResult(-3);
public static final L2GameServerPacket NOT_CONNECT_TO_PRODUCT_SERVER = new ExGoodsInventoryResult(-4);
public static final L2GameServerPacket CANT_USE_AT_TRADE_OR_PRIVATE_SHOP = new ExGoodsInventoryResult(-5);
public static final L2GameServerPacket NOT_EXISTS = new ExGoodsInventoryResult(-6);
public static final L2GameServerPacket TO_MANY_USERS_TRY_AGAIN_INVENTORY = new ExGoodsInventoryResult(-101);
public static final L2GameServerPacket TO_MANY_USERS_TRY_AGAIN = new ExGoodsInventoryResult(-102);
public static final L2GameServerPacket PREVIOS_REQUEST_IS_NOT_COMPLETE = new ExGoodsInventoryResult(-103);
public static final L2GameServerPacket CHANGED = new ExGoodsInventoryResult(-104);
public static final L2GameServerPacket ALREADY_RETRACTED = new ExGoodsInventoryResult(-105);
public static final L2GameServerPacket ALREADY_RECIVED = new ExGoodsInventoryResult(-106);
public static final L2GameServerPacket PRODUCT_CANNOT_BE_RECEIVED_AT_CURRENT_SERVER = new ExGoodsInventoryResult(-107);
public static final L2GameServerPacket PRODUCT_CANNOT_BE_RECEIVED_AT_CURRENT_PLAYER = new ExGoodsInventoryResult(-108);
private int _result;
public ExGoodsInventoryResult(int result)
{
_result = result;
}
@Override
protected void writeImpl()
{
writeId(ServerPackets.EX_GOODS_INVENTORY_RESULT);
writeD(_result);
}
}
EX_REQUEST_GOODS_INVENTORY_INFO(0xAA, RequestGoodsInventoryInfo::new),
EX_REQUEST_USE_GOODS_IVENTORY_ITEM(0xAB, RequestUseGoodsInventoryItem::new),
package l2p.gameserver.network.c2s.goods;
import l2p.gameserver.config.OtherConfig;
import l2p.gameserver.model.Player;
import l2p.gameserver.network.c2s.L2GameClientPacket;
import l2p.gameserver.network.s2c.ActionFail;
import l2p.gameserver.network.s2c.goods.ExGoodsInventoryInfo;
public class RequestGoodsInventoryInfo extends L2GameClientPacket
{
private int _mode;
@Override
protected void readImpl()
{
_mode = readC();
}
@Override
protected void runImpl()
{
Player player = getPlayer();
if (player == null)
return;
if (OtherConfig.GOODS_INVENTORY_ENABLED)
player.sendPacket(new ExGoodsInventoryInfo(player, _mode));
else
player.sendPacket(ActionFail.STATIC);
}
}
package l2p.gameserver.network.c2s.goods;
import l2p.gameserver.holders.items.PremiumItem;
import l2p.gameserver.managers.GoodsManager;
import l2p.gameserver.model.Player;
import l2p.gameserver.network.c2s.L2GameClientPacket;
import l2p.gameserver.network.s2c.ActionFail;
import l2p.gameserver.network.s2c.goods.*;
import l2p.gameserver.utils.ItemUtils;
public class RequestUseGoodsInventoryItem extends L2GameClientPacket
{
private int _mode;
private long _id;
@SuppressWarnings("unused")
private long _unk;
@Override
protected void readImpl()
{
_mode = readC();
_id = readQ();
_unk = _mode == 0 ? readQ() : 0L;
}
@Override
protected void runImpl()
{
Player player = getPlayer();
if (player == null)
return;
if (player.isActionsDisabled())
{
player.sendPacket(ActionFail.STATIC);
return;
}
if (player.isInGoodsInventory())
{
player.sendPacket(ExGoodsInventoryResult.PREVIOS_REQUEST_IS_NOT_COMPLETE, ActionFail.STATIC);
return;
}
if (player.getPremiumItems().isEmpty() && GoodsManager.getInstance().getGoods(player).isEmpty())
{
player.sendPacket(ExGoodsInventoryResult.NOT_EXISTS, ActionFail.STATIC);
return;
}
if (!ItemUtils.checkInventory(player, false))
{
player.sendPacket(ExGoodsInventoryResult.INVENTORY_FULL, ActionFail.STATIC);
return;
}
if (player.isInTrade() || player.isInPrivateStore())
{
player.sendPacket(ExGoodsInventoryResult.CANT_USE_AT_TRADE_OR_PRIVATE_SHOP, ActionFail.STATIC);
return;
}
if (_mode == 1)
{
PremiumItem goods = GoodsManager.getInstance().getGoods(player, (int) _id);
if (goods == null)
{
player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC);
return;
}
player.setInGoodsInventory(true);
try
{
goods.getItems().forEach(item -> ItemUtils.addItem(player, item));
GoodsManager.getInstance().updateGoods(player, (int) _id);
}
catch (Exception e)
{
player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC);
}
finally
{
player.setInGoodsInventory(false);
}
player.sendPacket(ExGoodsInventoryResult.SUCCESS, new ExGoodsInventoryInfo(player, 1));
}
else
{
PremiumItem item = player.getPremiumItems().getItem((int) _id);
if (item == null || item.getItem() == null || item.getItem().getCount() < 1)
{
player.sendPacket(ExGoodsInventoryResult.NOT_EXISTS, ActionFail.STATIC);
return;
}
player.setInGoodsInventory(true);
try
{
ItemUtils.addItem(player, item.getItem());
player.getPremiumItems().updateItem((int) _id, 0);
}
catch (Exception e)
{
player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC);
}
finally
{
player.setInGoodsInventory(false);
}
player.sendPacket(ExGoodsInventoryResult.SUCCESS, new ExGoodsInventoryInfo(player, 1));
}
}
}
Well, implement it - the packages there are simple, the main thing is to think through the system of working with all this.
For example, in my case this inventory is a separate entity and is linked to accounts, not to specific characters, i.e. it is common for all characters on the account.
Well, by the way, it is more convenient than the usual inventory of premium goods in that here you can immediately issue sets of items in a pack.
something like this
Посмотреть вложение 85134
I can post the package structures here, as they look in hamster, if needed, but implement the rest yourself.
спасибо буду пробовать думаю все получится )Код само собой под овероподобные сборки, т.к. у меня сервер на базе овера, но тут главное понять сами структуры и логику работы с этим инвентарем, чтобы написать все под мобиусJava:EX_GOODS_INVENTORY_CHANGED_NOTI(0xFE, 0x10C), EX_GOODS_INVENTORY_INFO(0xFE, 0x10D), EX_GOODS_INVENTORY_RESULT(0xFE, 0x10E),
Java:package l2p.gameserver.network.s2c.goods; import java.util.Collection; import java.util.Collections; import java.util.stream.Collectors; import l2p.gameserver.holders.items.ItemData; import l2p.gameserver.holders.items.PremiumItem; import l2p.gameserver.managers.GoodsManager; import l2p.gameserver.model.Player; import l2p.gameserver.network.components.ServerPackets; import l2p.gameserver.network.s2c.L2GameServerPacket; public class ExGoodsInventoryInfo extends L2GameServerPacket { private int _mode; private Collection<PremiumItem> _goods = Collections.emptyList(); private Collection<PremiumItem> _items = Collections.emptyList(); public ExGoodsInventoryInfo(Player player, int mode) { _mode = mode; _goods = GoodsManager.getInstance().getGoods(player).values().stream().limit(100).collect(Collectors.toList()); _items = player.getPremiumItems().getItems().values().stream().limit(100 - _goods.size()).collect(Collectors.toList()); } @Override protected void writeImpl() { writeId(ServerPackets.EX_GOODS_INVENTORY_INFO); writeH(0); writeH(_goods.size() + _items.size()); for (PremiumItem goods : _goods) { writeC(0x01); writeQ(goods.getUid()); writeD(goods.getIconId()); // номер иконки из GoodsIcon.dat writeS(goods.getGoodsName()); // название товара writeS(goods.getGoodsDesc()); // описание товара writeQ(_mode == 0 ? 60 : 0); // время автоматического обновления списка (в секундах) writeC(0x02); // цвет названия товара (2 - желтый если предыдущий параметр > 0, другие значения - белый) writeC(!goods.getSenderName().isEmpty()); // 1 - показать информацию об отправителе, 0 - не показывать writeS(goods.getSenderName()); // имя отправителя writeS(goods.getSenderMessage()); // сообщение от отправителя writeQ(Long.MAX_VALUE); // возможно время, когда товар исчезнет? writeH(goods.getItems().size()); // количество вещей в товаре for (ItemData item : goods.getItems()) { writeD(item.getId()); writeD((int) item.getCount()); } } for (PremiumItem item : _items) { writeC(0x00); writeQ(item.getUid()); writeC(!item.getSenderName().isEmpty()); // 1 - показать имя отправителя, 0 - не показывать writeS(item.getSenderName()); // имя отправителя writeD(item.getItem().getId()); // id вещи writeQ(item.getItem().getCount()); // количество } } }
Java:package l2p.gameserver.network.s2c.goods; import l2p.gameserver.network.components.ServerPackets; import l2p.gameserver.network.s2c.L2GameServerPacket; public class ExGoodsInventoryChangedNotify extends L2GameServerPacket { public static final L2GameServerPacket STATIC = new ExGoodsInventoryChangedNotify(); @Override protected void writeImpl() { writeId(ServerPackets.EX_GOODS_INVENTORY_CHANGED_NOTI); } }
Java:package l2p.gameserver.network.s2c.goods; import l2p.gameserver.network.components.ServerPackets; import l2p.gameserver.network.s2c.L2GameServerPacket; public class ExGoodsInventoryResult extends L2GameServerPacket { public static final L2GameServerPacket NOTHING = new ExGoodsInventoryResult(1); public static final L2GameServerPacket SUCCESS = new ExGoodsInventoryResult(2); public static final L2GameServerPacket ERROR = new ExGoodsInventoryResult(-1); public static final L2GameServerPacket TRY_AGAIN_LATER = new ExGoodsInventoryResult(-2); public static final L2GameServerPacket INVENTORY_FULL = new ExGoodsInventoryResult(-3); public static final L2GameServerPacket NOT_CONNECT_TO_PRODUCT_SERVER = new ExGoodsInventoryResult(-4); public static final L2GameServerPacket CANT_USE_AT_TRADE_OR_PRIVATE_SHOP = new ExGoodsInventoryResult(-5); public static final L2GameServerPacket NOT_EXISTS = new ExGoodsInventoryResult(-6); public static final L2GameServerPacket TO_MANY_USERS_TRY_AGAIN_INVENTORY = new ExGoodsInventoryResult(-101); public static final L2GameServerPacket TO_MANY_USERS_TRY_AGAIN = new ExGoodsInventoryResult(-102); public static final L2GameServerPacket PREVIOS_REQUEST_IS_NOT_COMPLETE = new ExGoodsInventoryResult(-103); public static final L2GameServerPacket CHANGED = new ExGoodsInventoryResult(-104); public static final L2GameServerPacket ALREADY_RETRACTED = new ExGoodsInventoryResult(-105); public static final L2GameServerPacket ALREADY_RECIVED = new ExGoodsInventoryResult(-106); public static final L2GameServerPacket PRODUCT_CANNOT_BE_RECEIVED_AT_CURRENT_SERVER = new ExGoodsInventoryResult(-107); public static final L2GameServerPacket PRODUCT_CANNOT_BE_RECEIVED_AT_CURRENT_PLAYER = new ExGoodsInventoryResult(-108); private int _result; public ExGoodsInventoryResult(int result) { _result = result; } @Override protected void writeImpl() { writeId(ServerPackets.EX_GOODS_INVENTORY_RESULT); writeD(_result); } }
Java:package l2p.gameserver.network.c2s.goods; import l2p.gameserver.config.OtherConfig; import l2p.gameserver.model.Player; import l2p.gameserver.network.c2s.L2GameClientPacket; import l2p.gameserver.network.s2c.ActionFail; import l2p.gameserver.network.s2c.goods.ExGoodsInventoryInfo; public class RequestGoodsInventoryInfo extends L2GameClientPacket { private int _mode; @Override protected void readImpl() { _mode = readC(); } @Override protected void runImpl() { Player player = getPlayer(); if (player == null) return; if (OtherConfig.GOODS_INVENTORY_ENABLED) player.sendPacket(new ExGoodsInventoryInfo(player, _mode)); else player.sendPacket(ActionFail.STATIC); } }
Java:package l2p.gameserver.network.c2s.goods; import l2p.gameserver.holders.items.PremiumItem; import l2p.gameserver.managers.GoodsManager; import l2p.gameserver.model.Player; import l2p.gameserver.network.c2s.L2GameClientPacket; import l2p.gameserver.network.s2c.ActionFail; import l2p.gameserver.network.s2c.goods.*; import l2p.gameserver.utils.ItemUtils; public class RequestUseGoodsInventoryItem extends L2GameClientPacket { private int _mode; private long _id; @SuppressWarnings("unused") private long _unk; @Override protected void readImpl() { _mode = readC(); _id = readQ(); _unk = _mode == 0 ? readQ() : 0L; } @Override protected void runImpl() { Player player = getPlayer(); if (player == null) return; if (player.isActionsDisabled()) { player.sendPacket(ActionFail.STATIC); return; } if (player.isInGoodsInventory()) { player.sendPacket(ExGoodsInventoryResult.PREVIOS_REQUEST_IS_NOT_COMPLETE, ActionFail.STATIC); return; } if (player.getPremiumItems().isEmpty() && GoodsManager.getInstance().getGoods(player).isEmpty()) { player.sendPacket(ExGoodsInventoryResult.NOT_EXISTS, ActionFail.STATIC); return; } if (!ItemUtils.checkInventory(player, false)) { player.sendPacket(ExGoodsInventoryResult.INVENTORY_FULL, ActionFail.STATIC); return; } if (player.isInTrade() || player.isInPrivateStore()) { player.sendPacket(ExGoodsInventoryResult.CANT_USE_AT_TRADE_OR_PRIVATE_SHOP, ActionFail.STATIC); return; } if (_mode == 1) { PremiumItem goods = GoodsManager.getInstance().getGoods(player, (int) _id); if (goods == null) { player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC); return; } player.setInGoodsInventory(true); try { goods.getItems().forEach(item -> ItemUtils.addItem(player, item)); GoodsManager.getInstance().updateGoods(player, (int) _id); } catch (Exception e) { player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC); } finally { player.setInGoodsInventory(false); } player.sendPacket(ExGoodsInventoryResult.SUCCESS, new ExGoodsInventoryInfo(player, 1)); } else { PremiumItem item = player.getPremiumItems().getItem((int) _id); if (item == null || item.getItem() == null || item.getItem().getCount() < 1) { player.sendPacket(ExGoodsInventoryResult.NOT_EXISTS, ActionFail.STATIC); return; } player.setInGoodsInventory(true); try { ItemUtils.addItem(player, item.getItem()); player.getPremiumItems().updateItem((int) _id, 0); } catch (Exception e) { player.sendPacket(ExGoodsInventoryResult.ERROR, ActionFail.STATIC); } finally { player.setInGoodsInventory(false); } player.sendPacket(ExGoodsInventoryResult.SUCCESS, new ExGoodsInventoryInfo(player, 1)); } } }
package org.l2jmobius.gameserver.network.serverpackets.goods;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.WritableBuffer;
import org.l2jmobius.gameserver.data.xml.ItemData;
import org.l2jmobius.gameserver.model.PremiumItem;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.ServerPackets;
import l2p.gameserver.managers.GoodsManager;
import org.l2jmobius.gameserver.network.serverpackets.ServerPacket;
public class ExGoodsInventoryInfo extends ServerPacket
{
private int _mode;
private Collection<PremiumItem> _goods = Collections.emptyList();
private Collection<PremiumItem> _items = Collections.emptyList();
public ExGoodsInventoryInfo(Player player, int mode)
{
_mode = mode;
_goods = GoodsManager.getInstance().getGoods(player).values().stream().limit(100).collect(Collectors.toList());
_items = player.getPremiumItemList().getItems().values().stream().limit(100 - _goods.size()).collect(Collectors.toList());
}
@Override
protected void writeImpl(GameClient client, WritableBuffer buffer) throws Exception
{
buffer.writeShort(ServerPackets.EX_GOODS_INVENTORY_INFO);
buffer.writeShort(0);
buffer.writeShort(_goods.size() + _items.size());
for (PremiumItem goods : _goods)
{
writeC(0x01);
writeQ(goods.getUid());
writeD(goods.getIconId()); // номер иконки из GoodsIcon.dat
writeS(goods.getGoodsName()); // название товара
writeS(goods.getGoodsDesc()); // описание товара
writeQ(_mode == 0 ? 60 : 0); // время автоматического обновления списка (в секундах)
writeC(0x02); // цвет названия товара (2 - желтый если предыдущий параметр > 0, другие значения - белый)
writeC(!goods.getSenderName().isEmpty()); // 1 - показать информацию об отправителе, 0 - не показывать
writeS(goods.getSenderName()); // имя отправителя
writeS(goods.getSenderMessage()); // сообщение от отправителя
writeQ(Long.MAX_VALUE); // возможно время, когда товар исчезнет?
writeH(goods.getItems().size()); // количество вещей в товаре
for (ItemData item : goods.getItems())
{
writeD(item.getId());
writeD((int) item.getCount());
}
}
for (PremiumItem item : _items)
{
writeC(0x00);
writeQ(item.getUid());
writeC(!item.getSenderName().isEmpty()); // 1 - показать имя отправителя, 0 - не показывать
writeS(item.getSenderName()); // имя отправителя
writeD(item.getItem().getId()); // id вещи
writeQ(item.getItem().getCount()); // количество
}
}
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?