How to get a list of all players in the game?

lpp168
lpp168
edited August 2012 in Photon Server
I want to achieve a Chat function,
The players entered the hall into the room between the private chat or broadcast.
For example:
A player message "Hello World", in the lobby and all rooms of the players can receive the message.
A player in the hall in the message "Hello Lobby", the players in the hall to receive the message.
In in LiteLobby, I wrote:
public enum LiteLobbyOpCode: byte {Chat = 200}
public enum LiteLobbyEventCode: byte {Chat = 200}
In the add LiteLobbyPeer the OnOperationRequest
case LiteLobbyOpCode.Chat:
                    this.HandleChatOperation (operationRequest, sendParameters);
                    return;
But in HandleChatOperation me how to find all the players to broadcast a message to them?
public void HandleChatOperation (OperationRequest operationRequest, SendParameters sendParameters)
{
// TODO:
// In OnOperationRequest
// How to get a list of all players in the game, not a list of players in a room.
}

Comments

  • This.GameInstance.Peer.OpRaiseEvent method
    Found that only players in the same room in order to receive the broadcast message

    But for a game, system messages, chat between players can not limit being in the same room!

    I need to completely re-implement the new Lite in order to achieve the purpose of chat in the game?
  • You would probably have to add this yourself, yes.

    By design, we don't offer "global" chat or chat in the lobby. Just imagine having 1k active players and all chat with each other. If everyone can broadcast messages globally, this can get out of hand quickly.

    I'm not sure if you want players to me in more than one room at the same time but:
    We don't allow a peer to be in more than one room, by default. It would complicate things like "which room is my message for" and "where does that message come from".
    This would also be in your hands.
  • If want to send a system message, for example: five minutes after the server will restart.
    This message is also not allowed to?
  • It's not implemented but should be relatively easy to add.
    There is a LiteGameCache class which you should modify. Add a method that uses EnqueueMessage on all rooms. These in turn send an event to every player inside.

    Players that change from room to room in the very same moment could miss the message. You could use the room's event cache, so every player who joins the room will get the cached event.
  • Sorry, I can not understand the room's event cache
    Directly on the code, you help me find that okay?
    public abstract class RoomCacheBase
    {
           ...
            public List <Room> GetRooms ()
            {
                List <Room> list = new List <Room> ();
                foreach (var r in roomInstances)
                {
                    list.Add (r.Value.Room);
                }
                return list;
            }
    }

    public class LiteGameCache: RoomCacheBase
    {
            ...
            protected void EnqueueMessage (IMessage message)
            {
                foreach (var room in base.GetRooms ())
                {
                    room.EnqueueMessage (message);
                }
            }
    }

    And this is to directly modify the Lite code
    For the official upgrade the Lite, I have to re-edit.

    Excuse me, I used Google Translate.
  • Here is some example code for how to send an event to all players currently connected to a Lite application instance.

    Add following code to LiteApplication.cs:
            private static readonly HashSet&lt;PeerBase&gt; peers = new HashSet&lt;PeerBase&gt;();
    
            public static void AddPeer(PeerBase peer)
            {
                lock (peers)
                {
                    peers.Add(peer);
                }
            }
    
            public static bool RemovePeer(PeerBase peer)
            {
                lock (peers)
                {
                    return peers.Remove(peer);
                }
            }
    
            public static void SendMessageToAllPeers(EventData eventData)
            {
                lock (peers)
                {
                    ApplicationBase.Instance.BroadCastEvent(eventData, peers, new SendParameters());
                }
            }
    
            protected override PeerBase CreatePeer(InitRequest initRequest)
            {
                var peer = new LitePeer(initRequest.Protocol, initRequest.PhotonPeer);
                AddPeer(peer);
                return peer;
            }
    


    This code to LitePeer.cs
            protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("OnDisconnect: conId={0}, reason={1}, reasonDetail={2}", this.ConnectionId, reasonCode, reasonDetail);
                }
    
                LiteApplication.RemovePeer(this);
    
                if (this.RoomReference == null)
                {
                    return;
                }
    
                var message = new RoomMessage((byte)GameMessageCodes.RemovePeerFromGame, this);
                this.RoomReference.Room.EnqueueMessage(message);
                this.RoomReference.Dispose();
                this.RoomReference = null;
            }
    

    Youre code would than look something like this
    public void HandleChatOperation (OperationRequest operationRequest, SendParameters sendParameters)
        { 
            // TODO:
            // In OnOperationRequest
            // How to get a list of all players in the game, not a list of players in a room.
            var eventData = new EventData(1);
            LiteApplication.SendMessageToAllPeers(eventData);
    }
    
  • Thank you, this method is very good for the sent message to all players.
    But in the LiteApplication is PeerBase Actor,
    If I want to send an announcement to the players in a room, or send an announcement to a guild of players, and then rely solely on the PeerBase can not be removed corresponding to the collection.
    public void HandleChatOperation(OperationRequest operationRequest, SendParameters sendParameters)
            {
                var request = new ChatRequest(this.Protocol, operationRequest);
                if (this.ValidateOperation(request, sendParameters) == false)
                {
                    return;
                }
                var @message = new RoomMessage((byte)OperationCode.Chat, new&#91;&#93; { request.Code.ToString(), request.Data });
                this.RoomReference.Room.EnqueueMessage(@message);
    }
    
    Use EnqueueMessage the client can not receive message
  • Please read the complete sample above. Ben wrote how your HandleChatOperation would look like. Modify Room, the Application and LitePeer.
    If you get a BasePeer, you can try to cast it to LitePeer to use more specific methods.