Skip to content
This repository has been archived by the owner on Jun 11, 2022. It is now read-only.

Lobby id and its application #9

Closed
itzkin opened this issue Oct 8, 2013 · 30 comments
Closed

Lobby id and its application #9

itzkin opened this issue Oct 8, 2013 · 30 comments

Comments

@itzkin
Copy link

itzkin commented Oct 8, 2013

I am testing bots capabilities in regards of lobbies.
First thing I noticed is that when I bot creates a lobby the bot is present in "unassigned players", but he is not inside the lobby chat channel.
Code such as Dota2.joinChat("Lobby"); doesn't work.
Using the ingame console command dota_lobby_debug I can find the lobby id.
I added some functions to steam messaging the bot using bot.on('message') event listener. precisely

if (message.substr(0,2) == '/j') {
    console.log('asked to join chat room ' + message.substr(3,message.length));
    Dota2.joinChat(message.substr(3,message.length));
  }

Works on existing chat channels. This way I tried using the lobby ID as a chat channel name to join, but without success.

In addition I tried to make my own function to start lobbies (without success so far)
Consulting dota_gcmesages.desc and gcsdk_gcmessages.desc, and copying some functions from lobbies.js I wrote this:

Dota2.Dota2Client.prototype.launchPracticeLobby = function(callback) {
  callback = callback || null;

  /* Sends a message to the Game Coordinator requesting lobby start. */

  if (!this._gcReady) {
    if (this.debug) util.log("GC not ready, please listen for the 'ready' event.");
    return null;
  }

  if (this.debug) util.log("Sending match CMsgPracticeLobbyLaunch request");
  var payload = dota_gcmessages.CMsgPracticeLobbyLaunch.serialize({
  });

  this._client.toGC(this._appid, (Dota2.EDOTAGCMsg.k_EMsgGCPracticeLobbyLaunch | protoMask), payload, callback);
};

I enter the bot-created-lobby with my real account, join a side and add a pasive bot to the other side. When the function fires I get this in the console

8 Oct 15:45:04 - Sending match CMsgPracticeLobbyLaunch request
8 Oct 15:45:04 - Dota2 fromGC: 570, 7055
8 Oct 15:45:04 - Received a bad practiceLobbyJoinResponse
{"result":"DOTA_JOIN_RESULT_INVALID_LOBBY"}

My thought - I need to add some lobby details to the payload that is being sent. Not sure if that has to be the lobby id, or not or how to present the data to be serialized.

My questions right now:
Does GC provide the lobby id somewhere so I don't have to find it manually?
How do I make the PracticeLobbyLaunch message valid?

I will search for a dota 2 ingame console command for a list of joined channels. That should reveal the lobby chat channel name, I bet it is something like 0052534e8e679ff8_lobby or something.

@nextdimension
Copy link

Take a look at
k_EMsgGCPracticeLobbyJoinBroadcastChannel = 7149;

To laucnh practice lobby you must have at least 1 player on a team, then use the function that you already have
CMsgPracticeLobbyLaunch

@nextdimension
Copy link

The problem I have is, when I launch the practice lobby with the bot as spectator, the game fails to load because of course the bot is not actually in the game so can't load.

Launching the practice lobby via the bot is useless because of this.

@itzkin
Copy link
Author

itzkin commented Oct 8, 2013

Even after I send the bot to a broadcast channel I still get "INVALID_LOBBY" response when I try to launch it.
Can you share the code you use to apply CMsgPracticeLobbyLaunch ?

@rjackson
Copy link
Member

rjackson commented Oct 8, 2013

With regards to launching lobbies, you are both correct in that the library currently does not support this - refer to issue #10 for discussion on that

With regards to joining a lobby's chat, you will need to specify that you're joining a lobby via the second argument - Dota2.joinChat("Lobby name", dota2.DOTAChatChannelType_t.DOTAChannelType_Lobby). I'm not sure what format the chat channel name is however, we might need to spy on steam via Nethook to determine that - I'll note that down on my TODO list, unless somebody wants to take a stab at it before I get around to it.

