Forráskód Böngészése

improved safty of world updates

Kolja Strohm 3 éve
szülő
commit
1d4450a75c

+ 0 - 1
FactoryCraft/AddChunkUpdate.cpp

@@ -21,7 +21,6 @@ void AddChunkUpdate::onUpdate( Dimension* zDimension )
 
 void AddChunkUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     int dimensionID = chunk->getDimensionId();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     Framework::Punkt center = chunk->getCenter();

+ 3 - 1
FactoryCraft/AddChunkUpdate.h

@@ -9,12 +9,14 @@ class AddChunkUpdate : public WorldUpdate
 private:
     Chunk* chunk;
 
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     AddChunkUpdate( Chunk* chunk );
     ~AddChunkUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
     Chunk* zChunk() const;
 };
 

+ 0 - 1
FactoryCraft/AddEntityUpdate.cpp

@@ -22,7 +22,6 @@ void AddEntityUpdate::onUpdate( Dimension* zDimension )
 
 void AddEntityUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     int id = entity->zType()->getId();
     zWriter->schreibe( (char*)&id, 4 );
     StaticRegistry<EntityType>::INSTANCE.zElement( id )->saveEntity( entity, zWriter );

+ 3 - 1
FactoryCraft/AddEntityUpdate.h

@@ -7,12 +7,14 @@ class AddEntityUpdate : public WorldUpdate
 private:
     Entity* entity;
 
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     AddEntityUpdate( Entity* entity, int dimension );
     ~AddEntityUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class AddEntityUpdateType : WorldUpdateType

+ 0 - 1
FactoryCraft/BlockChangedUpdate.cpp

@@ -18,7 +18,6 @@ void BlockChangedUpdate::onUpdate( Dimension* zDimension )
 
 void BlockChangedUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     int dimensionID = getAffectedDimension();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     auto pos = getMinAffectedPoint();

+ 3 - 1
FactoryCraft/BlockChangedUpdate.h

@@ -3,12 +3,14 @@
 
 class BlockChangedUpdate : public WorldUpdate
 {
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     BlockChangedUpdate( Framework::Vec3<int> pos, int dimension );
     ~BlockChangedUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class BlockChangedUpdateType : WorldUpdateType

+ 0 - 1
FactoryCraft/BlockRemovedUpdate.cpp

@@ -17,7 +17,6 @@ void BlockRemovedUpdate::onUpdate( Dimension* zDimension )
 
 void BlockRemovedUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     int dimensionID = getAffectedDimension();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     auto pos = getMinAffectedPoint();

+ 3 - 1
FactoryCraft/BlockRemovedUpdate.h

@@ -4,12 +4,14 @@
 
 class BlockRemovedUpdate : public WorldUpdate
 {
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     BlockRemovedUpdate( Framework::Vec3<int> pos, int dimension );
     ~BlockRemovedUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class BlockRemovedUpdateType : WorldUpdateType

+ 29 - 4
FactoryCraft/Entity.cpp

@@ -5,6 +5,7 @@
 #include "ItemSkill.h"
 #include "PlaceBlockUpdate.h"
 #include "EntityRemovedUpdate.h"
+#include "EntityChangedUpdate.h"
 
 
 ActionTarget::ActionTarget( Vec3<int> blockPos, Direction blockSide )
@@ -17,6 +18,16 @@ ActionTarget::ActionTarget( int entityId )
     : entityId( entityId )
 {}
 
+bool ActionTarget::isBlock( Framework::Vec3<int> blockPos, Direction blockSide ) const
+{
+    return this->entityId == -1 && this->blockPos == blockPos && this->targetBlockSide == targetBlockSide;
+}
+
+bool ActionTarget::isEntity( int entityId ) const
+{
+    return this->entityId == entityId;
+}
+
 void ActionTarget::applyItemSkillOnTarget( Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem )
 {
     if( entityId >= 0 )
@@ -74,6 +85,7 @@ Entity::Entity( const EntityType* zType, Framework::Vec3<float> location, int di
     currentDimensionId( dimensionId ),
     removed( 0 ),
     gravityMultiplier( 1.f ),
+    needUpdate( 0 ),
     id( entityId )
 {}
 
@@ -129,8 +141,12 @@ void Entity::prepareTick( const Dimension* zDimension )
     {
         if( getDefaultBlock( Game::INSTANCE->zBlockAt( Vec3<int>{ px, py, pz }, zDimension->getDimensionId() ) )->isInteractable() )
         {
-            delete target;
-            target = new ActionTarget( { px, py, pz }, dir );
+            if( !target || !target->isBlock( { px, py, pz }, dir ) )
+            {
+                delete target;
+                target = new ActionTarget( { px, py, pz }, dir );
+                needUpdate = 1;
+            }
             break;
         }
         // collision to neighbor of current block
@@ -200,8 +216,12 @@ void Entity::prepareTick( const Dimension* zDimension )
                 continue;
             }
         }
-        delete target;
-        target = 0;
+        if( target )
+        {
+            delete target;
+            target = 0;
+            needUpdate = 1;
+        }
         break;
     }
 }
@@ -328,6 +348,11 @@ void Entity::tick( const Dimension* zDimension )
         }
     }
     location += frameSpeed;
