Author Topic: Access Lobby Server Details Externally  (Read 2292 times)

rxmarcus

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 62
    • View Profile
Access Lobby Server Details Externally
« on: August 01, 2017, 10:38:26 AM »
I know this is a long shot, but figured I'd ask.

Is there any way possible that I could access the details of my Lobby Server via an HTTP request that could send me JSON for example?

I'm wanting to write a bot for my game's discord channel that will post when players host new matches on the lobby server so other players are aware.
Any thoughts are appreciated!

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Access Lobby Server Details Externally
« Reply #1 on: August 01, 2017, 06:26:32 PM »
If you go to your lobby server from web browser you should get # of servers, # of players, and for each server the # of players on that server and that servers name. It isn't returned in JSON but might work for your purposes?

But if you're still using the dedicated server, then new matches are just new channels, right? So you'd want to access your dedicated game server in addition to the lobby server for full coverage. But the game server doesn't spit out channels when accessing via web, so you'd either have to modify that or rely on player count to determine how many channels there are (since I think your game has locked player count per match?)

Search "case Packet.RequestHTTPGet:" in both TNGameServer.cs and TNTcpLobbyServer.cs for the relevant code. "if (mExpected == 542393671)" in TNTcpProtocol.cs is what determines if a packet is from a web browser and does some pre-processing.

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Access Lobby Server Details Externally
« Reply #2 on: August 01, 2017, 08:59:11 PM »
For game server:
  1. case Packet.RequestHTTPGet:
  2.         {
  3.                 if (player.stage == TcpProtocol.Stage.WebBrowser)
  4.                 {
  5.                         // string requestText = reader.ReadString();
  6.                         // Example of an HTTP request:
  7.                         // GET / HTTP/1.1
  8.                         // Host: 127.0.0.1:5127
  9.                         // Connection: keep-alive
  10.                         // User-Agent: Chrome/47.0.2526.80
  11.                         StringBuilder sb = new StringBuilder();
  12.  
  13.                         string requestText = reader.ReadString();
  14.                         if (!string.IsNullOrEmpty(requestText))
  15.                         {
  16.                                 int getIndex = requestText.IndexOf("GET");
  17.                                 int httpIndex = requestText.IndexOf("HTTP");
  18.                                 // lots of sanity checking here. probably not necessary.
  19.                                 if ((getIndex == 0) && (httpIndex > 0) && (requestText.Length > httpIndex + 1))
  20.                                 {
  21.                                         // input: 192.168.1.2:5127/channels/json
  22.                                         // parsed: channels/json
  23.                                         // parts: { "channels", "json" }
  24.                                         requestText = requestText.Substring(5, (httpIndex - 6));
  25.                                         string[] parts = requestText.Split('/');
  26.                                         // proposed format:
  27.                                         // data_type / (opt) output_format / (opt) additional_data
  28.                                         switch (parts[0])
  29.                                         {
  30.                                                 case "channels":
  31.                                                         {
  32.                                                                 if (parts.Length > 1)
  33.                                                                 {
  34.                                                                         if (parts[1] == "json")
  35.                                                                         {
  36.                                                                                 // TO-DO:
  37.                                                                                 // return channels data as json
  38.                                                                                 sb.Append("Unsupported");
  39.                                                                                 break;
  40.                                                                         }
  41.                                                                 }
  42.                                                                 // return channels data as raw
  43.                                                                 for (int index = 0; index < mChannelList.size; index++)
  44.                                                                 {
  45.                                                                         Channel ch = mChannelList.buffer[index];
  46.                                                                         sb.Append(ch.id);
  47.                                                                         sb.Append("|");
  48.                                                                         sb.Append(ch.players.size);
  49.                                                                         sb.Append("|");
  50.                                                                         sb.Append(ch.playerLimit);
  51.                                                                         sb.Append("|");
  52.                                                                         sb.Append(ch.host.name);
  53.                                                                         sb.Append("|");
  54.                                                                         sb.Append(ch.level);
  55.                                                                         sb.Append("|");
  56.                                                                         sb.AppendLine((ch.isOpen && !ch.isLocked && string.IsNullOrEmpty(ch.password)).ToString());
  57.                                                                 }
  58.                                                                 break;
  59.                                                         }
  60.                                         }
  61.                                 }
  62.                         }
  63.                         else
  64.                         {
  65.                                 // Server name
  66.                                 sb.Append("Name: ");
  67.                                 sb.AppendLine(name);
  68.  
  69.                                 // Number of connected clients
  70.                                 sb.Append("Clients: ");
  71.                                 sb.AppendLine(playerCount.ToString());
  72.  
  73.                                 // Detailed list of clients
  74.                                 for (int i = 0, count = 0; i < mPlayerList.size; ++i)
  75.                                 {
  76.                                         TcpPlayer p = (TcpPlayer)mPlayerList[i];
  77.  
  78.                                         if (p.stage == TcpProtocol.Stage.Connected)
  79.                                         {
  80.                                                 sb.Append(++count);
  81.                                                 sb.Append(" ");
  82.                                                 sb.AppendLine(p.name);
  83.                                         }
  84.                                 }
  85.                         }
  86.                         // Create the header indicating that the connection should be severed after receiving the data
  87.                         string text = sb.ToString();
  88.                         sb = new StringBuilder();
  89.                         sb.AppendLine("HTTP/1.1 200 OK");
  90.                         sb.AppendLine("Server: TNet 3");
  91.                         sb.AppendLine("Content-Length: " + text.Length);
  92.                         sb.AppendLine("Content-Type: text/plain");
  93.                         sb.AppendLine("Connection: Closed\n");
  94.                         sb.Append(text);
  95.  
  96.                         // Send the response
  97.                         mBuffer = Buffer.Create();
  98.                         BinaryWriter bw = mBuffer.BeginWriting(false);
  99.                         bw.Write(Encoding.ASCII.GetBytes(sb.ToString()));
  100.                         player.SendTcpPacket(mBuffer);
  101.                         mBuffer.Recycle();
  102.                         mBuffer = null;
  103.                 }
  104.                 break;
  105.         }
  106.  
Navigating to "192.168.1.2:5127/channels" in a web browser produces:
  1. 1|1|2|Editor|world|True
  2.  

It's super sloppy. I'd recommend splitting all web logic into its own class, like how LobbyLink is separate from GameServer. Maybe use HttpListener in this class, too, to reduce the amount of work you'd have to do.

rxmarcus

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 62
    • View Profile
Re: Access Lobby Server Details Externally
« Reply #3 on: August 02, 2017, 11:48:46 AM »
Wow, thanks for the detailed response and direction.
This should definitely push me towards what I was wanting!