@nextdimension
Copy link

I didn't even realize nethook existed, I will try to play around with it, thanks!

@itzkin
Copy link
Author

itzkin commented Oct 10, 2013

OK, I have a new question.
Say I want my bot to spectate a game. I found that you can join an active game using
steam://connect/XXX.XX.XXX.XX:XXXX/YYYY
where XXX.XX.XXX.XX:XXXX is the ip and port from the ingame console command "status" and YYYY is the lobby password.
Can I make the bot follow that link?
Is there anyway for the bot to recieve match info for lobby games?

@rjackson
Copy link
Member

No, the bot cannot connect to servers, see issue #10.

As for getting lobby details, just feed it some lobby match ids and see what happens. I don't think you can view info on other peoples lobby games, but I'm not sure.

@itzkin
Copy link
Author

itzkin commented Oct 11, 2013

There is an option in the lobby settings to enable or disable spectators. So private lobbies are spectatable (that is how tournaments work)
"just feed it some lobby match ids and see what happens"
Not sure what you mean by that. CMsgPracticeLobbyJoin a lobby that has started?

@rjackson
Copy link
Member

I mean send a matchDetailsRequest with a lobby match id.

@itzkin
Copy link
Author

itzkin commented Oct 12, 2013

I managed to compile nethook2 and nethookanalyzer. Here is an example of what it had to offer.
analyzer

I noticed that the channel_name was using the decimal value of the lobby ID so I went and did a parseInt(hexString, 16) on the next lobby I made and told the bot to Dota2.joinChat('Lobby_'+decimal_ID) it went on and created it as a new channel room.
I see channel_id, maybe using that will help?

@rjackson
Copy link
Member

I'm not sure what you mean with regards to the hexadecimal and decimal comments, 0x653829 is 6633513, not the long number in the channel_name.

The response object is giving you the channel_name property because there is likely no correlation between lobby id and lobby chat id, so you just want to use that property - no need to do anything complicated. You're also not telling the GC servers that you're trying to join a lobby chat, not a regular chat, which is why it was creating a new room.

Try

Dota2.on("practiceLobbyJoinResponse", function(result, response){
    Dota2.joinChat(response.channelName, dota2.DOTAChatChannelType_t.DOTAChannelType_Lobby);
});

@itzkin
Copy link
Author

itzkin commented Oct 14, 2013

The ID I read from the ingame console using dota_lobby_debug is a hexadecimal number (i.e. 005259a9d570e2e8 ) The channel_name for the lobby chat is using a number that is equal to the lobby id, only converted to decimal (23179534055564010 for this example).

Now I tried your code and couldn't make it work. Fiddling around I found that must be because of the "DOTA_JOIN_RESULT_ALREADY_IN_GAME" message, which is a bad practiceLobbyJoinResponce and wasn't emitting anything. Inside lobbies.js handlers I added this.emit("practiceLobbyJoinResponse", practiceLobbyJoinResponse.result, practiceLobbyJoinResponse); for the case of bad responses, correct me if I did wrong.
I was receiving "undefined" for response.channelName in your suggestion so I went on and gave it the channel name manually (converting lobby id to decimal, adding 'Lobby_' in the start). Now I get "DOTA_JOIN_RESULT_INVALID_LOBBY"
I still don't know how to fetch the lobby id using node. I am using my real steam account to join the lobby made by the bot, open the ingame console and type dota_lobby_debug

@AncientiCe
Copy link

Well, creating the launch method is not actually a big deal.
Just send an empty payload and don't mind the response of it. (Take notice you have to serialize it based on the message ).
Didn't figure out how to pass the Failed to load thing. Closed spectators/Moved bot to broadcasting/tried to ReadyUp method after launching the game/Told the bot to quit the game after launching by Abandon etc..
How do i get the lobby_id dinamically? CMsgReadyUpStatus might do the trick.

@paralin
Copy link
Contributor

paralin commented Apr 29, 2014

I would say this is all fixed now with my latest patch.