+    if( oldPos != location || needUpdate )
+    {
+        needUpdate = 0;
+        Game::INSTANCE->requestWorldUpdate( new EntityChangedUpdate( id, location, currentDimensionId ) );
+    }
 }
 
 void Entity::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )

+ 4 - 0
FactoryCraft/Entity.h

@@ -25,6 +25,9 @@ public:
     ActionTarget( Framework::Vec3<int> blockPos, Direction blockSide );
     ActionTarget( int entityId );
 
+    bool isBlock( Framework::Vec3<int> blockPos, Direction blockSide ) const;
+    bool isEntity( int entityId ) const;
+
     void applyItemSkillOnTarget( Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem );
     void placeBlock( Entity* zActor, Item* zItem );
     void save( Framework::StreamWriter* zWriter ) const;
@@ -51,6 +54,7 @@ protected:
     int currentDimensionId;
     bool removed;
     float gravityMultiplier;
+    bool needUpdate;
     int id;
 
     virtual void onDeath();

+ 5 - 1
FactoryCraft/EntityChangedUpdate.cpp

@@ -20,11 +20,15 @@ void EntityChangedUpdate::write( Framework::StreamWriter* zWriter )
     if( entity )
     {
         int type = entity->zType()->getId();
-        WorldUpdate::write( zWriter );
         zWriter->schreibe( (char*)&entityId, 4 );
         zWriter->schreibe( (char*)&type, 4 );
         StaticRegistry<EntityType>::INSTANCE.zElement( type )->saveEntity( entity, zWriter );
     }
+    else
+    {
+        int id = -1;
+        zWriter->schreibe( (char*)&id, 4 );
+    }
 }
 
 

+ 3 - 1
FactoryCraft/EntityChangedUpdate.h

@@ -7,12 +7,14 @@ class EntityChangedUpdate : public WorldUpdate
 private:
     int entityId;
 
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     EntityChangedUpdate( int entityId, Framework::Vec3<int> pos, int dimension );
     ~EntityChangedUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class EntityChangedUpdateType : WorldUpdateType

+ 0 - 1
FactoryCraft/EntityRemovedUpdate.cpp

@@ -17,7 +17,6 @@ void EntityRemovedUpdate::onUpdate( Dimension* zDimension )
 
 void EntityRemovedUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     zWriter->schreibe( (char*)&entityId, 4 );
 }
 

+ 3 - 1
FactoryCraft/EntityRemovedUpdate.h

@@ -7,12 +7,14 @@ class EntityRemovedUpdate : public WorldUpdate
 private:
     int entityId;
 
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     EntityRemovedUpdate( int entityId, int dimensionId, Framework::Vec3<int> pos );
     ~EntityRemovedUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class EntityRemovedUpdateType : WorldUpdateType

