forked from oerkki/voxelands
inventory should only be updated when digging/placing, don't send the whole thing
This commit is contained in:
parent
e780ed8cd7
commit
d34f87b459
|
@ -1102,6 +1102,36 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
m_inventory_updated = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TOCLIENT_INVENTORY_UPDATE:
|
||||
{
|
||||
if (datasize < 3)
|
||||
return;
|
||||
{
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
assert(player != NULL);
|
||||
|
||||
u16 list_count = readU16(is);
|
||||
for (int i=0; i<list_count; i++) {
|
||||
std::string name = deSerializeString(is);
|
||||
u16 slots = readU16(is);
|
||||
InventoryList *l = player->inventory.getList(name);
|
||||
if (!l)
|
||||
return;
|
||||
for (int k=0; k<slots; k++) {
|
||||
u16 index = readU16(is);
|
||||
u16 type = readU16(is);
|
||||
u16 count = readU16(is);
|
||||
l->updateItem(index,type,count);
|
||||
}
|
||||
}
|
||||
|
||||
m_inventory_updated = true;
|
||||
}
|
||||
}
|
||||
//DEBUG
|
||||
break;
|
||||
case TOCLIENT_OBJECTDATA:
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "utility.h"
|
||||
|
||||
#define PROTOCOL_VERSION 8
|
||||
#define PROTOCOL_VERSION 9
|
||||
/* the last protocol version used by 0.3.x minetest-c55 clients */
|
||||
#define PROTOCOL_DOTTHREE 3
|
||||
/* this is the oldest protocol that we will allow to connect
|
||||
|
@ -221,11 +221,12 @@ enum ToClientCommand
|
|||
[0] u16 command
|
||||
[2] u16 player count
|
||||
[4] u16 field count
|
||||
for each player:
|
||||
for each player {
|
||||
u16 peer_id
|
||||
char[20] name
|
||||
u16 length of serialized chardef
|
||||
string serialized character definition
|
||||
}
|
||||
*/
|
||||
|
||||
TOCLIENT_ENV_EVENT = 0x41,
|
||||
|
@ -236,6 +237,22 @@ enum ToClientCommand
|
|||
u16 length of serialised event data
|
||||
string serialised event data
|
||||
*/
|
||||
|
||||
TOCLIENT_INVENTORY_UPDATE = 0x42,
|
||||
/*
|
||||
u16 command
|
||||
u16 list count
|
||||
for each list {
|
||||
u16 length of serialised list name
|
||||
string serialised list name
|
||||
u16 slot count
|
||||
for each slot {
|
||||
u16 slot index
|
||||
u16 content type
|
||||
u16 count/wear
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
enum ToServerCommand
|
||||
|
|
|
@ -338,8 +338,10 @@ InventoryList::~InventoryList()
|
|||
void InventoryList::clearItems()
|
||||
{
|
||||
for (u32 i=0; i<m_items.size(); i++) {
|
||||
if (m_items[i])
|
||||
if (m_items[i]) {
|
||||
delete m_items[i];
|
||||
m_diff.add(m_name,i,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
|
@ -537,6 +539,7 @@ InventoryItem * InventoryList::changeItem(u32 i, InventoryItem *newitem)
|
|||
|
||||
InventoryItem *olditem = m_items[i];
|
||||
m_items[i] = newitem;
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return olditem;
|
||||
}
|
||||
|
||||
|
@ -546,6 +549,7 @@ void InventoryList::deleteItem(u32 i)
|
|||
InventoryItem *item = changeItem(i, NULL);
|
||||
if (item)
|
||||
delete item;
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
}
|
||||
|
||||
InventoryItem * InventoryList::addItem(InventoryItem *newitem)
|
||||
|
@ -605,15 +609,18 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
|
|||
newitem->remove(1);
|
||||
m_items[i] = newitem->clone();
|
||||
m_items[i]->setCount(1);
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return newitem;
|
||||
}
|
||||
m_items[i] = newitem;
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return to_item;
|
||||
}
|
||||
|
||||
// If it is an empty position, it's an easy job.
|
||||
if (to_item == NULL) {
|
||||
m_items[i] = newitem;
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -624,6 +631,7 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
|
|||
// If the item fits fully in the slot, add counter and delete it
|
||||
if (newitem->getCount() <= to_item->freeSpace()) {
|
||||
to_item->add(newitem->getCount());
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
delete newitem;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -634,11 +642,37 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
|
|||
if (!freespace)
|
||||
return newitem;
|
||||
to_item->add(freespace);
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
newitem->remove(freespace);
|
||||
return newitem;
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryList::updateItem(u32 i, content_t type, u16 wear_count)
|
||||
{
|
||||
if (type == CONTENT_IGNORE) {
|
||||
if (m_items[i] != NULL)
|
||||
delete m_items[i];
|
||||
m_items[i] = NULL;
|
||||
return;
|
||||
}
|
||||
if (m_items[i] != NULL) {
|
||||
if (m_items[i]->getContent() == type) {
|
||||
if (
|
||||
(type&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK
|
||||
|| (type&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK
|
||||
) {
|
||||
m_items[i]->setWear(wear_count);
|
||||
}else{
|
||||
m_items[i]->setCount(wear_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
delete m_items[i];
|
||||
}
|
||||
m_items[i] = InventoryItem::create(type,wear_count,wear_count);
|
||||
}
|
||||
|
||||
bool InventoryList::itemFits(const u32 i, const InventoryItem *newitem)
|
||||
{
|
||||
// If it is an empty position, it's an easy job.
|
||||
|
@ -659,18 +693,19 @@ bool InventoryList::itemFits(const u32 i, const InventoryItem *newitem)
|
|||
|
||||
bool InventoryList::roomForItem(const InventoryItem *item)
|
||||
{
|
||||
for(u32 i=0; i<m_items.size(); i++)
|
||||
if(itemFits(i, item))
|
||||
for (u32 i=0; i<m_items.size(); i++) {
|
||||
if (itemFits(i, item))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InventoryList::roomForCookedItem(const InventoryItem *item)
|
||||
{
|
||||
if(!item)
|
||||
if (!item)
|
||||
return false;
|
||||
const InventoryItem *cook = item->createCookResult();
|
||||
if(!cook)
|
||||
if (!cook)
|
||||
return false;
|
||||
bool room = roomForItem(cook);
|
||||
delete cook;
|
||||
|
@ -689,11 +724,14 @@ InventoryItem * InventoryList::takeItem(u32 i, u32 count)
|
|||
|
||||
if (count >= item->getCount()) {
|
||||
// Get the item by swapping NULL to its place
|
||||
return changeItem(i, NULL);
|
||||
InventoryItem *item = changeItem(i, NULL);
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return item;
|
||||
}else{
|
||||
InventoryItem *item2 = item->clone();
|
||||
item->remove(count);
|
||||
item2->setCount(count);
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
return item2;
|
||||
}
|
||||
|
||||
|
@ -719,6 +757,7 @@ void InventoryList::decrementMaterials(u16 count)
|
|||
InventoryItem *item = takeItem(i, count);
|
||||
if (item)
|
||||
delete item;
|
||||
m_diff.add(m_name,i,m_items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -519,6 +519,74 @@ private:
|
|||
u16 m_wear;
|
||||
};
|
||||
|
||||
class InventoryDiffData
|
||||
{
|
||||
public:
|
||||
InventoryDiffData(u32 i, content_t t, u16 c):
|
||||
index(i),
|
||||
type(t),
|
||||
wear_count(c)
|
||||
{
|
||||
}
|
||||
InventoryDiffData():
|
||||
index(0),
|
||||
type(CONTENT_IGNORE),
|
||||
wear_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
u32 index;
|
||||
content_t type;
|
||||
u16 wear_count;
|
||||
};
|
||||
|
||||
class InventoryDiff
|
||||
{
|
||||
public:
|
||||
InventoryDiff()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
~InventoryDiff()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
void add(std::string list, u32 index, content_t type, u16 count_wear)
|
||||
{
|
||||
m_data[list][index] = InventoryDiffData(index,type,count_wear);
|
||||
}
|
||||
|
||||
void add(std::string list, u32 index, InventoryItem *item)
|
||||
{
|
||||
if (item == NULL) {
|
||||
add(list,index,CONTENT_IGNORE,0);
|
||||
}else if (
|
||||
(item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK
|
||||
|| (item->getContent()&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK
|
||||
) {
|
||||
add(list,index,item->getContent(),item->getWear());
|
||||
}else{
|
||||
add(list,index,item->getContent(),item->getCount());
|
||||
}
|
||||
}
|
||||
|
||||
void merge(InventoryDiff &other)
|
||||
{
|
||||
for (std::map<std::string,std::map<u32,InventoryDiffData> >::iterator i = other.m_data.begin(); i != other.m_data.end(); i++) {
|
||||
m_data[i->first].swap(i->second);
|
||||
i->second.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string,std::map<u32,InventoryDiffData> > m_data;
|
||||
};
|
||||
|
||||
class InventoryList
|
||||
{
|
||||
public:
|
||||
|
@ -579,6 +647,9 @@ public:
|
|||
// If can be added fully, NULL is returned.
|
||||
InventoryItem * addItem(u32 i, InventoryItem *newitem);
|
||||
|
||||
// Updates item type/count/wear
|
||||
void updateItem(u32 i, content_t type, u16 wear_count);
|
||||
|
||||
// Checks whether the item could be added to the given slot
|
||||
bool itemFits(const u32 i, const InventoryItem *newitem);
|
||||
|
||||
|
@ -601,6 +672,9 @@ public:
|
|||
|
||||
void print(std::ostream &o);
|
||||
|
||||
void addDiff(u32 index, InventoryItem *item) {m_diff.add(m_name,index,item);}
|
||||
InventoryDiff &getDiff() {return m_diff;}
|
||||
|
||||
private:
|
||||
core::array<InventoryItem*> m_items;
|
||||
u32 m_size;
|
||||
|
@ -608,7 +682,7 @@ private:
|
|||
std::map<content_t,bool> m_allowed;
|
||||
std::map<content_t,bool> m_denied;
|
||||
bool m_stackable;
|
||||
//bool m_dirty;
|
||||
InventoryDiff m_diff;
|
||||
};
|
||||
|
||||
class Inventory
|
||||
|
@ -634,16 +708,26 @@ public:
|
|||
InventoryItem * addItem(const std::string &listname, InventoryItem *newitem)
|
||||
{
|
||||
InventoryList *list = getList(listname);
|
||||
if(list == NULL)
|
||||
if (list == NULL)
|
||||
return newitem;
|
||||
return list->addItem(newitem);
|
||||
}
|
||||
InventoryDiff &getDiff()
|
||||
{
|
||||
m_diff.clear();
|
||||
for (u32 i=0; i<m_lists.size(); i++) {
|
||||
InventoryDiff &diff = m_lists[i]->getDiff();
|
||||
m_diff.merge(diff);
|
||||
}
|
||||
return m_diff;
|
||||
}
|
||||
|
||||
private:
|
||||
// -1 if not found
|
||||
const s32 getListIndex(const std::string &name) const;
|
||||
|
||||
core::array<InventoryList*> m_lists;
|
||||
InventoryDiff m_diff;
|
||||
};
|
||||
|
||||
class Player;
|
||||
|
|
147
src/server.cpp
147
src/server.cpp
|
@ -2024,7 +2024,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|
||||
// Send inventory to player
|
||||
UpdateCrafting(peer_id);
|
||||
SendInventory(peer_id);
|
||||
SendInventory(peer_id,true);
|
||||
|
||||
// Send player items to all players
|
||||
SendPlayerItems();
|
||||
|
@ -2151,15 +2151,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
thrown = content_craftitem_features(item->getContent()).shot_item;
|
||||
if (thrown == CONTENT_IGNORE)
|
||||
return;
|
||||
item_i = i;
|
||||
if (g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(1000);
|
||||
if (weared_out) {
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
ilist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
item_i = i;
|
||||
}
|
||||
|
||||
if (g_settings->getBool("droppable_inventory") == false || (getPlayerPrivs(player) & PRIV_BUILD) == 0) {
|
||||
|
@ -2403,8 +2405,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
|
||||
if (titem && g_settings->getBool("tool_wear")) {
|
||||
if (titem->addWear(wear))
|
||||
if (titem->addWear(wear)) {
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
}
|
||||
|
@ -2550,9 +2555,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
ToolItem *titem = (ToolItem*)wield;
|
||||
if ((getPlayerPrivs(player) & PRIV_SERVER) == 0 && g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(10000);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -2792,9 +2799,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
ToolItem *titem = (ToolItem*)wield;
|
||||
if (g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(1000);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -2826,9 +2835,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
ToolItem *titem = (ToolItem*)wield;
|
||||
if (g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(1000);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -2943,9 +2954,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
ToolItem *titem = (ToolItem*)wield;
|
||||
if (g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(200);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -2993,6 +3006,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
ilist->deleteItem(item_i);
|
||||
}else{
|
||||
wield->remove(1);
|
||||
ilist->addDiff(item_i,wield);
|
||||
}
|
||||
// Send inventory
|
||||
UpdateCrafting(peer_id);
|
||||
|
@ -3557,7 +3571,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
std::string dug_s = std::string("ToolItem ") + tool->getToolName() + "_water 1";
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
mlist->changeItem(item_i,item);
|
||||
InventoryItem *ritem = mlist->changeItem(item_i,item);
|
||||
if (ritem)
|
||||
delete ritem;
|
||||
item = NULL;
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
|
@ -3592,14 +3608,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
{
|
||||
u16 peer_id = *i;
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
if(client==NULL)
|
||||
if (client==NULL)
|
||||
continue;
|
||||
client->SetBlocksNotSent(modified_blocks);
|
||||
}
|
||||
std::string dug_s = std::string("ToolItem ") + tool->getToolName() + "_water 1";
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
mlist->changeItem(item_i,item);
|
||||
InventoryItem *ritem = mlist->changeItem(item_i,item);
|
||||
if (ritem)
|
||||
delete ritem;
|
||||
item = NULL;
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
|
@ -3618,7 +3636,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
std::string dug_s = std::string("ToolItem ") + tool->getToolName() + "_lava 1";
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
mlist->changeItem(item_i,item);
|
||||
InventoryItem *ritem = mlist->changeItem(item_i,item);
|
||||
if (ritem)
|
||||
delete ritem;
|
||||
item = NULL;
|
||||
}
|
||||
UpdateCrafting(player->peer_id);
|
||||
|
@ -3675,13 +3695,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
&& material != CONTENT_WATER
|
||||
&& material != CONTENT_LAVA
|
||||
) {
|
||||
bool dosend = false;
|
||||
if (item != NULL) {
|
||||
// Add a item to inventory
|
||||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
dosend = true;
|
||||
}
|
||||
|
||||
item = NULL;
|
||||
|
@ -3704,6 +3724,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
dosend = true;
|
||||
}
|
||||
if (dosend) {
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -4028,10 +4051,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
InventoryList *ilist = player->inventory.getList("main");
|
||||
if(g_settings->getBool("infinite_inventory") == false && ilist) {
|
||||
// Remove from inventory and send inventory
|
||||
if (mitem->getCount() == 1)
|
||||
if (mitem->getCount() == 1) {
|
||||
ilist->deleteItem(item_i);
|
||||
else
|
||||
}else{
|
||||
mitem->remove(1);
|
||||
ilist->addDiff(item_i,mitem);
|
||||
}
|
||||
// Send inventory
|
||||
UpdateCrafting(peer_id);
|
||||
SendInventory(peer_id);
|
||||
|
@ -4233,12 +4258,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (g_settings->getBool("infinite_inventory") == false) {
|
||||
// Delete the right amount of items from the slot
|
||||
u16 dropcount = item->getDropCount();
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
// Delete item if all gone
|
||||
if (item->getCount() <= dropcount) {
|
||||
if (item->getCount() < dropcount)
|
||||
infostream<<"WARNING: Server: dropped more items"
|
||||
<<" than the slot contains"<<std::endl;
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
// Remove from inventory and send inventory
|
||||
if (ilist)
|
||||
ilist->deleteItem(item_i);
|
||||
|
@ -4246,6 +4271,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
// Else decrement it
|
||||
else{
|
||||
item->remove(dropcount);
|
||||
ilist->addDiff(item_i,item);
|
||||
}
|
||||
// Send inventory
|
||||
UpdateCrafting(peer_id);
|
||||
|
@ -4287,6 +4313,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (g_settings->getBool("infinite_inventory") == false) {
|
||||
// Delete the right amount of items from the slot
|
||||
u16 dropcount = item->getDropCount();
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
|
||||
// Delete item if all gone
|
||||
if (item->getCount() <= dropcount) {
|
||||
|
@ -4294,12 +4321,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
infostream<<"WARNING: Server: dropped more items"
|
||||
<<" than the slot contains"<<std::endl;
|
||||
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
if (ilist)
|
||||
// Remove from inventory and send inventory
|
||||
ilist->deleteItem(item_i);
|
||||
}else{
|
||||
item->remove(dropcount);
|
||||
ilist->addDiff(item_i,item);
|
||||
}
|
||||
|
||||
// Send inventory
|
||||
|
@ -4368,6 +4395,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (g_settings->getBool("infinite_inventory") == false) {
|
||||
// Delete the right amount of items from the slot
|
||||
u16 dropcount = item->getDropCount();
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
|
||||
// Delete item if all gone
|
||||
if (item->getCount() <= dropcount) {
|
||||
|
@ -4375,7 +4403,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
infostream<<"WARNING: Server: dropped more items"
|
||||
<<" than the slot contains"<<std::endl;
|
||||
|
||||
InventoryList *ilist = player->inventory.getList("main");
|
||||
if(ilist)
|
||||
// Remove from inventory and send inventory
|
||||
ilist->deleteItem(item_i);
|
||||
|
@ -4383,6 +4410,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
// Else decrement it
|
||||
else{
|
||||
item->remove(dropcount);
|
||||
ilist->addDiff(item_i,item);
|
||||
}
|
||||
|
||||
// Send inventory
|
||||
|
@ -4482,8 +4510,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
fw /= bonus;
|
||||
w = fw;
|
||||
}
|
||||
if (i->addWear(w))
|
||||
if (i->addWear(w)) {
|
||||
l->deleteItem(0);
|
||||
}else{
|
||||
l->addDiff(0,i);
|
||||
}
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
return;
|
||||
|
@ -4652,7 +4683,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
dir.rotateXZBy(player->getYaw());
|
||||
pos += dir;
|
||||
ServerActiveObject *obj = item->createSAO(&m_env,0,pos);
|
||||
m_env.addActiveObject(obj);
|
||||
if (obj)
|
||||
m_env.addActiveObject(obj);
|
||||
}
|
||||
if (g_settings->getBool("infinite_inventory") == false) {
|
||||
list->deleteItem(0);
|
||||
|
@ -4662,9 +4694,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
// Eat the action
|
||||
delete a;
|
||||
}
|
||||
else
|
||||
{
|
||||
}else{
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
|
@ -5017,8 +5047,7 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
|
|||
Strfnd fn(id);
|
||||
std::string id0 = fn.next(":");
|
||||
|
||||
if(id0 == "nodemeta")
|
||||
{
|
||||
if (id0 == "nodemeta") {
|
||||
v3s16 p;
|
||||
p.X = mystoi(fn.next(","));
|
||||
p.Y = mystoi(fn.next(","));
|
||||
|
@ -5026,15 +5055,14 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
|
|||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
|
||||
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
|
||||
if(meta)
|
||||
if (meta)
|
||||
meta->inventoryModified();
|
||||
|
||||
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
|
||||
if(block)
|
||||
if (block)
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
||||
|
||||
setBlockNotSent(blockpos);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5222,29 +5250,59 @@ void Server::SendPlayerInfos()
|
|||
m_con.SendToAll(0, data, true);
|
||||
}
|
||||
|
||||
void Server::SendInventory(u16 peer_id)
|
||||
void Server::SendInventory(u16 peer_id, bool full)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
Player* player = m_env.getPlayer(peer_id);
|
||||
assert(player);
|
||||
|
||||
/*
|
||||
Serialize it
|
||||
*/
|
||||
// get also clears, so get diff for full and partial sends
|
||||
InventoryDiff idiff = player->inventory.getDiff();
|
||||
|
||||
std::ostringstream os;
|
||||
if (full) {
|
||||
/*
|
||||
Serialize it
|
||||
*/
|
||||
|
||||
player->inventory.serialize(os);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
std::string s = os.str();
|
||||
writeU16(os,TOCLIENT_INVENTORY);
|
||||
player->inventory.serialize(os);
|
||||
|
||||
SharedBuffer<u8> data(s.size()+2);
|
||||
writeU16(&data[0], TOCLIENT_INVENTORY);
|
||||
memcpy(&data[2], s.c_str(), s.size());
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
||||
|
||||
// Send as reliable
|
||||
m_con.Send(peer_id, 0, data, true);
|
||||
// Send as reliable
|
||||
m_con.Send(peer_id, 0, data, true);
|
||||
return;
|
||||
}
|
||||
{
|
||||
if (idiff.m_data.size() == 0)
|
||||
return;
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
writeU16(os, TOCLIENT_INVENTORY_UPDATE);
|
||||
writeU16(os, idiff.m_data.size());
|
||||
for (std::map<std::string,std::map<u32,InventoryDiffData> >::iterator l = idiff.m_data.begin(); l != idiff.m_data.end(); l++) {
|
||||
os<<serializeString(l->first);
|
||||
writeU16(os,l->second.size());
|
||||
for (std::map<u32,InventoryDiffData>::iterator i = l->second.begin(); i != l->second.end(); i++) {
|
||||
writeU16(os,i->second.index);
|
||||
writeU16(os,i->second.type);
|
||||
writeU16(os,i->second.wear_count);
|
||||
}
|
||||
}
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
||||
|
||||
// Send as reliable
|
||||
m_con.Send(peer_id, 0, data, true);
|
||||
}
|
||||
}
|
||||
|
||||
std::string getWieldedItemString(const Player *player)
|
||||
|
@ -5842,15 +5900,12 @@ void Server::UpdateCrafting(u16 peer_id)
|
|||
if(rlist && rlist->getUsedSlots() == 0)
|
||||
player->craftresult_is_preview = true;
|
||||
|
||||
if(rlist && player->craftresult_is_preview)
|
||||
{
|
||||
if (rlist && player->craftresult_is_preview) {
|
||||
rlist->clearItems();
|
||||
}
|
||||
if(clist && rlist && player->craftresult_is_preview)
|
||||
{
|
||||
if (clist && rlist && player->craftresult_is_preview) {
|
||||
InventoryItem *items[9];
|
||||
for(u16 i=0; i<9; i++)
|
||||
{
|
||||
for (u16 i=0; i<9; i++) {
|
||||
items[i] = clist->getItem(i);
|
||||
}
|
||||
|
||||
|
|
|
@ -533,7 +533,7 @@ private:
|
|||
// Envlock and conlock should be locked when calling these
|
||||
void SendObjectData(float dtime);
|
||||
void SendPlayerInfos();
|
||||
void SendInventory(u16 peer_id);
|
||||
void SendInventory(u16 peer_id, bool full=false);
|
||||
// send animation info about player to all
|
||||
void SendPlayerAnim(const Player *player, u8 animation_id);
|
||||
// send wielded item info about all players to all players
|
||||
|
|
Loading…
Reference in New Issue