Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
90 lines
3.3 KiB
Plaintext
90 lines
3.3 KiB
Plaintext
modded class RplSessionErrorHandler
|
|
{
|
|
override void EOnConnected(RplIdentity identity)
|
|
{
|
|
super.EOnConnected(identity);
|
|
if (!Replication.IsServer()) return;
|
|
ERR_GameMode mode = ERR_GameMode.Get();
|
|
if (!mode || !mode.ERR_TerrainTakenOver()) return;
|
|
PrintFormat("ERR GATE: hold connection %1", identity);
|
|
ERR_TerrainClientGate.Stream(mode, identity, false);
|
|
ERR_TerrainClientGate gate = ERR_TerrainClientGate.Cast(GetGame().SpawnEntityPrefab(Resource.Load("{EA9D38B04C6F8521}Prefabs/ERR/TerrainClientGate.et"), GetGame().GetWorld()));
|
|
if (gate) gate.Assign(identity);
|
|
}
|
|
}
|
|
class ERR_TerrainClientGateClass : GenericEntityClass {}
|
|
class ERR_TerrainClientGate : GenericEntity
|
|
{
|
|
protected RplIdentity m_Target;
|
|
protected bool m_Drained;
|
|
protected bool m_Ready;
|
|
protected float m_Elapsed;
|
|
static void Stream(IEntity entity, RplIdentity identity, bool enabled)
|
|
{
|
|
if (!entity) return;
|
|
RplComponent rpl = RplComponent.Cast(entity.FindComponent(RplComponent));
|
|
if (rpl) { rpl.EnableSpatialRelevancy(false); rpl.EnableStreamingConNode(identity, enabled); }
|
|
IEntity child = entity.GetChildren();
|
|
while (child)
|
|
{
|
|
Stream(child, identity, enabled);
|
|
child = child.GetSibling();
|
|
}
|
|
}
|
|
void Assign(RplIdentity identity)
|
|
{
|
|
m_Target = identity;
|
|
RplComponent rpl = RplComponent.Cast(FindComponent(RplComponent));
|
|
rpl.Give(identity);
|
|
}
|
|
override void EOnFrame(IEntity owner, float timeSlice)
|
|
{
|
|
if (Replication.IsServer() || m_Ready) return;
|
|
RplComponent rpl = RplComponent.Cast(FindComponent(RplComponent));
|
|
if (!rpl || !rpl.IsOwner()) return;
|
|
if (!m_Drained)
|
|
{
|
|
GetGame().ERR_ClientGateDrain();
|
|
m_Drained = true;
|
|
}
|
|
m_Elapsed += timeSlice;
|
|
if (m_Elapsed < 0.5 || !GetGame().ERR_ClientGateEmpty()) return;
|
|
m_Ready = true;
|
|
Print("ERR GATE: client drained, requesting managers");
|
|
Rpc(RpcAsk_Ready);
|
|
}
|
|
[RplRpc(RplChannel.Reliable, RplRcver.Server)]
|
|
protected void RpcAsk_Ready()
|
|
{
|
|
if (!Replication.IsServer() || m_Ready) return;
|
|
m_Ready = true;
|
|
PrintFormat("ERR GATE: release connection %1", m_Target);
|
|
Stream(ERR_GameMode.Get(), m_Target, true);
|
|
}
|
|
void ERR_TerrainClientGate(IEntitySource src, IEntity parent)
|
|
{
|
|
SetEventMask(EntityEvent.FRAME);
|
|
}
|
|
}
|
|
modded class ArmaReforgerScripted
|
|
{
|
|
void ERR_ClientGateDrain()
|
|
{
|
|
PrintFormat("ERR GATE: client drain old mode=%1 runtime=%2", GetGameMode(), Replication.Runtime());
|
|
SCR_BaseGameMode mode = SCR_BaseGameMode.Cast(GetGameMode());
|
|
if (ERR_GameMode.Cast(mode)) { Print("ERR GATE: too late", LogLevel.ERROR); return; }
|
|
if (mode) mode.OnGameEnd();
|
|
if (m_DataCollectorComponent) m_DataCollectorComponent = null;
|
|
SCR_EntityCatalogManagerComponent.ERR_ReleaseTerrainCatalog(mode);
|
|
array<IEntity> managers = {mode, GetLoadoutManager(), GetFactionManager(), GetPerceptionManager(), GetChat()};
|
|
ChimeraWorld chimera = ChimeraWorld.CastFrom(GetWorld());
|
|
if (chimera) managers.Insert(chimera.GetRadioManager());
|
|
foreach (IEntity manager : managers) if (manager) SCR_EntityHelper.DeleteEntityAndChildren(manager);
|
|
}
|
|
bool ERR_ClientGateEmpty()
|
|
{
|
|
ChimeraWorld chimera = ChimeraWorld.CastFrom(GetWorld());
|
|
return !GetGameMode() && !GetLoadoutManager() && !GetFactionManager() && !GetPerceptionManager() && !GetChat() && (!chimera || !chimera.GetRadioManager()) && !SCR_EntityCatalogManagerComponent.GetInstance() && !m_DataCollectorComponent;
|
|
}
|
|
}
|