+ 8 - 27
FactoryCraft/Game.cpp

@@ -6,6 +6,7 @@
 #include "NoBlock.h"
 #include "AsynchronCall.h"
 #include "Entity.h"
+#include "AddEntityUpdate.h"
 
 using namespace Framework;
 
@@ -29,7 +30,7 @@ GameClient::GameClient( Player* zPlayer, FCKlient* client )
                 other.unlock();
                 background.lock();
                 this->client->zBackgroundWriter()->schreibe( (char*)&Message::WORLD_UPDATE, 1 );
-                update->write( this->client->zBackgroundWriter() );
+                update->writeAndCheck( this->client->zBackgroundWriter() );
                 background.unlock();
                 update->release();
             }
@@ -92,34 +93,14 @@ void GameClient::reply()
     int x = (int)floor( zPlayer->getPosition().x );
     int y = (int)floor( zPlayer->getPosition().y );
     int d = zPlayer->getCurrentDimensionId();
-    foreground.lock();
-    client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1 );
-    float f = zPlayer->getPosition().x;
-    client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-    f = zPlayer->getPosition().y;
-    client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-    f = zPlayer->getPosition().z;
-    client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-    if( first )
-    {
-        f = zPlayer->getFaceDir().x;
-        client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-        f = zPlayer->getFaceDir().y;
-        client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-        f = zPlayer->getFaceDir().z;
-        client->zForegroundWriter()->schreibe( (char*)&f, 4 );
-    }
-    if( zPlayer->zTarget() )
-        zPlayer->zTarget()->save( client->zForegroundWriter() );
-    else
-    {
-        char b = 0;
-        client->zForegroundWriter()->schreibe( &b, 1 );
-    }
-    foreground.unlock();
     // send world to client
     if( first )
     {
+        foreground.lock();
+        int id = zPlayer->getId();
+        client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1 );
+        client->zForegroundWriter()->schreibe( (char*)&id, 4 );
+        foreground.unlock();
         first = 0;
         Dimension* dim = Game::INSTANCE->zDimension( d );
         if( dim )
@@ -417,7 +398,6 @@ GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
         Sleep( 1000 );
         cs.lock();
     }
-    zDimension( player->getCurrentDimensionId() )->addEntity( player );
     if( isNew )
     {
         Either<Block*, int> b = AirBlockBlockType::ID;
@@ -426,6 +406,7 @@ GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
             b = zBlockAt( { (int)player->getPosition().x, (int)player->getPosition().y, --h }, player->getCurrentDimensionId() );
         player->setPosition( { player->getPosition().x, player->getPosition().y, (float)h + 1.f } );
     }
+    requestWorldUpdate( new AddEntityUpdate( player, player->getCurrentDimensionId() ) );
     cs.unlock();
     return dynamic_cast<GameClient*>(gameClient->getThis());
 }

+ 17 - 13
FactoryCraft/Inventory.cpp

