From 30801697d924ff15f993466d9f91e4fd637de521 Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 29 Oct 2016 00:28:37 +0530 Subject: [PATCH 1/2] Send items sitting on the floor through remoteFortressReader --- plugins/proto/RemoteFortressReader.proto | 11 ++++ plugins/remotefortressreader.cpp | 84 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index 4c049d1a9..6b730d8c2 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -206,6 +206,16 @@ message SpatterPile repeated Spatter spatters = 1; } +message Item +{ + optional int32 id = 1; + optional Coord pos = 2; + optional uint32 flags1 = 3; + optional uint32 flags2 = 4; + optional MatPair type = 5; + optional MatPair material = 6; +} + message MapBlock { required int32 map_x = 1; @@ -233,6 +243,7 @@ message MapBlock repeated int32 tree_z = 23; repeated TileDigDesignation tile_dig_designation = 24; repeated SpatterPile spatterPile = 25; + repeated Item items = 26; } message MatPair { diff --git a/plugins/remotefortressreader.cpp b/plugins/remotefortressreader.cpp index 05ad56e75..5c5068ed2 100644 --- a/plugins/remotefortressreader.cpp +++ b/plugins/remotefortressreader.cpp @@ -141,6 +141,7 @@ static command_result GetPlantRaws(color_ostream &stream, const EmptyMessage *in static command_result CopyScreen(color_ostream &stream, const EmptyMessage *in, ScreenCapture *out); static command_result PassKeyboardEvent(color_ostream &stream, const KeyboardEvent *in); static command_result SendDigCommand(color_ostream &stream, const DigCommand *in); +void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem); void CopyBlock(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBlock, MapExtras::MapCache * MC, DFCoord pos); @@ -958,12 +959,45 @@ bool IsspatterChanged(DFCoord pos) return false; } +map itemHashes; + +bool isItemChanged(int i) +{ + uint16_t hash = 0; + if (i >= 0 && i < world->items.all.size()) + { + auto item = world->items.all[i]; + if (item) + { + hash = fletcher16((uint8_t*)item, sizeof(df::item)); + } + } + if (itemHashes[i] != hash) + { + itemHashes[i] = hash; + return true; + } + return false; +} + +bool areItemsChanged(vector * items) +{ + bool result = false; + for (int i = 0; i < items->size(); i++) + { + if (isItemChanged(items->at(i))) + result = true; + } + return result; +} + static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *in) { hashes.clear(); waterHashes.clear(); buildingHashes.clear(); spatterHashes.clear(); + itemHashes.clear(); return CR_OK; } @@ -1417,6 +1451,17 @@ void CopyBuildings(df::map_block * DfBlock, RemoteFortressReader::MapBlock * Net continue; auto out_bld = NetBlock->add_buildings(); CopyBuilding(i, out_bld); + df::building_actual* actualBuilding = strict_virtual_cast(bld); + if (actualBuilding) + { + for (int i = 0; i < actualBuilding->contained_items.size(); i++) + { + if (isItemChanged(actualBuilding->contained_items[i]->item->id)) + { + CopyItem(NetBlock->add_items(), actualBuilding->contained_items[i]->item); + } + } + } } } @@ -1459,6 +1504,42 @@ void Copyspatters(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetB } } +void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem) +{ + NetItem->set_id(DfItem->id); + NetItem->set_flags1(DfItem->flags.whole); + NetItem->set_flags2(DfItem->flags2.whole); + auto pos = NetItem->mutable_pos(); + pos->set_x(DfItem->pos.x); + pos->set_y(DfItem->pos.y); + pos->set_z(DfItem->pos.z); + auto mat = NetItem->mutable_material(); + mat->set_mat_index(DfItem->getMaterialIndex()); + mat->set_mat_type(DfItem->getMaterial()); + auto type = NetItem->mutable_type(); + type->set_mat_type(DfItem->getType()); + type->set_mat_index(DfItem->getSubtype()); +} + +void CopyItems(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBlock, MapExtras::MapCache * MC, DFCoord pos) +{ + NetBlock->set_map_x(DfBlock->map_pos.x); + NetBlock->set_map_y(DfBlock->map_pos.y); + NetBlock->set_map_z(DfBlock->map_pos.z); + for (int i = 0; i < DfBlock->items.size(); i++) + { + int id = DfBlock->items[i]; + + if (id < 0) + continue; + if (id >= world->items.all.size()) + continue; + + auto item = world->items.all[id]; + CopyItem(NetBlock->add_items(), item); + } +} + static command_result GetBlockList(color_ostream &stream, const BlockRequest *in, BlockList *out) { int x, y, z; @@ -1518,6 +1599,7 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in bool desChanged = IsDesignationChanged(pos); bool spatterChanged = IsspatterChanged(pos); bool buildingChanged = IsBuildingChanged(pos); + bool itemsChanged = areItemsChanged(&block->items); //bool bldChanged = IsBuildingChanged(pos); RemoteFortressReader::MapBlock *net_block; if (tileChanged || desChanged || spatterChanged || buildingChanged) @@ -1533,6 +1615,8 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in CopyBuildings(block, net_block, &MC, pos); if (spatterChanged) Copyspatters(block, net_block, &MC, pos); + if (itemsChanged) + CopyItems(block, net_block, &MC, pos); } } } From 148202bcba8c700647fc7b79acb62a0a3a29a93e Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 29 Oct 2016 08:54:27 +0530 Subject: [PATCH 2/2] Use Binsearch for finding items. --- plugins/remotefortressreader.cpp | 42 ++++++++++++++------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/plugins/remotefortressreader.cpp b/plugins/remotefortressreader.cpp index 5c5068ed2..0ec2056db 100644 --- a/plugins/remotefortressreader.cpp +++ b/plugins/remotefortressreader.cpp @@ -964,13 +964,10 @@ map itemHashes; bool isItemChanged(int i) { uint16_t hash = 0; - if (i >= 0 && i < world->items.all.size()) + auto item = df::item::find(i); + if (item) { - auto item = world->items.all[i]; - if (item) - { - hash = fletcher16((uint8_t*)item, sizeof(df::item)); - } + hash = fletcher16((uint8_t*)item, sizeof(df::item)); } if (itemHashes[i] != hash) { @@ -1451,17 +1448,17 @@ void CopyBuildings(df::map_block * DfBlock, RemoteFortressReader::MapBlock * Net continue; auto out_bld = NetBlock->add_buildings(); CopyBuilding(i, out_bld); - df::building_actual* actualBuilding = strict_virtual_cast(bld); - if (actualBuilding) - { - for (int i = 0; i < actualBuilding->contained_items.size(); i++) - { - if (isItemChanged(actualBuilding->contained_items[i]->item->id)) - { - CopyItem(NetBlock->add_items(), actualBuilding->contained_items[i]->item); - } - } - } + //df::building_actual* actualBuilding = strict_virtual_cast(bld); + //if (actualBuilding) + //{ + // for (int i = 0; i < actualBuilding->contained_items.size(); i++) + // { + // if (isItemChanged(actualBuilding->contained_items[i]->item->id)) + // { + // CopyItem(NetBlock->add_items(), actualBuilding->contained_items[i]->item); + // } + // } + //} } } @@ -1530,13 +1527,10 @@ void CopyItems(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBloc { int id = DfBlock->items[i]; - if (id < 0) - continue; - if (id >= world->items.all.size()) - continue; - - auto item = world->items.all[id]; - CopyItem(NetBlock->add_items(), item); + + auto item = df::item::find(id); + if(item) + CopyItem(NetBlock->add_items(), item); } }