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; int Id = m_FirstFree;
dbg_assert(Id != -1, "id error"); dbg_assert(Id != -1, "id error");
if(Id == -1)
return Id;
m_FirstFree = m_aIDs[m_FirstFree].m_Next; m_FirstFree = m_aIDs[m_FirstFree].m_Next;
m_aIDs[Id].m_State = 1; m_aIDs[Id].m_State = 1;
m_Usage++; m_Usage++;
@ -131,6 +133,8 @@ void CSnapIDPool::TimeoutIDs()
void CSnapIDPool::FreeID(int Id) void CSnapIDPool::FreeID(int Id)
{ {
if(Id < 0)
return;
dbg_assert(m_aIDs[Id].m_State == 1, "id is not alloced"); dbg_assert(m_aIDs[Id].m_State == 1, "id is not alloced");
m_InUsage--; 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(Type >= 0 && Type <=0xffff, "incorrect type");
dbg_assert(Id >= 0 && Id <=0xffff, "incorrect id"); 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) void CServer::SnapSetStaticsize(int ItemType, int Size)

View file

@ -793,20 +793,22 @@ void CCharacter::Snap(int SnappingClient)
if(NetworkClipped(SnappingClient)) if(NetworkClipped(SnappingClient))
return; 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 // write down the m_Core
if(!m_ReckoningTick || GameServer()->m_World.m_Paused) if(!m_ReckoningTick || GameServer()->m_World.m_Paused)
{ {
// no dead reckoning when paused because the client doesn't know // no dead reckoning when paused because the client doesn't know
// how far to perform the reckoning // how far to perform the reckoning
Character->m_Tick = 0; pCharacter->m_Tick = 0;
m_Core.Write(Character); m_Core.Write(pCharacter);
} }
else else
{ {
Character->m_Tick = m_ReckoningTick; pCharacter->m_Tick = m_ReckoningTick;
m_SendCore.Write(Character); m_SendCore.Write(pCharacter);
} }
// set emote // set emote
@ -816,30 +818,30 @@ void CCharacter::Snap(int SnappingClient)
m_EmoteStop = -1; m_EmoteStop = -1;
} }
Character->m_Emote = m_EmoteType; pCharacter->m_Emote = m_EmoteType;
Character->m_AmmoCount = 0; pCharacter->m_AmmoCount = 0;
Character->m_Health = 0; pCharacter->m_Health = 0;
Character->m_Armor = 0; pCharacter->m_Armor = 0;
Character->m_Weapon = m_ActiveWeapon; pCharacter->m_Weapon = m_ActiveWeapon;
Character->m_AttackTick = m_AttackTick; pCharacter->m_AttackTick = m_AttackTick;
Character->m_Direction = m_Input.m_Direction; pCharacter->m_Direction = m_Input.m_Direction;
if(m_pPlayer->GetCID() == SnappingClient) if(m_pPlayer->GetCID() == SnappingClient)
{ {
Character->m_Health = m_Health; pCharacter->m_Health = m_Health;
Character->m_Armor = m_Armor; pCharacter->m_Armor = m_Armor;
if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) 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) 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) void CFlag::Snap(int SnappingClient)
{ {
CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag)); 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_X = (int)m_Pos.x;
pFlag->m_Y = (int)m_Pos.y; pFlag->m_Y = (int)m_Pos.y;
pFlag->m_Team = m_Team; pFlag->m_Team = m_Team;

View file

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

View file

@ -126,6 +126,9 @@ void CPickup::Snap(int SnappingClient)
return; return;
CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_Id, sizeof(CNetObj_Pickup))); 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_X = (int)m_Pos.x;
pP->m_Y = (int)m_Pos.y; pP->m_Y = (int)m_Pos.y;
pP->m_Type = m_Type; pP->m_Type = m_Type;

View file

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

View file

@ -50,6 +50,7 @@ void CEventHandler::Snap(int SnappingClient)
if(SnappingClient == -1 || distance(GameServer()->m_apPlayers[SnappingClient]->m_ViewPos, vec2(ev->m_X, ev->m_Y)) < 1500.0f) 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]); void *d = GameServer()->Server()->SnapNewItem(m_aTypes[i], i, m_aSizes[i]);
if(d)
mem_copy(d, &m_aData[m_aOffsets[i]], m_aSizes[i]); 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) void IGameController::Snap(int SnappingClient)
{ {
CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game)); 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_Paused = GameServer()->m_World.m_Paused;
pGameObj->m_GameOver = m_GameOverTick==-1?0:1; pGameObj->m_GameOver = m_GameOverTick==-1?0:1;
pGameObj->m_SuddenDeath = m_SuddenDeath; pGameObj->m_SuddenDeath = m_SuddenDeath;

View file

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