@@ -86,6 +86,7 @@ void InventoryInteraction::unlock()
 
 void InventoryInteraction::transaction( Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count )
 {
+    // TODO: rewrite this such that for each source slot all target slots are looped trough
     auto sourceSlot = zSource->pullSlotsOrder->begin();
     for( auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
     {
@@ -142,20 +143,23 @@ void InventoryInteraction::transaction( Inventory* zSource, Inventory* zTarget,
                 if( number > 0 && zSource->allowPullStack( sourceSlot, sourceView ) && zTarget->allowPushStack( targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp ) )
                 {
                     number = MIN( number, tmp );
-                    ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
-                    if( stack )
+                    if( number > 0 )
                     {
-                        zSource->updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
-                        targetSlot->addItems( stack, dir );
-                        zTarget->updateCache( targetSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
-                        zSource->afterPullStack( sourceSlot, sourceView, targetSlot->zStack()->zItem(), number );
-                        zTarget->afterPushStack( targetSlot, targetView, targetSlot->zStack()->zItem(), number );
-                        if( stack->getSize() )
-                            throw stack;
-                        stack->release();
-                        count -= number;
-                        if( count == 0 )
-                            return;
+                        ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
+                        if( stack )
+                        {
+                            targetSlot->addItems( stack, dir );
+                            zSource->updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
+                            zTarget->updateCache( targetSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
+                            zSource->afterPullStack( sourceSlot, sourceView, targetSlot->zStack()->zItem(), number );
+                            zTarget->afterPushStack( targetSlot, targetView, targetSlot->zStack()->zItem(), number );
+                            if( stack->getSize() )
+                                throw stack;
+                            stack->release();
+                            count -= number;
+                            if( count == 0 )
+                                return;
+                        }
                     }
                 }
             }

+ 0 - 5
FactoryCraft/ItemEntity.cpp

@@ -22,7 +22,6 @@ ItemEntity::ItemEntity( Framework::Vec3<float> location, int dimensionId, int en
 
 void ItemEntity::tick( const Dimension* zDimension )
 {
-    Framework::Vec3<float> pos = location;
     // add speed to next entity with free inventory
     Entity* zOther = Game::INSTANCE->zNearestEntity( currentDimensionId, location, [this]( Entity* zOther ) {
         return zOther != this && zOther->numberOfAddableItems( slot->zStack(), NO_DIRECTION );
@@ -55,10 +54,6 @@ void ItemEntity::tick( const Dimension* zDimension )
             speed = { 0.f, 0.f, 0.f };
     }
     Entity::tick( zDimension );
-    if( pos != location )
-    {
-        Game::INSTANCE->requestWorldUpdate( new EntityChangedUpdate( id, (Framework::Vec3<int>)location, currentDimensionId ) );
-    }
 }
 
 void ItemEntity::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )

+ 0 - 1
FactoryCraft/PlaceBlockUpdate.cpp

@@ -23,7 +23,6 @@ void PlaceBlockUpdate::onUpdate( Dimension* zDimension )
 
 void PlaceBlockUpdate::write( Framework::StreamWriter* zWriter )
 {
-    WorldUpdate::write( zWriter );
     int dimensionID = getAffectedDimension();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     auto pos = getMinAffectedPoint();

+ 3 - 1
FactoryCraft/PlaceBlockUpdate.h

@@ -11,12 +11,14 @@ class PlaceBlockUpdate : public WorldUpdate
 private:
     Framework::Either<Block*, int> block;
 
+protected:
+    void write( Framework::StreamWriter* zWriter ) override;
+
 public:
     PlaceBlockUpdate( Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId );
     ~PlaceBlockUpdate();
 
     void onUpdate( Dimension* zDimension ) override;
-    void write( Framework::StreamWriter* zWriter ) override;
     Block* zBlock() const;
 };
 

+ 3 - 1
FactoryCraft/WorldUpdate.cpp

@@ -8,9 +8,11 @@ WorldUpdate::WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAff
     type( type )
 {}
 
-void WorldUpdate::write( Framework::StreamWriter* zWriter )
+void WorldUpdate::writeAndCheck( Framework::StreamWriter* zWriter )
 {
     zWriter->schreibe( (char*)&type, 4 );
+    this->write( zWriter );
+    zWriter->schreibe( (char*)&type, 4 );
 }
 
 int WorldUpdate::getAffectedDimension() const

+ 4 - 1
FactoryCraft/WorldUpdate.h

@@ -16,11 +16,14 @@ private:
     Framework::Vec3<int> maxAffected;
     int type;
 
+protected:
+    virtual void write( Framework::StreamWriter* zWriter ) = 0;
+
 public:
     WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected );
 
     virtual void onUpdate( Dimension* zDimension ) = 0;
-    virtual void write( Framework::StreamWriter* zWriter );
+    void writeAndCheck( Framework::StreamWriter* zWriter );
 
     int getAffectedDimension() const;
     const Framework::Vec3<int>& getMinAffectedPoint() const;