Comments (40)
from dotaservice.
By the way, I see that you are using "auto-generated files" as a means to communicate between the bots and the agent. This assumes they always exist on the same hardware, basically disallowing the possibility of dotaservice running on one physical host while the agent code runs on a different one (well, short of doing network file transfers between the two).
I previously implemented the comms method of using CreateHTTPRequest() API (and I believe there is also a CreateRemoteHTTPRequest() API - could be wrong - Valve kept flip-flopping between allowing this and not):
https://github.com/Nostrademous/Dota2-WebAI/blob/master/webserver_out.lua#L443-L467
While not necessarily "reliable", it is WAY faster than using files as a comms method. Currently I'm seeing the Think() function take 18-20ms for Nevermore, whereas I believe the method I had above was about 10x less time. I believe this has to do with "loadfile" being rather slow, but I could be wrong.
from dotaservice.
from dotaservice.
I'm fine with file passing providing it's "fast enough" which I believe it is.
Back to the initial question though - as we slowly transition to 5 agents and self-play (10 agents) - what about courier/glyph/scan functions - are they part of each agent or their own entities?
from dotaservice.
from dotaservice.
which library/executable did the "Init" reside in?
I guess I'm asking if you know if the functions I am to find the signatures for exist in the main dota2 binary or a specific library that gets loaded for handling bots
from dotaservice.
from dotaservice.
Observe(size_t teamID, void *, void *)
First arg is team ID. 2 for Radiant, 3 for Dire.
Busy with kids right now but I believe 2nd will be pointer to protobuf.
from dotaservice.
from dotaservice.
* thread #1, name = 'MainThrd', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000090f2f9e0 botcpp_radiant.so`Observe
frame #1: 0x00000000892c53e1 libserver.dylib`___lldb_unnamed_symbol90409$$libserver.dylib + 769
frame #2: 0x00000000892bc2cd libserver.dylib`___lldb_unnamed_symbol90399$$libserver.dylib + 925
frame #3: 0x000000008923ab65 libserver.dylib`___lldb_unnamed_symbol89338$$libserver.dylib + 629
frame #4: 0x0000000088829641 libserver.dylib`___lldb_unnamed_symbol30869$$libserver.dylib + 129
frame #5: 0x0000000088b5c8bb libserver.dylib`___lldb_unnamed_symbol46417$$libserver.dylib + 155
frame #6: 0x0000000088b385c6 libserver.dylib`___lldb_unnamed_symbol45980$$libserver.dylib + 1510
frame #7: 0x00000000064b97d7 libengine2.dylib`___lldb_unnamed_symbol7478$$libengine2.dylib + 503
frame #8: 0x000000000639c3fe libengine2.dylib`___lldb_unnamed_symbol2598$$libengine2.dylib + 174
frame #9: 0x0000000006398b5e libengine2.dylib`___lldb_unnamed_symbol2557$$libengine2.dylib + 126
frame #10: 0x00000000063950a7 libengine2.dylib`___lldb_unnamed_symbol2521$$libengine2.dylib + 2855
frame #11: 0x0000000006387c8b libengine2.dylib`___lldb_unnamed_symbol2351$$libengine2.dylib + 1339
frame #12: 0x0000000006387712 libengine2.dylib`___lldb_unnamed_symbol2350$$libengine2.dylib + 18
frame #13: 0x000000000637b150 libengine2.dylib`___lldb_unnamed_symbol2189$$libengine2.dylib + 384
frame #14: 0x000000000637b880 libengine2.dylib`___lldb_unnamed_symbol2190$$libengine2.dylib + 1040
frame #15: 0x000000000637bbaa libengine2.dylib`Source2Main + 298
frame #16: 0x000000000630cd65 dota2`___lldb_unnamed_symbol6$$dota2 + 197
frame #17: 0x00007fff69c6908d libdyld.dylib`start + 1
That's the callstack to get to our Observe call
from dotaservice.
The only open q is: what should Act return?
from dotaservice.
I agree, makes the most sense, but wouldn't it have to be wrapped in a CMsgBotWorldState anyways?
from dotaservice.
How? What do you mean?
from dotaservice.
Well, isn't the Msg Actions protobuf embedded inside the CMsgBotWorldState?
from dotaservice.
from dotaservice.
Okay, at least reading the Observe() is done.
Example Code:
extern "C" void Observe(int teamID, const CMsgBotWorldState &ws) {
// The intention of this script is most probably to setup a connection with the
// worldstate sockets. Kinda weird though, because the dota game would be the server
// and then this script would be the client of that..
// Observe is called every tick that corresponds to the worldstate server's ticks,
// Exactly before the Act() is called.
cout << "Observe::cout" << endl;
cout << "TeamID: " << ws.team_id() << endl;
cout << "DotaTime: " << ws.dota_time() << endl;
cout << "GameState: " << ws.game_state() << endl;
for (CMsgBotWorldState_Player player : ws.players() ) {
cout << "\tPlayerID: " << player.player_id() << endl;
cout << "\tHeroID: " << player.hero_id() << endl;
}
}
Example Output:
Observe::cout
TeamID: 2
DotaTime: -77.2335
GameState: 4
PlayerID: 0
HeroID: 11
PlayerID: 1
HeroID: 35
PlayerID: 2
HeroID: 35
PlayerID: 3
HeroID: 35
PlayerID: 4
HeroID: 35
PlayerID: 5
HeroID: 35
PlayerID: 6
HeroID: 35
PlayerID: 7
HeroID: 35
PlayerID: 8
HeroID: 35
PlayerID: 9
HeroID: 35
from dotaservice.
from dotaservice.
Well, we could do a guessing game, but how will we know when we are right?
from dotaservice.
from dotaservice.
Well I agree... so easy to test.
from dotaservice.
So it's (probably)
const CMsgBotWorldState::Actions& Act(int team_id)
But the action is: what are the strictly required values? Or possibly, we might need to return something in Init (or Observe) that toggles some functionality. And still: why is it that we need to keep the worldstate sockets open?
from dotaservice.
So I assume we need to open the socket in Init() just to trigger pumping the world state through the ports.
from dotaservice.
could it not be:
extern "C" void Act(int team_id, CMsgBotWorldState_Actions &msg)
I'm thinking that way we don't have to allocate the protobuf and keep track of the memory. Perhaps an INOUT variable.
from dotaservice.
Tried a bunch of stuff, can't say i was successful on Act() yet.
from dotaservice.
from dotaservice.
Will check back tomorrow and work some more on it. 1am here and I have to get up at 6am. Calling it a night for now.
from dotaservice.
I'm thinking there is a 2nd arg to Act() (only valid after game starts, it's NULL during hero selection. I believe it might be the ArenaAllocator().
Currently this compiles and doesn't crash but still doesn't move.
CMsgBotWorldState_Actions * actions_pb;
CMsgBotWorldState_Action_MoveToLocation * mtl_pb;
CMsgBotWorldState_Vector * loc_pb;
// Returning std::shared_ptr<CMsgBotWorldState::Actions> crashes upon return.
// Returning CMsgBotWorldState::Actions craches.
// void, void *, char* is fine, even if its contents are totally bogus.
extern "C" const CMsgBotWorldState::Actions * Act(int team_id) {
// Act seems to be called practically _exactly_ after Observe is called.
// Since it is called once per team, all team-decisions need to be made here. That means
// that we need to communicate all actions. Probably that means we need to return the actions
// protobuf somehow. I think returning the protobuffer itself, from this function makes
// the most sense.
// This call is fully blocking the entire game, so possible they are indeed waiting for a
// synchronous return.
auto timenow = chrono::system_clock::to_time_t(chrono::system_clock::now());
cout << "Act::cout @" << ctime(&timenow) << endl;
cout << "TeamID: " << team_id << endl;
mtl_pb = new CMsgBotWorldState_Action_MoveToLocation;
loc_pb = new CMsgBotWorldState_Vector;
loc_pb->set_x(0.0);
loc_pb->set_y(0.0);
loc_pb->set_z(0.0);
cout << "loc set - addr: " << loc_pb << endl;
mtl_pb->add_units(test_id);
mtl_pb->set_allocated_location(loc_pb);
actions_pb = new CMsgBotWorldState_Actions;
cout << "new actions_pb created" << endl;
CMsgBotWorldState_Action * action_pb = actions_pb->add_actions();
cout << "action_pb referenced" << endl;
action_pb->set_actiontype(CMsgBotWorldState_Action_Type_DOTA_UNIT_ORDER_MOVE_TO_POSITION);
action_pb->set_player(4);
action_pb->set_allocated_movetolocation(mtl_pb);
std::string s;
if (google::protobuf::TextFormat::PrintToString(*actions_pb, &s)) {
std::cout << "Your message:\n" << s;
} else {
std::cerr << "Message not valid (partial content: " << actions_pb->ShortDebugString() << ")\n";
}
cout << "Gonna return from act..\n";
return actions_pb;
}
BTW, as expected, the first arg of Init() is int teamID
from dotaservice.
Notes for self:
* thread #1, name = 'MainThrd', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000090a539e0 botcpp_radiant.so`Act
frame #1: 0x00000000893523f5 libserver.dylib`___lldb_unnamed_symbol90409$$libserver.dylib + 789
frame #2: 0x00000000893492cd libserver.dylib`___lldb_unnamed_symbol90399$$libserver.dylib + 925
frame #3: 0x00000000892c7b65 libserver.dylib`___lldb_unnamed_symbol89338$$libserver.dylib + 629
frame #4: 0x00000000888b6651 libserver.dylib`___lldb_unnamed_symbol30869$$libserver.dylib + 129
frame #5: 0x0000000088be98cb libserver.dylib`___lldb_unnamed_symbol46417$$libserver.dylib + 155
frame #6: 0x0000000088bc55d6 libserver.dylib`___lldb_unnamed_symbol45980$$libserver.dylib + 1510
frame #7: 0x000000000de567d7 libengine2.dylib`___lldb_unnamed_symbol7478$$libengine2.dylib + 503
frame #8: 0x000000000dd393fe libengine2.dylib`___lldb_unnamed_symbol2598$$libengine2.dylib + 174
frame #9: 0x000000000dd35b5e libengine2.dylib`___lldb_unnamed_symbol2557$$libengine2.dylib + 126
frame #10: 0x000000000dd320a7 libengine2.dylib`___lldb_unnamed_symbol2521$$libengine2.dylib + 2855
frame #11: 0x000000000dd24c8b libengine2.dylib`___lldb_unnamed_symbol2351$$libengine2.dylib + 1339
frame #12: 0x000000000dd24712 libengine2.dylib`___lldb_unnamed_symbol2350$$libengine2.dylib + 18
frame #13: 0x000000000dd18150 libengine2.dylib`___lldb_unnamed_symbol2189$$libengine2.dylib + 384
frame #14: 0x000000000dd18880 libengine2.dylib`___lldb_unnamed_symbol2190$$libengine2.dylib + 1040
frame #15: 0x000000000dd18baa libengine2.dylib`Source2Main + 298
frame #16: 0x000000000dca9d65 dota2`___lldb_unnamed_symbol6$$dota2 + 197
frame #17: 0x00007fff69c6908d libdyld.dylib`start + 1
from dotaservice.
It's also very much possible the 2nd argument is actually a pointer to an already created [empty] Actions protobuf...
from dotaservice.
Function that calls our botcpp_*.so
0x8931f3f3 is where Act() is called
(lldb) disassemble --frame -mixed
libserver.dylib`___lldb_unnamed_symbol90409$$libserver.dylib:
0x8931f0e0 <+0>: pushq %rbp
0x8931f0e1 <+1>: movq %rsp, %rbp
0x8931f0e4 <+4>: pushq %r15
0x8931f0e6 <+6>: pushq %r14
0x8931f0e8 <+8>: pushq %r13
0x8931f0ea <+10>: pushq %r12
0x8931f0ec <+12>: pushq %rbx
0x8931f0ed <+13>: subq $0x18, %rsp
0x8931f0f1 <+17>: movq %rdi, %r15
0x8931f0f4 <+20>: movq 0xdca14d(%rip), %r13 ; (void *)0x0000000006bb6418: g_VProfCurrentProfile
0x8931f0fb <+27>: movl 0x1020(%r13), %r12d
0x8931f102 <+34>: testl %r12d, %r12d
0x8931f105 <+37>: je 0x8931f1d7 ; <+247>
0x8931f10b <+43>: rdtsc
0x8931f10d <+45>: movq %rdx, %rbx
0x8931f110 <+48>: shlq $0x20, %rbx
0x8931f114 <+52>: orq %rax, %rbx
0x8931f117 <+55>: movq 0x1020(%r13), %rax
0x8931f11e <+62>: testl %eax, %eax
0x8931f120 <+64>: jne 0x8931f131 ; <+81>
0x8931f122 <+66>: movabsq $0xff00000000, %rcx ; imm = 0xFF00000000
0x8931f12c <+76>: andq %rcx, %rax
0x8931f12f <+79>: jne 0x8931f1a2 ; <+194>
0x8931f131 <+81>: movq 0x1e18(%r13), %r14
0x8931f138 <+88>: callq 0x89c883b4 ; symbol stub for: ThreadGetCurrentId
0x8931f13d <+93>: cmpq %rax, %r14
0x8931f140 <+96>: jne 0x8931f1a2 ; <+194>
0x8931f142 <+98>: movq 0x1028(%r13), %rax
0x8931f149 <+105>: leaq 0xb8b5c9(%rip), %rcx ; "CDOTA_TeamCommander::SendBotWorldStateToSocket"
0x8931f150 <+112>: cmpq %rcx, (%rax)
0x8931f153 <+115>: je 0x8931f17a ; <+154>
0x8931f155 <+117>: leaq 0xb8b5bd(%rip), %rsi ; "CDOTA_TeamCommander::SendBotWorldStateToSocket"
0x8931f15c <+124>: leaq 0xb7d0b0(%rip), %rcx ; "Bots"
0x8931f163 <+131>: xorl %edx, %edx
0x8931f165 <+133>: movl $0x4, %r8d
0x8931f16b <+139>: movq %rax, %rdi
0x8931f16e <+142>: callq 0x89c88636 ; symbol stub for: CVProfNode::GetSubNode(char const*, int, char const*, int)
0x8931f173 <+147>: movq %rax, 0x1028(%r13)
0x8931f17a <+154>: movslq 0x70(%rax), %rax
0x8931f17e <+158>: movq 0x10e0(%r13), %rcx
0x8931f185 <+165>: shlq $0x4, %rax
0x8931f189 <+169>: orl $0x4, 0x8(%rcx,%rax)
0x8931f18e <+174>: movq 0x1028(%r13), %rdi
0x8931f195 <+181>: callq 0x89c88630 ; symbol stub for: CVProfNode::EnterScope()
0x8931f19a <+186>: movb $0x0, 0x1024(%r13)
0x8931f1a2 <+194>: rdtsc
0x8931f1a4 <+196>: shlq $0x20, %rdx
0x8931f1a8 <+200>: orq %rax, %rdx
0x8931f1ab <+203>: subq %rbx, %rdx
0x8931f1ae <+206>: movdqu 0x1010(%r13), %xmm0
0x8931f1b7 <+215>: movq %rdx, %xmm1
0x8931f1bc <+220>: movl $0x1, %eax
0x8931f1c1 <+225>: movq %rax, %xmm2
0x8931f1c6 <+230>: punpcklqdq %xmm2, %xmm1 ; xmm1 = xmm1[0],xmm2[0]
0x8931f1ca <+234>: paddq %xmm0, %xmm1
0x8931f1ce <+238>: movdqu %xmm1, 0x1010(%r13)
0x8931f1d7 <+247>: movq 0x11f0(%r15), %rdi
0x8931f1de <+254>: callq 0x892edb60 ; ___lldb_unnamed_symbol90248$$libserver.dylib
0x8931f1e3 <+259>: movq 0x11f0(%r15), %rbx
0x8931f1ea <+266>: cmpl $-0x1, 0x8(%rbx)
0x8931f1ee <+270>: jne 0x8931f23c ; <+348>
0x8931f1f0 <+272>: cmpl $0x0, (%rbx)
0x8931f1f3 <+275>: je 0x8931f23c ; <+348>
0x8931f1f5 <+277>: leaq 0x8(%rbx), %rsi
0x8931f1f9 <+281>: leaq 0x10(%rbx), %rdi
0x8931f1fd <+285>: leaq -0x30(%rbp), %rdx
0x8931f201 <+289>: callq 0x89b34c50 ; ___lldb_unnamed_symbol148171$$libserver.dylib
0x8931f206 <+294>: testl %eax, %eax
0x8931f208 <+296>: jne 0x8931f23c ; <+348>
0x8931f20a <+298>: cmpq $0x0, 0x70(%rbx)
0x8931f20f <+303>: jne 0x8931f23c ; <+348>
0x8931f211 <+305>: cmpb $0x0, 0xc(%rbx)
0x8931f215 <+309>: je 0x8931f23c ; <+348>
0x8931f217 <+311>: movq $0x0, (%rsp)
0x8931f21f <+319>: leaq -0x31606(%rip), %rdi ; ___lldb_unnamed_symbol90249$$libserver.dylib
0x8931f226 <+326>: xorl %edx, %edx
0x8931f228 <+328>: xorl %ecx, %ecx
0x8931f22a <+330>: xorl %r8d, %r8d
0x8931f22d <+333>: xorl %r9d, %r9d
0x8931f230 <+336>: movq %rbx, %rsi
0x8931f233 <+339>: callq 0x89c88294 ; symbol stub for: CreateSimpleThread
0x8931f238 <+344>: movq %rax, 0x70(%rbx)
0x8931f23c <+348>: movq 0x11f0(%r15), %rbx
0x8931f243 <+355>: movl 0x8(%rbx), %esi
0x8931f246 <+358>: cmpl $-0x1, %esi
0x8931f249 <+361>: je 0x8931f463 ; <+899>
0x8931f24f <+367>: leaq 0x10(%rbx), %r14
0x8931f253 <+371>: movq %r14, %rdi
0x8931f256 <+374>: callq 0x89b345f0 ; ___lldb_unnamed_symbol148161$$libserver.dylib
0x8931f25b <+379>: cmpl $0x3, %eax
0x8931f25e <+382>: jne 0x8931f463 ; <+899>
0x8931f264 <+388>: movb $0x0, -0x2a(%rbp)
0x8931f268 <+392>: movl 0x8(%rbx), %esi
0x8931f26b <+395>: leaq 0x19c5ad6(%rip), %rcx ; pcre_stack_free + 1080
0x8931f272 <+402>: leaq -0x2a(%rbp), %rdx
0x8931f276 <+406>: movl $0x1, %r8d
0x8931f27c <+412>: movq %r14, %rdi
0x8931f27f <+415>: callq 0x89b34470 ; ___lldb_unnamed_symbol148159$$libserver.dylib
0x8931f284 <+420>: testl %eax, %eax
0x8931f286 <+422>: jne 0x8931f463 ; <+899>
0x8931f28c <+428>: cmpb $0x0, -0x2a(%rbp)
0x8931f290 <+432>: je 0x8931f463 ; <+899>
0x8931f296 <+438>: movq 0x11f0(%r15), %r14
0x8931f29d <+445>: leaq 0x19f973c(%rip), %rax
0x8931f2a4 <+452>: movq (%rax), %rax
0x8931f2a7 <+455>: movl 0x18(%rax), %eax
0x8931f2aa <+458>: cltd
0x8931f2ab <+459>: idivl 0x4(%r14)
0x8931f2af <+463>: testl %edx, %edx
0x8931f2b1 <+465>: jne 0x8931f463 ; <+899>
0x8931f2b7 <+471>: cmpb $0x0, 0xc(%r14)
0x8931f2bc <+476>: jne 0x8931f2c7 ; <+487>
0x8931f2be <+478>: jmp 0x8931f322 ; <+578>
0x8931f2c0 <+480>: movq 0x11f0(%r15), %r14
0x8931f2c7 <+487>: cmpl $0x0, 0x10078(%r14)
0x8931f2cf <+495>: je 0x8931f322 ; <+578>
0x8931f2d1 <+497>: movl 0x8(%r14), %esi
0x8931f2d5 <+501>: cmpl $-0x1, %esi
0x8931f2d8 <+504>: je 0x8931f322 ; <+578>
0x8931f2da <+506>: leaq 0x10(%r14), %rbx
0x8931f2de <+510>: movq %rbx, %rdi
0x8931f2e1 <+513>: callq 0x89b345f0 ; ___lldb_unnamed_symbol148161$$libserver.dylib
0x8931f2e6 <+518>: cmpl $0x3, %eax
0x8931f2e9 <+521>: jne 0x8931f322 ; <+578>
0x8931f2eb <+523>: movb $0x0, -0x29(%rbp)
0x8931f2ef <+527>: movl 0x8(%r14), %esi
0x8931f2f3 <+531>: movl $0x1, %r8d
0x8931f2f9 <+537>: movq %rbx, %rdi
0x8931f2fc <+540>: leaq -0x29(%rbp), %rdx
0x8931f300 <+544>: leaq 0x19c5a41(%rip), %rcx ; pcre_stack_free + 1080
0x8931f307 <+551>: callq 0x89b34470 ; ___lldb_unnamed_symbol148159$$libserver.dylib
0x8931f30c <+556>: testl %eax, %eax
0x8931f30e <+558>: jne 0x8931f322 ; <+578>
0x8931f310 <+560>: cmpb $0x0, -0x29(%rbp)
0x8931f314 <+564>: je 0x8931f322 ; <+578>
0x8931f316 <+566>: callq 0x89c883cc ; symbol stub for: ThreadYield
0x8931f31b <+571>: jmp 0x8931f2c0 ; <+480>
0x8931f31d <+573>: jmp 0x8931f51e ; <+1086>
0x8931f322 <+578>: leaq 0xf10(%r15), %r14
0x8931f329 <+585>: movq %r15, %rdi
0x8931f32c <+588>: movq %r14, %rsi
0x8931f32f <+591>: callq 0x8932fa30 ; ___lldb_unnamed_symbol90466$$libserver.dylib
0x8931f334 <+596>: leaq 0x1080(%r15), %rbx
0x8931f33b <+603>: movq %r14, %rdi
0x8931f33e <+606>: movq %rbx, %rsi
0x8931f341 <+609>: callq 0x8855d3b0 ; ___lldb_unnamed_symbol9268$$libserver.dylib
0x8931f346 <+614>: movq %rbx, %rdi
0x8931f349 <+617>: callq 0x8855a570 ; ___lldb_unnamed_symbol9262$$libserver.dylib
0x8931f34e <+622>: movq 0x11f0(%r15), %rbx
0x8931f355 <+629>: leaq 0x78(%rbx), %rsi
0x8931f359 <+633>: movl $0x10000, %edx ; imm = 0x10000
0x8931f35e <+638>: movq %r14, %rdi
0x8931f361 <+641>: callq 0x89a7fabc ; ___lldb_unnamed_symbol144614$$libserver.dylib
0x8931f366 <+646>: testb %al, %al
0x8931f368 <+648>: jne 0x8931f378 ; <+664>
0x8931f36a <+650>: leaq 0xb85f81(%rip), %rdi ; "Overflow in GetSerializedWorldState!\n"
0x8931f371 <+657>: xorl %eax, %eax
0x8931f373 <+659>: callq 0x89c885f4 ; symbol stub for: DevWarning(char const*, ...)
0x8931f378 <+664>: movq (%r14), %rax
0x8931f37b <+667>: movq 0x60(%rax), %rax
0x8931f37f <+671>: movq %r14, %rdi
0x8931f382 <+674>: callq *%rax
0x8931f384 <+676>: movl %eax, 0x10078(%rbx)
0x8931f38a <+682>: cmpb $0x0, 0xc(%rbx)
0x8931f38e <+686>: je 0x8931f390 ; <+688>
0x8931f390 <+688>: movq 0x11f0(%r15), %rdi
0x8931f397 <+695>: cmpb $0x0, 0xc(%rdi)
0x8931f39b <+699>: jne 0x8931f3a2 ; <+706>
0x8931f39d <+701>: callq 0x892eda10 ; ___lldb_unnamed_symbol90247$$libserver.dylib
0x8931f3a2 <+706>: leaq 0x1b60157(%rip), %rdi
0x8931f3a9 <+713>: movl $0x1, %esi
0x8931f3ae <+718>: callq 0x89c88b3a ; symbol stub for: sigsetjmp
0x8931f3b3 <+723>: testl %eax, %eax
0x8931f3b5 <+725>: je 0x8931f3ca ; <+746>
0x8931f3b7 <+727>: cmpl $0x2, 0x350(%r15)
0x8931f3bf <+735>: jne 0x8931f3f7 ; <+791>
0x8931f3c1 <+737>: leaq 0xb3144c(%rip), %rsi ; "radiant"
0x8931f3c8 <+744>: jmp 0x8931f3fe ; <+798>
0x8931f3ca <+746>: movq 0x1428(%r15), %rax
0x8931f3d1 <+753>: movq 0x18(%rax), %rcx
0x8931f3d5 <+757>: testq %rcx, %rcx
0x8931f3d8 <+760>: je 0x8931f3e8 ; <+776>
0x8931f3da <+762>: movl (%rax), %edi
0x8931f3dc <+764>: movq %r14, %rsi
0x8931f3df <+767>: callq *%rcx
0x8931f3e1 <+769>: movq 0x1428(%r15), %rax
0x8931f3e8 <+776>: movq 0x20(%rax), %rcx
0x8931f3ec <+780>: testq %rcx, %rcx
0x8931f3ef <+783>: je 0x8931f463 ; <+899>
0x8931f3f1 <+785>: movl (%rax), %edi
0x8931f3f3 <+787>: callq *%rcx
0x8931f3f5 <+789>: jmp 0x8931f463 ; <+899>
0x8931f3f7 <+791>: leaq 0xb3141e(%rip), %rsi ; "dire"
0x8931f3fe <+798>: leaq 0xb8b343(%rip), %rdi ; "Segfault in %s bot API\n"
0x8931f405 <+805>: xorl %eax, %eax
0x8931f407 <+807>: callq 0x89c88588 ; symbol stub for: Warning
0x8931f40c <+812>: movq 0x1428(%r15), %rbx
0x8931f413 <+819>: movq 0x28(%rbx), %rax
0x8931f417 <+823>: testq %rax, %rax
0x8931f41a <+826>: je 0x8931f420 ; <+832>
0x8931f41c <+828>: movl (%rbx), %edi
0x8931f41e <+830>: callq *%rax
0x8931f420 <+832>: movq 0x8(%rbx), %rdi
0x8931f424 <+836>: testq %rdi, %rdi
0x8931f427 <+839>: je 0x8931f453 ; <+883>
0x8931f429 <+841>: callq 0x89c889f0 ; symbol stub for: dlclose
0x8931f42e <+846>: testl %eax, %eax
0x8931f430 <+848>: je 0x8931f44b ; <+875>
0x8931f432 <+850>: callq 0x89c889f6 ; symbol stub for: dlerror
0x8931f437 <+855>: movq %rax, %rcx
0x8931f43a <+858>: leaq 0xb85e91(%rip), %rdi ; "Could not close old botcpp: %s\n"
0x8931f441 <+865>: xorl %eax, %eax
0x8931f443 <+867>: movq %rcx, %rsi
0x8931f446 <+870>: callq 0x89c88588 ; symbol stub for: Warning
0x8931f44b <+875>: movq $0x0, 0x8(%rbx)
0x8931f453 <+883>: movq $0x0, 0x20(%rbx)
0x8931f45b <+891>: movq $0x0, 0x18(%rbx)
0x8931f463 <+899>: testl %r12d, %r12d
0x8931f466 <+902>: je 0x8931f50f ; <+1071>
0x8931f46c <+908>: rdtsc
0x8931f46e <+910>: movq %rdx, %rbx
0x8931f471 <+913>: shlq $0x20, %rbx
0x8931f475 <+917>: orq %rax, %rbx
0x8931f478 <+920>: cmpb $0x0, 0x1024(%r13)
0x8931f480 <+928>: je 0x8931f48d ; <+941>
0x8931f482 <+930>: movl 0x1020(%r13), %eax
0x8931f489 <+937>: testl %eax, %eax
0x8931f48b <+939>: je 0x8931f4da ; <+1018>
0x8931f48d <+941>: movq 0x1e18(%r13), %r14
0x8931f494 <+948>: callq 0x89c883b4 ; symbol stub for: ThreadGetCurrentId
0x8931f499 <+953>: cmpq %rax, %r14
0x8931f49c <+956>: jne 0x8931f4da ; <+1018>
0x8931f49e <+958>: movq 0x1028(%r13), %rdi
0x8931f4a5 <+965>: callq 0x89c88642 ; symbol stub for: CVProfNode::ExitScope()
0x8931f4aa <+970>: movq 0x1028(%r13), %rcx
0x8931f4b1 <+977>: testb %al, %al
0x8931f4b3 <+979>: je 0x8931f4c8 ; <+1000>
0x8931f4b5 <+981>: movq 0x58(%rcx), %rax
0x8931f4b9 <+985>: testq %rax, %rax
0x8931f4bc <+988>: je 0x8931f4c8 ; <+1000>
0x8931f4be <+990>: movq %rax, 0x1028(%r13)
0x8931f4c5 <+997>: movq %rax, %rcx
0x8931f4c8 <+1000>: leaq 0x1030(%r13), %rax
0x8931f4cf <+1007>: cmpq %rax, %rcx
0x8931f4d2 <+1010>: sete 0x1024(%r13)
0x8931f4da <+1018>: rdtsc
0x8931f4dc <+1020>: shlq $0x20, %rdx
0x8931f4e0 <+1024>: orq %rax, %rdx
0x8931f4e3 <+1027>: subq %rbx, %rdx
0x8931f4e6 <+1030>: movdqu 0x1010(%r13), %xmm0
0x8931f4ef <+1039>: movq %rdx, %xmm1
0x8931f4f4 <+1044>: movl $0x1, %eax
0x8931f4f9 <+1049>: movq %rax, %xmm2
0x8931f4fe <+1054>: punpcklqdq %xmm2, %xmm1 ; xmm1 = xmm1[0],xmm2[0]
0x8931f502 <+1058>: paddq %xmm0, %xmm1
0x8931f506 <+1062>: movdqu %xmm1, 0x1010(%r13)
0x8931f50f <+1071>: addq $0x18, %rsp
0x8931f513 <+1075>: popq %rbx
0x8931f514 <+1076>: popq %r12
0x8931f516 <+1078>: popq %r13
0x8931f518 <+1080>: popq %r14
0x8931f51a <+1082>: popq %r15
0x8931f51c <+1084>: popq %rbp
0x8931f51d <+1085>: retq
0x8931f51e <+1086>: movq %rax, %r14
0x8931f521 <+1089>: testl %r12d, %r12d
0x8931f524 <+1092>: je 0x8931f5d4 ; <+1268>
0x8931f52a <+1098>: rdtsc
0x8931f52c <+1100>: movq %rdx, %rbx
0x8931f52f <+1103>: shlq $0x20, %rbx
0x8931f533 <+1107>: orq %rax, %rbx
0x8931f536 <+1110>: cmpb $0x0, 0x1024(%r13)
0x8931f53e <+1118>: je 0x8931f54b ; <+1131>
0x8931f540 <+1120>: movl 0x1020(%r13), %eax
0x8931f547 <+1127>: testl %eax, %eax
0x8931f549 <+1129>: je 0x8931f598 ; <+1208>
0x8931f54b <+1131>: movq 0x1e18(%r13), %r15
0x8931f552 <+1138>: callq 0x89c883b4 ; symbol stub for: ThreadGetCurrentId
0x8931f557 <+1143>: cmpq %rax, %r15
0x8931f55a <+1146>: jne 0x8931f598 ; <+1208>
0x8931f55c <+1148>: movq 0x1028(%r13), %rdi
0x8931f563 <+1155>: callq 0x89c88642 ; symbol stub for: CVProfNode::ExitScope()
0x8931f568 <+1160>: movq 0x1028(%r13), %rcx
0x8931f56f <+1167>: testb %al, %al
0x8931f571 <+1169>: je 0x8931f586 ; <+1190>
0x8931f573 <+1171>: movq 0x58(%rcx), %rax
0x8931f577 <+1175>: testq %rax, %rax
0x8931f57a <+1178>: je 0x8931f586 ; <+1190>
0x8931f57c <+1180>: movq %rax, 0x1028(%r13)
0x8931f583 <+1187>: movq %rax, %rcx
0x8931f586 <+1190>: leaq 0x1030(%r13), %rax
0x8931f58d <+1197>: cmpq %rax, %rcx
0x8931f590 <+1200>: sete 0x1024(%r13)
0x8931f598 <+1208>: rdtsc
0x8931f59a <+1210>: jmp 0x8931f5a1 ; <+1217>
0x8931f59c <+1212>: movq %rax, %r14
0x8931f59f <+1215>: rdtsc
0x8931f5a1 <+1217>: shlq $0x20, %rdx
0x8931f5a5 <+1221>: orq %rax, %rdx
0x8931f5a8 <+1224>: subq %rbx, %rdx
0x8931f5ab <+1227>: movdqu 0x1010(%r13), %xmm0
0x8931f5b4 <+1236>: movq %rdx, %xmm1
0x8931f5b9 <+1241>: movl $0x1, %eax
0x8931f5be <+1246>: movq %rax, %xmm2
0x8931f5c3 <+1251>: punpcklqdq %xmm2, %xmm1 ; xmm1 = xmm1[0],xmm2[0]
0x8931f5c7 <+1255>: paddq %xmm0, %xmm1
0x8931f5cb <+1259>: movdqu %xmm1, 0x1010(%r13)
0x8931f5d4 <+1268>: movq %r14, %rdi
0x8931f5d7 <+1271>: callq 0x89c88942 ; symbol stub for: _Unwind_Resume
0x8931f5dc <+1276>: movq %rax, %rcx
0x8931f5df <+1279>: rdtsc
0x8931f5e1 <+1281>: jmp 0x8931f5e8 ; <+1288>
0x8931f5e3 <+1283>: movq %rax, %rcx
0x8931f5e6 <+1286>: rdtsc
0x8931f5e8 <+1288>: shlq $0x20, %rdx
0x8931f5ec <+1292>: orq %rax, %rdx
0x8931f5ef <+1295>: subq %rbx, %rdx
0x8931f5f2 <+1298>: movdqu 0x1010(%r13), %xmm0
0x8931f5fb <+1307>: movq %rdx, %xmm1
0x8931f600 <+1312>: movl $0x1, %eax
0x8931f605 <+1317>: movq %rax, %xmm2
0x8931f60a <+1322>: punpcklqdq %xmm2, %xmm1 ; xmm1 = xmm1[0],xmm2[0]
0x8931f60e <+1326>: paddq %xmm0, %xmm1
0x8931f612 <+1330>: movdqu %xmm1, 0x1010(%r13)
0x8931f61b <+1339>: movq %rcx, %rdi
0x8931f61e <+1342>: callq 0x883c0460 ; ___lldb_unnamed_symbol3$$libserver.dylib
0x8931f623 <+1347>: nopw %cs:(%rax,%rax)
from dotaservice.
It's also very much possible the 2nd argument is actually a pointer to an already created [empty] Actions protobuf...
I thought that too, but when I tried dumping it to string I would get a crash.
from dotaservice.
Still working on making sense of the code.
I believe Line #153 is call to Observe()
I believe Line #158 is call to Act()
from dotaservice.
from dotaservice.
Regarding the first IDA image I posted (2 images above)
I believe Line #153 is call to Observe()
I believe Line #158 is call to Act()
from dotaservice.
By the way... it looks like the intention is for us to be able to just call functions to take actions directly inside the Act(), and not use any protobuf. It just happens that in the Observe call the 2nd arg points the internal CMsgBot CLASS to the right offset so we sit at the WorldState implementation, but the class itself is full of virtual functions and other information.
When they pass the same data to Act() its probably for purposes of orientation but the intent might be to directly invoke using function pointers the appropriate actions using the provided class.
from dotaservice.
The code is something like this:
iteratePlayers(a1, *(double *)v17.m128_u64, *(double *)time_delta.m128i_i64);
sub_F5ABE0(a1);
sub_F5B1D0(a1);
considerGlyph(a1);
controlCourier(a1);
calculateLaneFronts(a1);
updatePotentialLocationGrid(a1);
updateAvoidanceGrid(a1);
if ( a1->gap354[725] > 0 )
{
v18 = 0;
do
{
v19 = *(_QWORD *)&a1->gap354[727];
v20 = 48LL * v18;
v17.m128_f32[0] = sub_6908D0(v19 + v20 + 24);
if ( v17.m128_f32[0] >= *(float *)(v19 + v20 + 36) )
{
v22 = a1->gap354[725];
if ( a1->gap354[725] - v18 - 1 > 0 )
{
memmove(
(void *)(*(_QWORD *)&a1->gap354[727] + v20),
(const void *)(*(_QWORD *)&a1->gap354[727] + 48LL * (v18 + 1)),
48LL * (a1->gap354[725] - v18 - 1));
v22 = a1->gap354[725];
}
v21 = v22 - 1;
a1->gap354[725] = v21;
--v18;
}
else
{
v21 = a1->gap354[725];
}
++v18;
}
while ( v18 < v21 );
}
if ( a1->gap354[731] > 0 )
{
v23 = 0;
do
{
v24 = *(_QWORD *)&a1->gap354[733];
v17 = (__m128)*(unsigned int *)(v24 + 8LL * v23 + 4);
v25 = *(float *)(v24 + 8LL * v23 + 4);
v17.m128_f32[0] = sub_A94280();
if ( v17.m128_f32[0] <= v25 )
{
v27 = a1->gap354[731];
}
else
{
v26 = a1->gap354[731];
if ( a1->gap354[731] - v23 - 1 > 0 )
{
memmove(
(void *)(*(_QWORD *)&a1->gap354[733] + 8LL * v23),
(const void *)(*(_QWORD *)&a1->gap354[733] + 8LL * (v23 + 1)),
8LL * (a1->gap354[731] - v23 - 1));
v26 = a1->gap354[731];
}
v27 = v26 - 1;
a1->gap354[731] = v27;
--v23;
}
++v23;
}
while ( v23 < v27 );
}
setRuneInfo(a1, (__m128i)v17);
callDynamicallyLoadedLibrary(a1, v28, (__m128)time_delta);
execLuaBotThink(a1, "TeamThink", *(_QWORD *)&a1->gap354[975], 0LL, 0LL);
updateLanePushDesires(a1);
updateLaneDefendDesires(a1);
updateFarmLaneDesires(a1);
updateRoamDesires(a1, *(double *)v17.m128_u64, (__m128)time_delta, a5);
updateRoshanDesire(a1, v17, (__m128)time_delta, a5);
updateItemsDesire(a1);
v29 = a1;
sub_F690D0((struct_a1 *)((char *)a1 + 20), a1, *(double *)v17.m128_u64, *(double *)time_delta.m128i_i64);
dota_time = a1->gap354[959];
if ( *(float *)&dota_time >= 0.0 )
{
v31 = qword_299B380;
if ( *(_DWORD *)(qword_299B380 + 920) == 4 )
{
if ( *(float *)&dota_time == 0.0 )
{
v32 = *(float *)(qword_299B380 + 2876);
*(float *)&dota_time = v32 + RandomFloat(COERCE_DOUBLE(1084227584LL), COERCE_DOUBLE(1097859072LL));
a1->gap354[959] = dota_time;
v31 = qword_299B380;
}
if ( *(float *)(v31 + 2876) >= *(float *)&dota_time )
{
v29 = (struct_a1 *)"dota_chatwheel_message_GLHF";
sub_F6B1E0(a1, "dota_chatwheel_message_GLHF", "", 0LL, 0LL);
a1->gap354[959] = 3212836864;
}
}
}
Our DLL sits inside the callDynamicallyLoadedLibrary Function
from dotaservice.
from dotaservice.
Inside the callDynamicallyLoadedLibrary functions is a stub that eventually does:
{
baseFuncPtr = *(_QWORD *)&a1->CMsgBot[1077];
Observe = *(void (__fastcall **)(__int64 *, int *))(baseFuncPtr + 0x18);
if ( Observe )
{
libraryTeamID = (__int64 *)*(unsigned int *)baseFuncPtr;
v21 = &a1->CMsgBot[751];
Observe(libraryTeamID, &a1->CMsgBot[751]);
baseFuncPtr = *(_QWORD *)&a1->CMsgBot[1077];
}
Act = *(__int64 (__fastcall **)(__int64 *, int *))(baseFuncPtr + 0x20);
if ( Act )
{
libraryTeamID = (__int64 *)*(unsigned int *)baseFuncPtr;
LODWORD(baseFuncPtr) = Act(libraryTeamID, v21);
}
}
from dotaservice.
That would mean you need headers? And that wouldnt make much sense since its a dlopen..
You don't need headers, you just extern anything you want to call that exists somewhere else; and honestly, in reality most of those functions would be access via function pointers available inside the main CMsgBot class that's passed to us (we just don't know what offsets points to what yet).
from dotaservice.
from dotaservice.
Related Issues (20)
- Dotaservice deadlocks itself HOT 1
- Time sync of radiant/dire teams upon reset not stable. HOT 10
- botcpp_dire.so and stuck at the map loading screen HOT 7
- how to remove the fog of war? HOT 8
- lane creep not spawn HOT 7
- AI vs Human/Buildin-AI play mode
- how to cast skill? HOT 20
- can not get the enemy lane creep info in world state HOT 3
- DebugDrawLine doesn't draw the correct line HOT 3
- Capture end-of-game signal HOT 2
- what the usage of actionDelay? HOT 3
- the head length of world state message is not correct HOT 5
- Dota2 Docker Error HOT 2
- Add DotaService Proto for Hero Selection HOT 3
- dota2 docker running problem HOT 9
- Minimal Working Example of client.py HOT 18
- Render in Macbook pro HOT 6
- How can i know a unit is visible to a team? HOT 2
- Docker: pull access denied for dota HOT 1
- where does the proto files come from? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dotaservice.