I've brought up some other questions in other issues.

@AncientiCe
Copy link

Considering the last update from kidovate we now have the lobby id and the game server the bot has to connect to. In order to make it work and not fail to load all the time we need to create a new udp connection to that ip:port and send a message. This message is probably a "keep alive" type message and we have to send it until the game says connected. I'm not sure this is what has to be done but maybe some1 can help and dissect the packages from/to the game server itself.

@bontscho
Copy link
Contributor

bontscho commented May 6, 2014

@AncientiCe i'm also looking into that kind of feature, i'm new in that field but i'm happy to help, lemme know if i can help you work that out

@paralin
Copy link
Contributor

paralin commented May 6, 2014

@AncientiCe @bontscho It's a regular Source engine multiplayer server. Just look at the Source SDK (source code of the Source engine) https://github.com/ValveSoftware/source-sdk-2013 and write a super lightweight client. Name it something like node-source.

@AncientiCe
Copy link

Will see what i can do with it. For the moment I've started to dissect the packages.

@AncientiCe
Copy link

Failed to load the SDK @kidovate mentioned. Anyone did this? Not a VS fan.

@AncientiCe
Copy link

Update:
Basically, I "think" the first C->S packet is:

  1. Defenetly simple response format since it starts with -1 (0xFFFFFFFF)
  2. 16 byte of payload
  3. Possible payload format is:
    (byte) which seems to be 0x71 in all my caps, which is G in ascii. It is probably safe to assume that single bytes are actually chars
    (long) 4 byte "ID" which seems to re-appear in next packets
    11 bytes of unknown format but which don't seem to change, at least not in my caps
    I defenetly need more caps from more people
    I am also pretty sure that the Payload part is specific to each different Source game so digging around the steam SDK is of no use
    I also found this snippet on google, to join as spectator into d2 game:

connect 146.66.152.163:28024
Connecting to public(146.66.152.163:28024) ...
0.029: Sending UDP connect to public IP 146.66.152.163:28024
NotifyClientSignon: 2
Connected to 146.66.152.163:28024

Dota 2
Map: dota
Players: 9 (1 bots) / 24 humans
Build: 4848
Server Number: 1
This is done from the console

@uside
Copy link

uside commented Jun 18, 2014

Hi all! I'm new in this stuff and have one question: how you dump queries?

@jimmydorry
Copy link
Member

Why would you not make a new issue... or even google it? http://bit.ly/1l2kB2h

@AncientiCe
Copy link

I've been busy past days. Me and a friend have been working to dissect the game server messages.
For the moment i got few exams, but will continue asap.

@uside
Copy link

uside commented Jun 18, 2014

Why would you not make a new issue... or even google it? http://bit.ly/1l2kB2h

I asked how you dump net packets from dota2 client to gc for use in protobuf...

@jimmydorry
Copy link
Member

You use nethook and nethook analyser for that.

https://github.com/SteamRE/SteamKit/tree/master/Resources/NetHook2
https://github.com/SteamRE/SteamKit/tree/master/Resources/NetHookAnalyzer

There may be a guide somewhere, but you essentially need winject to inject the nethook and look at the queries the dota client makes,

@AncientiCe
Copy link

Anyone got anywhere with this issue?
Any solution or even a hint?

@paralin
Copy link
Contributor

paralin commented Jul 28, 2014

Yes, my patch gave the ability to read the lobby ID on the OnCreated event

@paralin
Copy link
Contributor

paralin commented Jul 28, 2014

@AncientiCe
Copy link

This still doesn't allow the game to run when launched. It fails because the bot as spectator doesn't connect to the game server. It was mentioned in the previous comments.

@bontscho
Copy link
Contributor

i think we should wrap this up and spawn separate issues instead of mixing a lot of topics into one big issue

@AncientiCe in terms of connecting to the game it's safe to say that node-dota2 won't be able to realize that in the near future (if at all), it's source multiplayer. if you wish to discuss this further, please do so in its own issue.

as of for the original issue, this has been resolved thanks to @kidovate

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants