fixed server crash on too many snap items. Closes #317

This commit is contained in:
oy 2010-12-16 03:29:08 +01:00
parent 54f138f894
commit 0121f27311
9 changed files with 60 additions and 35 deletions

View file

@ -115,6 +115,8 @@ int CSnapIDPool::NewID()
int Id = m_FirstFree;
dbg_assert(Id != -1, "id error");
if(Id == -1)
return Id;
m_FirstFree = m_aIDs[m_FirstFree].m_Next;
m_aIDs[Id].m_State = 1;
m_Usage++;
@ -131,6 +133,8 @@ void CSnapIDPool::TimeoutIDs()
void CSnapIDPool::FreeID(int Id)
{
if(Id < 0)
return;
dbg_assert(m_aIDs[Id].m_State == 1, "id is not alloced");
m_InUsage--;
@ -1481,7 +1485,7 @@ void *CServer::SnapNewItem(int Type, int Id, int Size)
{
dbg_assert(Type >= 0 && Type <=0xffff, "incorrect type");
dbg_assert(Id >= 0 && Id <=0xffff, "incorrect id");
return m_SnapshotBuilder.NewItem(Type, Id, Size);
return Id < 0 ? 0 : m_SnapshotBuilder.NewItem(Type, Id, Size);
}
void CServer::SnapSetStaticsize(int ItemType, int Size)

View file

@ -793,20 +793,22 @@ void CCharacter::Snap(int SnappingClient)
if(NetworkClipped(SnappingClient))
return;
CNetObj_Character *Character = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
if(!pCharacter)
return;
// write down the m_Core
if(!m_ReckoningTick || GameServer()->m_World.m_Paused)
{
// no dead reckoning when paused because the client doesn't know
// how far to perform the reckoning
Character->m_Tick = 0;
m_Core.Write(Character);
pCharacter->m_Tick = 0;
m_Core.Write(pCharacter);
}
else
{
Character->m_Tick = m_ReckoningTick;
m_SendCore.Write(Character);
pCharacter->m_Tick = m_ReckoningTick;
m_SendCore.Write(pCharacter);
}
// set emote
@ -816,30 +818,30 @@ void CCharacter::Snap(int SnappingClient)
m_EmoteStop = -1;
}
Character->m_Emote = m_EmoteType;
pCharacter->m_Emote = m_EmoteType;
Character->m_AmmoCount = 0;
Character->m_Health = 0;
Character->m_Armor = 0;
pCharacter->m_AmmoCount = 0;
pCharacter->m_Health = 0;
pCharacter->m_Armor = 0;
Character->m_Weapon = m_ActiveWeapon;
Character->m_AttackTick = m_AttackTick;
pCharacter->m_Weapon = m_ActiveWeapon;
pCharacter->m_AttackTick = m_AttackTick;
Character->m_Direction = m_Input.m_Direction;
pCharacter->m_Direction = m_Input.m_Direction;
if(m_pPlayer->GetCID() == SnappingClient)
{
Character->m_Health = m_Health;
Character->m_Armor = m_Armor;
pCharacter->m_Health = m_Health;
pCharacter->m_Armor = m_Armor;
if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0)
Character->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
pCharacter->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
}
if (Character->m_Emote == EMOTE_NORMAL)
if(pCharacter->m_Emote == EMOTE_NORMAL)
{
if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5)
Character->m_Emote = EMOTE_BLINK;
pCharacter->m_Emote = EMOTE_BLINK;
}
Character->m_PlayerState = m_PlayerState;
pCharacter->m_PlayerState = m_PlayerState;
}

View file

@ -26,6 +26,9 @@ void CFlag::Reset()
void CFlag::Snap(int SnappingClient)
{
CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag));
if(!pFlag)
return;
pFlag->m_X = (int)m_Pos.x;
pFlag->m_Y = (int)m_Pos.y;
pFlag->m_Team = m_Team;

View file

@ -98,6 +98,9 @@ void CLaser::Snap(int SnappingClient)
return;
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
if(!pObj)
return;
pObj->m_X = (int)m_Pos.x;
pObj->m_Y = (int)m_Pos.y;
pObj->m_FromX = (int)m_From.x;

View file

@ -126,6 +126,9 @@ void CPickup::Snap(int SnappingClient)
return;
CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_Id, sizeof(CNetObj_Pickup)));
if(!pP)
return;
pP->m_X = (int)m_Pos.x;
pP->m_Y = (int)m_Pos.y;
pP->m_Type = m_Type;

View file

@ -100,5 +100,6 @@ void CProjectile::Snap(int SnappingClient)
return;
CNetObj_Projectile *pProj = static_cast<CNetObj_Projectile *>(Server()->SnapNewItem(NETOBJTYPE_PROJECTILE, m_Id, sizeof(CNetObj_Projectile)));
FillInfo(pProj);
if(pProj)
FillInfo(pProj);
}

View file

@ -50,7 +50,8 @@ void CEventHandler::Snap(int SnappingClient)
if(SnappingClient == -1 || distance(GameServer()->m_apPlayers[SnappingClient]->m_ViewPos, vec2(ev->m_X, ev->m_Y)) < 1500.0f)
{
void *d = GameServer()->Server()->SnapNewItem(m_aTypes[i], i, m_aSizes[i]);
mem_copy(d, &m_aData[m_aOffsets[i]], m_aSizes[i]);
if(d)
mem_copy(d, &m_aData[m_aOffsets[i]], m_aSizes[i]);
}
}
}

View file

@ -535,6 +535,9 @@ bool IGameController::IsTeamplay() const
void IGameController::Snap(int SnappingClient)
{
CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game));
if(!pGameObj)
return;
pGameObj->m_Paused = GameServer()->m_World.m_Paused;
pGameObj->m_GameOver = m_GameOverTick==-1?0:1;
pGameObj->m_SuddenDeath = m_SuddenDeath;

View file

@ -78,24 +78,29 @@ void CPlayer::Snap(int SnappingClient)
if(!Server()->ClientIngame(m_ClientID))
return;
CNetObj_ClientInfo *ClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
StrToInts(&ClientInfo->m_Name0, 6, Server()->ClientName(m_ClientID));
StrToInts(&ClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
ClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
ClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
ClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
if(!pClientInfo)
return;
CNetObj_PlayerInfo *Info = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
StrToInts(&pClientInfo->m_Name0, 6, Server()->ClientName(m_ClientID));
StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
pClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
Info->m_Latency = m_Latency.m_Min;
Info->m_LatencyFlux = m_Latency.m_Max-m_Latency.m_Min;
Info->m_Local = 0;
Info->m_ClientId = m_ClientID;
Info->m_Score = m_Score;
Info->m_Team = m_Team;
CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
if(!pPlayerInfo)
return;
pPlayerInfo->m_Latency = m_Latency.m_Min;
pPlayerInfo->m_LatencyFlux = m_Latency.m_Max-m_Latency.m_Min;
pPlayerInfo->m_Local = 0;
pPlayerInfo->m_ClientId = m_ClientID;
pPlayerInfo->m_Score = m_Score;
pPlayerInfo->m_Team = m_Team;
if(m_ClientID == SnappingClient)
Info->m_Local = 1;
pPlayerInfo->m_Local = 1;
}
void CPlayer::OnDisconnect()