FabianTerhorst / coreclr-module

Old alt:V CoreClr (.NET Core Common Language Runtime) community made module. New: https://github.com/altmp/coreclr-module

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rendering multiple entities OnWorldObjectStreamIn/Out callback gets called multiple times

kyro95 opened this issue · comments

Description of the problem

When rendering multiple entities OnWorldObjectStreamIn/Out gets called multiple times for the second entity.

Two entities in the same range (doesn't work fine)

Grand.Theft.Auto.V.2023.09.24.-.14.26.51.01.mp4

Single entity in the same range (works fine)

Grand.Theft.Auto.V.2023.09.24.-.14.29.11.02.mp4

Reproduction steps

Example;

There are within the same range two virtual entities.

Steps =>

  1. Render the first virtual entity, it gets rendered correctly,
  2. Render the second virtual entity and go toward the area of the second virtual entity

OnWorldObjectStreamIn/Out will be get called multiple times on the second virtual entity.

namespace Armonia.Client.Handler.House;

public class HouseMarkerHandler
{
    private Hashtable _markers;
    private readonly ChatService _chatService;

    public HouseMarkerHandler(ChatService chatService)
    {
        _chatService = chatService;
        _markers = new();
        Alt.OnWorldObjectStreamIn += OnWorldObjectStreamIn;
        Alt.OnWorldObjectStreamOut += OnWorldObjectStreamOut;
    }

    private void OnWorldObjectStreamIn(IWorldObject target)
    {
        if (worldObject is not IVirtualEntity entity)
            return;

        var entity = (IVirtualEntity) target;
        var position = entity.Position;

        position.Z -= 1.0f;
        
        entity.GetStreamSyncedMetaData<string>("id", out var id);
        
        _chatService.SendMessage($"Debug: Called OnStreamedIn with id {id}");
        if (_markers.Contains(id))
        {
            _chatService.SendMessage("Debug: Called OnStreamedIn but marker already exists");
            return;
        }

        var marker = Alt.CreateMarker(MarkerType.MarkerCylinder, position, new Rgba(247, 2, 1, 255), false, 0);
        _markers.Add(id, marker);
        marker.Scale = new Vector3(1.5f, 1.5f, 1.5f);
    }

    private void OnWorldObjectStreamOut(IWorldObject target)
    {
        if (worldObject is not IVirtualEntity entity)
            return;

        var entity = (IVirtualEntity) target;
        entity.GetStreamSyncedMetaData<string>("id", out var id);
        _chatService.SendMessage($"Debug: Called OnStreamedOut with id {id}");

        if (!_markers.Contains(id))
        {
            _chatService.SendMessage("Debug: Called OnStreamedOut but marker not found");
            return;
        }
        
        IMarker marker = (IMarker)_markers[id]!;
        
        _markers.Remove(id);
        marker.Destroy();
    }
}

Expected behaviour

OnWorldObjectStreamIn/Out with multiple entities should be called once when entering that area and once when leaving that area

(the actual behaviour of the single area)

Additional context

JS TEST

import * as alt from "alt-client";

const _streamedMarkers = new Map();

alt.on("worldObjectStreamIn", (worldObject) => {
    const id = worldObject.getStreamSyncedMeta("id");
    var position = new alt.Vector3(worldObject.pos.x, worldObject.pos.y, worldObject.pos.z - 1.0);

    alt.log(`Debug: Called OnStreamedIn with id ${id}}`);
    if(_streamedMarkers.has(id)) {
        alt.log("Debug: Called OnStreamedIn but marker already exists");
        return;
    }

    const marker = new alt.Marker(id, position, new alt.RGBA(247, 2, 1, 255), false, 0);
    _streamedMarkers.set(id, marker);
});

alt.on("worldObjectStreamOut", (worldObject) => {
    const id = worldObject.getStreamSyncedMeta("id");

    alt.log(`Debug: Called OnStreamedOut with id ${id}}`);

    if(!_streamedMarkers.has(id)) {
        alt.log("Debug: Called OnStreamedOut but marker not found");
        return;
    }

    const marker = _streamedMarkers.get(id);
    marker.destroy();
    _streamedMarkers.delete(id);
});
Grand.Theft.Auto.V.2023.09.24.-.15.52.40.03.mp4

Operating system

Windows 11 (10.0.22621 build 22621)

Version

15.0-dev683 (dev)

Crashdump ID

No response

Reproduction tested

  • I confirm that I have made sure that this issue is also present on the newest dev version

your C# Code is not the same like JS

U Create Marker by OnWorldObjectStreamOut and delete on OnWorldObjectStreamIn

your C# Code is not the same like JS

U Create Marker by OnWorldObjectStreamOut and delete on OnWorldObjectStreamIn

my bad i edited a little bit the code cause i wrote a wrapper on top of it on my gamemode, now the test is fixed

can u give me the positions and the create VirtualEntity, that i can easy repo oit?

       Dictionary<string, object> marker1 = new()
        {
            {"id", "650f552569330d6c234bef88"},
        };

        Dictionary<string, object> marker2 = new()
        {
            {"id", "650f554669330d6c234bef8d"},
        };

        _pickupGroup = Alt.CreateVirtualEntityGroup(500);
        var virtualEntity1 = Alt.CreateVirtualEntity(_pickupGroup, new Position(-274.1802062988281f, -674.8087768554688f, 33.087890625f), 5, marker1);
        var virtualEntity2 = Alt.CreateVirtualEntity(_pickupGroup, new Position(-289.002197265625f, -672.5538330078125f, 33.037353515625f), 5, marker2);

@Doxoh

@kyro95 cannot repo it https://streamable.com/p50k05



    private void OnWorldObjectStreamIn(IWorldObject worldObject)
    {
        if (worldObject is not IVirtualEntity entity)
            return;

        var position = entity.Position;

        position.Z -= 1.0f;

        entity.GetStreamSyncedMetaData<string>("id", out var id);

        Alt.Log($"Debug: Called OnStreamedIn with id {id}");
        if (_markers.Contains(id))
        {
            Alt.Log("Debug: Called OnStreamedIn but marker already exists");
            return;
        }

        var marker = Alt.CreateMarker(MarkerType.MarkerCylinder, position, new Rgba(247, 2, 1, 255), false, 0);
        _markers.Add(id, marker);
        marker.Scale = new Vector3(1.5f, 1.5f, 1.5f);
    }

    private void OnWorldObjectStreamOut(IWorldObject worldObject)
    {
        if (worldObject is not IVirtualEntity entity)
            return;

        entity.GetStreamSyncedMetaData<string>("id", out var id);
        Alt.Log($"Debug: Called OnStreamedOut with id {id}");

        if (!_markers.Contains(id))
        {
            Alt.Log("Debug: Called OnStreamedOut but marker not found");
            return;
        }

        IMarker marker = (IMarker)_markers[id]!;

        _markers.Remove(id);
        marker.Destroy();
    }