Hopefully fixed switch in networking mode.
This commit is contained in:
parent
c2d0ac4a61
commit
76dc8c8763
@ -33,15 +33,23 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
|||||||
{
|
{
|
||||||
m_type = (EventType)buffer->getUInt8();
|
m_type = (EventType)buffer->getUInt8();
|
||||||
m_ticks = buffer->getTime();
|
m_ticks = buffer->getTime();
|
||||||
|
*count -= 5;
|
||||||
|
if (m_type != IEI_SWITCH)
|
||||||
|
{
|
||||||
m_kart_id = buffer->getInt8();
|
m_kart_id = buffer->getInt8();
|
||||||
m_index = buffer->getUInt16();
|
m_index = buffer->getUInt16();
|
||||||
*count -= 8;
|
*count -= 3;
|
||||||
if (m_type == IEI_NEW)
|
if (m_type == IEI_NEW)
|
||||||
{
|
{
|
||||||
m_xyz = buffer->getVec3();
|
m_xyz = buffer->getVec3();
|
||||||
*count -= 12;
|
*count -= 12;
|
||||||
}
|
}
|
||||||
|
} // is not switch
|
||||||
|
else // switch
|
||||||
|
{
|
||||||
|
m_kart_id = -1;
|
||||||
|
|
||||||
|
}
|
||||||
} // ItemEventInfo(BareNetworkString, int *count)
|
} // ItemEventInfo(BareNetworkString, int *count)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -51,10 +59,14 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
|||||||
void ItemEventInfo::saveState(BareNetworkString *buffer)
|
void ItemEventInfo::saveState(BareNetworkString *buffer)
|
||||||
{
|
{
|
||||||
assert(NetworkConfig::get()->isServer());
|
assert(NetworkConfig::get()->isServer());
|
||||||
buffer->addUInt8(m_type).addTime(m_ticks).addUInt8(m_kart_id)
|
buffer->addUInt8(m_type).addTime(m_ticks);
|
||||||
.addUInt16(m_index);
|
if (m_type != IEI_SWITCH)
|
||||||
|
{
|
||||||
|
// Only new item and collecting items need the index and kart id:
|
||||||
|
buffer->addUInt8(m_kart_id).addUInt16(m_index);
|
||||||
if (m_type == IEI_NEW)
|
if (m_type == IEI_NEW)
|
||||||
buffer->add(m_xyz);
|
buffer->add(m_xyz);
|
||||||
|
}
|
||||||
} // saveState
|
} // saveState
|
||||||
|
|
||||||
|
|
||||||
|
76
src/items/network_item_manager.cpp
Normal file → Executable file
76
src/items/network_item_manager.cpp
Normal file → Executable file
@ -42,6 +42,7 @@ void NetworkItemManager::create()
|
|||||||
NetworkItemManager::NetworkItemManager()
|
NetworkItemManager::NetworkItemManager()
|
||||||
: Rewinder("N"), ItemManager()
|
: Rewinder("N"), ItemManager()
|
||||||
{
|
{
|
||||||
|
m_confirmed_switch_ticks = -1;
|
||||||
m_last_confirmed_item_ticks.clear();
|
m_last_confirmed_item_ticks.clear();
|
||||||
|
|
||||||
if (NetworkConfig::get()->isServer())
|
if (NetworkConfig::get()->isServer())
|
||||||
@ -71,6 +72,7 @@ NetworkItemManager::~NetworkItemManager()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void NetworkItemManager::reset()
|
void NetworkItemManager::reset()
|
||||||
{
|
{
|
||||||
|
m_confirmed_switch_ticks = -1;
|
||||||
ItemManager::reset();
|
ItemManager::reset();
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
@ -114,6 +116,25 @@ void NetworkItemManager::collectedItem(ItemState *item, AbstractKart *kart)
|
|||||||
}
|
}
|
||||||
} // collectedItem
|
} // collectedItem
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Called when a switch is activated. On the server adds this information to
|
||||||
|
* the item state so it can be sent to all clients.
|
||||||
|
*/
|
||||||
|
void NetworkItemManager::switchItems()
|
||||||
|
{
|
||||||
|
if (NetworkConfig::get()->isServer())
|
||||||
|
{
|
||||||
|
// The server saves the collected item as item event info
|
||||||
|
m_item_events.lock();
|
||||||
|
// Create a switch event - the constructor called determines
|
||||||
|
// the type of the event automatically.
|
||||||
|
m_item_events.getData()
|
||||||
|
.emplace_back(World::getWorld()->getTicksSinceStart());
|
||||||
|
m_item_events.unlock();
|
||||||
|
}
|
||||||
|
ItemManager::switchItems();
|
||||||
|
} // switchItems
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Called when a new item is created, e.g. bubble gum.
|
/** Called when a new item is created, e.g. bubble gum.
|
||||||
* \param type Type of the item.
|
* \param type Type of the item.
|
||||||
@ -233,6 +254,13 @@ void NetworkItemManager::forwardTime(int ticks)
|
|||||||
{
|
{
|
||||||
if (i) i->update(ticks);
|
if (i) i->update(ticks);
|
||||||
} // for m_all_items
|
} // for m_all_items
|
||||||
|
if(m_switch_ticks>ticks)
|
||||||
|
m_switch_ticks -= ticks;
|
||||||
|
else if (m_switch_ticks >= 0)
|
||||||
|
{
|
||||||
|
switchItemsInternal(m_confirmed_state);
|
||||||
|
m_switch_ticks = -1;
|
||||||
|
}
|
||||||
} // forwardTime
|
} // forwardTime
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -245,6 +273,7 @@ void NetworkItemManager::forwardTime(int ticks)
|
|||||||
*/
|
*/
|
||||||
void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(NetworkConfig::get()->isClient());
|
assert(NetworkConfig::get()->isClient());
|
||||||
// The state at World::getTicksSinceStart() needs to be restored. The confirmed
|
// The state at World::getTicksSinceStart() needs to be restored. The confirmed
|
||||||
// state in this instance was taken at m_confirmed_state_time. First
|
// state in this instance was taken at m_confirmed_state_time. First
|
||||||
@ -270,18 +299,34 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// --------------------------
|
// --------------------------
|
||||||
for (unsigned int i=0; i<m_all_items.size(); i++)
|
for (unsigned int i=0; i<m_all_items.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = m_all_items[i];
|
ItemState *item = m_all_items[i];
|
||||||
if(item && item->isPredicted())
|
if(item && item->isPredicted())
|
||||||
{
|
{
|
||||||
deleteItem(item);
|
deleteItem(item);
|
||||||
}
|
}
|
||||||
} // for i in m_all_items
|
} // for i in m_all_items
|
||||||
|
|
||||||
|
// Reset a predicted switch time: if the items are currently
|
||||||
|
// predicted to be switched, but not switched at the confirmed
|
||||||
|
// state time or vice versa, we need to switch them back. This
|
||||||
|
// is tested by seeing if the signs of the switch_ticks and
|
||||||
|
// confirmed switch_ticks are opposite:
|
||||||
|
if(m_switch_ticks * m_confirmed_switch_ticks < 0)
|
||||||
|
{
|
||||||
|
switchItemsInternal(m_all_items);
|
||||||
|
}
|
||||||
|
m_switch_ticks = m_confirmed_switch_ticks;
|
||||||
|
|
||||||
|
|
||||||
// 2) Apply all events to current confirmed state:
|
// 2) Apply all events to current confirmed state:
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
int current_time = m_confirmed_state_time;
|
int current_time = m_confirmed_state_time;
|
||||||
bool has_state = count > 0;
|
bool has_state = count > 0;
|
||||||
|
|
||||||
|
// Note that the actual ItemManager states must NOT be changed here, only
|
||||||
|
// the confirmed states in the Network manager are allowed to be modified.
|
||||||
|
// They will all be copied to the ItemManager states after the loop.
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
{
|
{
|
||||||
// 2.1) Decode the event in the message
|
// 2.1) Decode the event in the message
|
||||||
@ -292,16 +337,14 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// the time to the time of this event:
|
// the time to the time of this event:
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
int dt = iei.getTicks() - current_time;
|
int dt = iei.getTicks() - current_time;
|
||||||
// Skip an event that are 'in the past' (i.e. have been sent again by
|
// Skip an event that is 'in the past' (i.e. have been sent again by
|
||||||
// the server because it has not yet received confirmation from all
|
// the server because it has not yet received confirmation from all
|
||||||
// clients.
|
// clients).
|
||||||
if(dt<0) continue;
|
if(dt<0) continue;
|
||||||
|
|
||||||
// Forward the saved state:
|
// Forward the saved state:
|
||||||
if (dt>0) forwardTime(dt);
|
if (dt>0) forwardTime(dt);
|
||||||
|
|
||||||
// TODO: apply the various events types, atm only collection
|
|
||||||
// and new items are supported.
|
|
||||||
if(iei.isItemCollection())
|
if(iei.isItemCollection())
|
||||||
{
|
{
|
||||||
int index = iei.getIndex();
|
int index = iei.getIndex();
|
||||||
@ -348,6 +391,19 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(iei.isSwitch())
|
||||||
|
{
|
||||||
|
// Reset current switch ticks
|
||||||
|
m_switch_ticks = -1;
|
||||||
|
ItemManager::switchItemsInternal(m_confirmed_state);
|
||||||
|
m_confirmed_switch_ticks = m_switch_ticks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::error("NetworkItemManager",
|
||||||
|
"Received unknown event type at %d",
|
||||||
|
iei.getTicks());
|
||||||
|
}
|
||||||
current_time = iei.getTicks();
|
current_time = iei.getTicks();
|
||||||
} // while count >0
|
} // while count >0
|
||||||
|
|
||||||
@ -360,6 +416,8 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
gp->sendItemEventConfirmation(world->getTicksSinceStart());
|
gp->sendItemEventConfirmation(world->getTicksSinceStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_switch_ticks = m_confirmed_switch_ticks;
|
||||||
|
|
||||||
// Forward the confirmed item state to the world time:
|
// Forward the confirmed item state to the world time:
|
||||||
int dt = world->getTicksSinceStart() - current_time;
|
int dt = world->getTicksSinceStart() - current_time;
|
||||||
if(dt>0) forwardTime(dt);
|
if(dt>0) forwardTime(dt);
|
||||||
@ -369,7 +427,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
|
|
||||||
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
|
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
ItemState *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
||||||
const ItemState *is = m_confirmed_state[i];
|
const ItemState *is = m_confirmed_state[i];
|
||||||
if (is && item)
|
if (is && item)
|
||||||
*(ItemState*)item = *is;
|
*(ItemState*)item = *is;
|
||||||
@ -383,8 +441,6 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// The server has this item at a different index in the list
|
// The server has this item at a different index in the list
|
||||||
// of all items, which means the client has an incorrect
|
// of all items, which means the client has an incorrect
|
||||||
// item at the index given by the server - delete that item
|
// item at the index given by the server - delete that item
|
||||||
Log::info("nim", "about to delete item with not matching index i %d item %d",
|
|
||||||
i, item_new->getItemId());
|
|
||||||
if(m_all_items[i])
|
if(m_all_items[i])
|
||||||
deleteItem(m_all_items[i]);
|
deleteItem(m_all_items[i]);
|
||||||
m_all_items[item_new->getItemId()] = NULL;
|
m_all_items[item_new->getItemId()] = NULL;
|
||||||
@ -397,14 +453,12 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
}
|
}
|
||||||
else if (!is && item)
|
else if (!is && item)
|
||||||
{
|
{
|
||||||
Log::info("nim", "About to delete item index %d i %d",
|
|
||||||
item->getItemId(), i);
|
|
||||||
|
|
||||||
deleteItem(m_all_items[i]);
|
deleteItem(m_all_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we save the current local
|
// Now we save the current local
|
||||||
m_confirmed_state_time = world->getTicksSinceStart();
|
m_confirmed_state_time = world->getTicksSinceStart();
|
||||||
|
m_confirmed_switch_ticks = m_switch_ticks;
|
||||||
} // restoreState
|
} // restoreState
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@ private:
|
|||||||
* server data. This is used in case of rewind. */
|
* server data. This is used in case of rewind. */
|
||||||
std::vector<ItemState*> m_confirmed_state;
|
std::vector<ItemState*> m_confirmed_state;
|
||||||
|
|
||||||
|
/** The switch ticks value at the lime of the last confirmed state. */
|
||||||
|
int m_confirmed_switch_ticks;
|
||||||
|
|
||||||
/** Time at which m_confirmed_state was taken. */
|
/** Time at which m_confirmed_state was taken. */
|
||||||
int m_confirmed_state_time;
|
int m_confirmed_state_time;
|
||||||
|
|
||||||
@ -66,7 +69,6 @@ public:
|
|||||||
static void create();
|
static void create();
|
||||||
virtual ~NetworkItemManager();
|
virtual ~NetworkItemManager();
|
||||||
|
|
||||||
void setSwitchItems(const std::vector<int> &switch_items);
|
|
||||||
void sendItemUpdate();
|
void sendItemUpdate();
|
||||||
void initClientConfirmState();
|
void initClientConfirmState();
|
||||||
|
|
||||||
@ -74,6 +76,7 @@ public:
|
|||||||
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
||||||
int ticks) OVERRIDE;
|
int ticks) OVERRIDE;
|
||||||
virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE;
|
virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE;
|
||||||
|
virtual void switchItems() OVERRIDE;
|
||||||
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
||||||
const Vec3 *xyz=NULL) OVERRIDE;
|
const Vec3 *xyz=NULL) OVERRIDE;
|
||||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||||
|
Loading…
Reference in New Issue
Block a user