Giter Site home page Giter Site logo

Comments (7)

blapaz avatar blapaz commented on May 20, 2024 2

I added a fix for this issue loosely based on some snippets I received from @Persegan. This could be improved but this does allow the lobby system to work as expected and without the issue.

Pull request: #369

from forgenetworkingremastered.

TonyViT avatar TonyViT commented on May 20, 2024 1

Persegan gave me those fixes as well (he's been very kind), but they have issues if you have many players because there are too many messages that get exchanged. Yesterday I tried with 4 players on Android devices and the lobby got crazy.

from forgenetworkingremastered.

TonyViT avatar TonyViT commented on May 20, 2024

This is a very annoying issue. A guy on Discord gave me some scripts that are a workaround on this, but I had to tweak them a bit to make them work. Otherwise, I discovered that a Thread.Sleep in the lobbyservice helps a lot with this problem

from forgenetworkingremastered.

blapaz avatar blapaz commented on May 20, 2024

I have not run into that issue even with that many and more players connecting. Although the way I use it, my players are not all connecting into the lobby at the same exact time.

from forgenetworkingremastered.

blapaz avatar blapaz commented on May 20, 2024

I would have to look at the code again but I feel like instead of sending an RPC for every player already in the lobby, a RPC should be created to send all that info in one call. One RPC that sends all players already connected to the newly connected player.

In theory would fix your issue, just would have to look how you could set it up.

from forgenetworkingremastered.

TonyViT avatar TonyViT commented on May 20, 2024

I'm going to investigate it next week for the program we are implementing, maybe if I find a solution, I can share it with the community. I will keep you posted!

from forgenetworkingremastered.

TonyViT avatar TonyViT commented on May 20, 2024

Hey @blapaz @Persegan I have improved the solution by Persegan:

  • It now supports Custom names
  • It sends only the necessary messages.

Now I have no endless loops anymore, even with 10-12 players!

My idea has been sending the messages of old players only to the last connecting user, and preventing the function to be called multiple times. Furthermore I've modified the RPC about players so now a name is shared.

I know git well, but I'm not very practical with big GitHub repos, so can you tell me how can I start from Persegan solution and do a pull request?

For people stumbling here before I make the pull request, I'll try to share here some code snippet. Start from solution from Persegan, not from the regular branch, or nothing will work.

Then in the LobbyManager:

  1. Add a variable
    /// <summary>
    /// True if the lobby has already sent a sync to get the list of connected players, false otherwise
    /// </summary>
    private bool m_setupped = false;
  1. Change the method SetupService with this one
    private void SetupService(NetworkObject obj)
    {
        if (!m_setupped)
        {
            LobbyService.Instance.Initialize(obj);
            _networkObjectReference = LobbyService.Instance.networkObject;
            LobbyService.Instance.networkObject.SendRpc(LobbyService.RPC_SYNC_ALL_PLAYERS, Receivers.Server, _networkObjectReference.MyPlayerId); //RPC Fix received on discord

            MainThreadManager.Run(() => SetupComplete());
            m_setupped = true;
        }
    }

This will make sure the event is sent only to the latest connecting player and won't be repeated

Now switch to LobbyService:
3. At line 483 change the signature of the RPC SyncAllPlayers to accept the id of the player and change PlayerJoined to accept a player name

networkObject.RegisterRpc("PlayerJoined", PlayerJoined, typeof(uint), typeof(string));
networkObject.RegisterRpc("SyncAllPlayers", SyncAllPlayers, typeof(uint));

  1. Change the code of SyncAllPlayers with this one, that makes the calls only to selected id
private void SyncAllPlayers(RpcArgs args)
        {           
            Debug.Log("---------------------------------------------------------------");
            if (networkObject.IsServer)
            {
                uint newlyJoinedPlayerId = args.GetNext<uint>();          
                int newlyJoinedPlayerIndex = LobbyService.Instance.MasterLobby.LobbyPlayers.FindIndex(player => player.NetworkId == (int)newlyJoinedPlayerId); //find the id of the object in the list

                //for (int i = 0; i < LobbyService.Instance.MasterLobby.LobbyPlayers.Count; i++)
                //{
                    LobbyService.Instance.networkObject.Networker.IteratePlayers((p) =>
                    {
                        IClientMockPlayer cPlayer = LobbyService.Instance.MasterLobby.LobbyPlayers.First(l => l.NetworkId == p.NetworkId);
                        Debug.Log("Debugging Name Before RPC Joined" + cPlayer.Name);
                        Debug.Log("Debugging Avatar ID Before RPC Joined " + cPlayer.AvatarID);
                        if (p == LobbyService.Instance.MasterLobby.LobbyPlayers[newlyJoinedPlayerIndex])
                            return;
                        LobbyService.Instance.networkObject.SendRpc(LobbyService.Instance.networkObject.Networker.Players[newlyJoinedPlayerIndex], RPC_PLAYER_JOINED, p.NetworkId, cPlayer.Name == null ? "" : cPlayer.Name);
                        Debug.Log("Debugging Name After RPC Joined " + cPlayer.Name);
                        Debug.Log("Debugging Avatar ID After RPC Joined " + cPlayer.AvatarID);
                        LobbyService.Instance.networkObject.SendRpc(LobbyService.Instance.networkObject.Networker.Players[newlyJoinedPlayerIndex], RPC_PLAYER_SYNC, p.NetworkId, cPlayer.Name, cPlayer.TeamID, cPlayer.AvatarID);
                    });
                //}
            }
            Debug.Log("---------------------------------------------------------------FIN");

        }
  1. Change the code of PlayerJoined with this one that accept the name of a player
        /// <summary>
        /// Arguments:
        /// uint playerid
        /// </summary>
        private void PlayerJoined(RpcArgs args)
        {
            Debug.Log("Player Joined Called");
            uint playerId = args.GetNext<uint>();
            string playerName = args.GetNext<string>();
            var player = CreateClientMockPlayer(playerId, String.IsNullOrEmpty(playerName) ? "Player " + playerId : playerName);

            MasterLobby.OnFNPlayerConnected(player);
        }
  1. In the PlayerConnected method, modify the calls to the PLAYER_JOINED RPC by adding a last empty-string parameter
    networkObject.SendRpc(RPC_PLAYER_JOINED, Receivers.All, player.NetworkId, "");
    networkObject.SendRpc(player, RPC_PLAYER_JOINED, p.NetworkId, "");

If I haven't forgotten anything, it should work, and you should have less exchange of messages and also the propagation of the names you have chosen for your players!

I hope this will help someone

from forgenetworkingremastered.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.