rhaziel Posted September 28, 2011 Report Posted September 28, 2011 Hi guys, Now im kind of new to C++ (or atleast such extensive enterprises as Mangos). I've done some programming in the days and i do know C++ and Delphi (T Pascal) and some ASM. What i want is to find a simple almost the first ever made mangos core (or any other emu with a simple structure). I want to have the source - so that i can dissasmeble it and break to pieces. Once i do that i will put it all back together with some of my personal modifications. And then i will write it from scratch. And once im done - i should be able to contribute atleast in some extent. Please direct me to some good source so that i can start learning.
shlainn Posted September 28, 2011 Report Posted September 28, 2011 Hi rhaziel, while MaNGOS looks big and scary, it actually all boils down to a couple of files. I suggest you start at understanding WHAT MaNGOS is trying to emulate - in order of appearance: Realm Login (https://github.com/mangos/mangos/blob/master/src/realmd/AuthSocket.cpp) World Login (https://github.com/mangos/mangos/blob/master/src/game/WorldSocket.cpp) Packet Handling (https://github.com/mangos/mangos/blob/master/src/game/Opcodes.cpp) Object system (https://github.com/mangos/mangos/blob/master/src/game/Object.h) Map/Grid system (https://github.com/mangos/mangos/blob/master/src/game/GridMap.cpp) While this list is probably very incomplete, it should be enough to jumpstart your MaNGOS adventure. In parallel, it may help you to look at PseuWoW (http://mangosclient.org)(yes, shameless self-promo), which attempts to emulate the client part. If you have any specific questions, you should ask them in the appropriate boards, and they may be answered... at some point
TheLuda Posted September 29, 2011 Report Posted September 29, 2011 And in case it's not been obvious enough: PseuWow really is worth a look to understand both sides of the deal, e.g. shlainn's repository on github would be a suitable starting point, too.
rhaziel Posted September 29, 2011 Report Posted September 29, 2011 I've actually seem PseuWoW before i even started this thread. tho the web page seemed kinda abandoned. Nonetheless i will dive into this for sure - not sure if server or client side but for sure will contribute. But btw guys, can u tell me - what exactly is the point of pseuwow since the official client works just fine?
faramir118 Posted September 29, 2011 Report Posted September 29, 2011 what exactly is the point of pseuwowmangos since the official clientserver works just fine? I'm just here to learn!
shlainn Posted September 30, 2011 Report Posted September 30, 2011 And there are still idealistic people around who believe that the ultimate purpose of MaNGOS still is learning how to create a full-blown MMORPG. Any such endeavor would at some point require a client... like Pseuwow (funny how the clone count on my repo has gone up recently )
ensiferum Posted October 6, 2011 Report Posted October 6, 2011 Hello can someone please tell me if i can download a precompiled pseuWOW on windows? I dont have Cpp on my computer and i cannot compile it.. please help..
shlainn Posted October 7, 2011 Report Posted October 7, 2011 @ensiferum: this is off topic - go over to the proper forums. @rhaziel: Try a specific question. For general ideas on the structure on the system check my post above. Let me walk you through how I would go about figuring out how this system works. This may or may not work for you. 1) Compile MaNGOS 2) Compile PseuWoW 3) Configure PseuWoW for the maximum debug output possible Specifically this means in PseuWoW.conf: debug=3 // Output every single piece of debug crap ever deposited in the source showopcodes=3 // Show every single opcode that goes over the wire hidefrequentopcodes=0 // REALLY every single opcode HideDisabledOpcodes=0 // ... showmyopcodes=1 // Also show what I am sending to the server enablegui=0 // GUI adds unnecessary complexity, so no need for that 4) Now start up PseuWow and see what happens... OMG! It's full of crap!!! ...No, seriously: 2011-10-07 11:00:19 +----------------------------------+ 2011-10-07 11:00:19 | © 2006-2010 Snowstorm Software | 2011-10-07 11:00:19 | http://www.mangosclient.org | 2011-10-07 11:00:19 +----------------------------------+ 2011-10-07 11:00:19 Platform: Unix 2011-10-07 11:00:19 Compiler: GCC (40502) 2011-10-07 11:00:19 Compiled: Sep 22 2011 16:39:00 2011-10-07 11:00:19 2011-10-07 11:00:19 --- Initializing Instance --- 2011-10-07 11:00:19 *** DefScript StartUp [A13.51]... 2011-10-07 11:00:19 *** Loading 14 script files. 2011-10-07 11:00:19 * Loading script file [./scripts/__core_chat.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_chatAI.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_eventstubs.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_func.def] 2011-10-07 11:00:19 * Loading core scripts... 2011-10-07 11:00:19 * Loading script file [./scripts/__core_funstuff.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_hookHelper.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_internal.def] 2011-10-07 11:00:19 * Loading core scripts (internal config)... 2011-10-07 11:00:19 ** Configuring PseuWoW... 2011-10-07 11:00:19 * Loading 1 conf files. 2011-10-07 11:00:19 * Loading conf file [ PseuWoW.conf ] 2011-10-07 11:00:19 MemoryDataHolder: Single-threaded mode. 2011-10-07 11:00:19 * Configuration applied. 2011-10-07 11:00:19 * Cleaning up variables... 2011-10-07 11:00:19 * Dangerous variables removed. 2011-10-07 11:00:19 * Assigning permissions for internal functions... 2011-10-07 11:00:19 ** All Config done. 2011-10-07 11:00:19 * Loading script file [./scripts/__core_list_extensions.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_misc.def] 2011-10-07 11:00:19 * Loading script file [./scripts/__core_wrappers.def] 2011-10-07 11:00:19 * Loading script file [./scripts/autobroadcast.def] 2011-10-07 11:00:19 ** AutoBroadcast: skipped loading. 2011-10-07 11:00:19 * Loading script file [./scripts/database_loader.def] 2011-10-07 11:00:19 * Loading script file [./scripts/help.def] 2011-10-07 11:00:19 * Loading script file [./scripts/uptime.def] 2011-10-07 11:00:19 *** All files loaded without errors. 2011-10-07 11:00:19 *** StartUp complete! 2011-10-07 11:00:19 ** Loading / dyncompiling databases... 2011-10-07 11:00:19 Loading database 'race' 2011-10-07 11:00:19 File './data/scp/race.scp' matching database 'race', loading 2011-10-07 11:00:19 21 sections loaded 2011-10-07 11:00:19 Compacting database 'race' into file './cache/race.ccp' 2011-10-07 11:00:19 Database 'race' loaded from source and compacted with compression 6 --snip-- 2011-10-07 11:00:19 Loading database 'emote' 2011-10-07 11:00:19 SCP: No files found that contain database [emote] --snip-- 2011-10-07 11:00:19 ** Databases loaded. 2011-10-07 11:00:19 RemoteController: listening on port 8101 2011-10-07 11:00:19 Starting CLI... 2011-10-07 11:00:19 Init complete. 2011-10-07 11:00:19 PseuInstance: Initialized and running! 2011-10-07 11:00:19 GUI not active or Login data pre-entered, skipping Login GUI 2011-10-07 11:00:19 RealmSocket connected! 2011-10-07 11:00:19 Packet Sent 2011-10-07 11:00:19 RealmSocket::OnRead() 119 bytes 2011-10-07 11:00:19 RealmSocket: Got AUTH_LOGON_CHALLENGE [119 of 118 bytes] 2011-10-07 11:00:19 Login successful, now calculating proof packet... 2011-10-07 11:00:19 == Server Bignums == 2011-10-07 11:00:19 --> B=2CEC5E45B34CB20CABC099088CCF3D6B315F12DCBE070CC2F563D5447884D917 2011-10-07 11:00:19 --> g=07 2011-10-07 11:00:19 --> N=894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7 2011-10-07 11:00:19 --> salt=B1CDCBFEE4C62F33D47D3A41DEE66E1667D487764058304BF1A70BB6C3557361 2011-10-07 11:00:19 --> unk=96C6A6BE2A589806B0B0070D852BBAC7 2011-10-07 11:00:19 == My Bignums == 2011-10-07 11:00:19 --> a=A4722A2E0E9F1B9764E615034870B981569409 2011-10-07 11:00:19 --> x=36A15107ECF19C70E49EF4E5B42D36C7E3990B47 2011-10-07 11:00:19 --> v=77F37E45F8A88CDE9943038D4AE6C3292F407ED62D9B3DCC93E701E56E4D5228 2011-10-07 11:00:19 --> A=7BADE689AA63658C8DA684A78660BF1C62114269930D4141B9B30F75EDE466BB 2011-10-07 11:00:19 --> u=DBC0E8AE033ACA9A9066E583DC160CB741A39737 2011-10-07 11:00:19 --> S=1F9CC8F4E9F82C234427CAD5FBA670BB3F13E45369A9785278F248A7ED4A6A4D 2011-10-07 11:00:19 --> SessionKey=B950BE26E5472829B32D9BFCDD442A3C4D7D70A4DA6290E5C4F2ACC78D823BFB39F3B5E21342083A 2011-10-07 11:00:19 == Common Hashes == 2011-10-07 11:00:19 --> M1=9BB22EF3A2E65D59F59A69AC526A0DE5D6EE0EE4 2011-10-07 11:00:19 --> M2=B128DC34B9061495325AECA7059D269386B4D46F 2011-10-07 11:00:19 --> CRC=0000000000000000000000000000000000000000 2011-10-07 11:00:19 Data left on RealmSocket, Hexdump: 2011-10-07 11:00:19 00 -- CUT -- An average PseuWoW login produces about 400 lines of logfile. Obviously in the beginning you have some startup messages which say that some script files are loaded, some config is read, some databases are loaded, etc. If you would like to know specifics on how this is done, do a search over all files using some of the log output. For example if you would like to know how the databases are loaded, run "Loading databases" in your search, and you will find out that databases are loaded somewhere in src/Client/DefScriptInterface.cpp. Then it says "Init complete. PseuInstance: Initialized and running" - The fun starts. PseuWoW connects to the server... I have to admit, that the realm socket code does not produce very nice output. But still. Every single line of log output can be found in the source, so you can follow the code execution. I will go through the next 5 lines: 11:00:19 RealmSocket connected! This line is logged in src/Client/Realm/RealmSocket.cpp RealmSocket::OnConnect(). When does this function get called? After some more searching we find out that RealmSocket is derived from TcpSocket (see src/Client/Realm/RealmSocket.h) and TcpSocket calls OnConnect() when a connection is made (see src/shared/Network/TcpSocket.cpp). Nice one! 11:00:19 Packet Sent This line comes from src/Client/Realm/RealmSession.cpp RealmSession::SendLogonChallenge() which gets called from src/Client/PseuWoW.cpp PseuInstance::ConnectToRealm() which is called from PseuInstance::Update() which in turn gets called from PseuInstance::Run(). As you will also find out, Run() contains the main program loop. So after reading through some or all of these functions, you will see that SendLogonChallenge() puts together a data packet containing all kinds of logon data (I believe some of that is a bit hacky, now that I look at it...) (Client Version, account name, etc) and sends it off to the server. This is the first contact. So what does the server do with it? (At this point you should take a look at server startup logs using the same strategy as before) The server (in this case realmd) gets this AUTH_LOGON_CHALLENGE packet. Searching mangos source for that string reveals that src/realmd/AuthSocket.cpp handles it in AuthSocket::_HandleLogonChallenge. Reading through the code (and ignoring or looking up bits you don't understand right away) you will see that realmd checks if the packet is okay, if the account exists, is not banned, suspended, or any other bad thing and if it is not, it calculates some lovely bignumbers which are then used as logon challenge to the client. By following the pkt object throughout the function you can see the structure and order of data in the packet, just as before in PseuWoW. In the end, the packet is sent back to the client, which then says: 11:00:19 RealmSocket::OnRead() 119 bytes By now you will not have any difficulties to find out that this is called from src/Client/Realm/RealmSocket.cpp RealmSocket::OnRead(). It receives all data on the socket, and adds it to a packet queue for processing. 11:00:19 RealmSocket: Got AUTH_LOGON_CHALLENGE [119 of 118 bytes] This message is reported from src/Client/Realm/RealmSession.cpp RealmSession::_HandleLogonChallenge(). How the hell did we get from the packet queue to this function? Let's see. RealmSession::_GetAuthHandlerTable() has a mention of _HandleLogonChallenge() in a table of some sorts. _GetAuthHandlerTable() gets called from RealmSession::Update() and returns a pointer to the table. A bit into the Update() function (which presumably gets called from the main loop, I leave it to you to verify this) you will find that a for loop goes through the table and checks if the Opcode of the packet matches the one in the table. If it does, a magic called "function pointers" is used to call the associated handler function, which we already know is _HandleLogonChallenge(). 11:00:19 Login successful, now calculating proof packet... This line is also from _HandleLogonChallenge(), a bit further down. As you will have found out at this point, PseuWoW has checked if there were any errors, and found none. So now it will extract the data from the packet, calculate login proof data and send it off again, while outputting copious amounts of debug information. I hope this starts your learning process. What you will see all the time it this ping-pong game between the server and the client throwing packets at each other in response to something happening on either side (movement, attacks, cooldowns, etc) and replying to those packets. I am not sure what you mean by "pinning this thing down", but I am very certain that only a handful of people on this planet have a complete in-depth understanding of every bit of code in the MaNGOS repository. It is also not necessary to understand the underlying network code to fix something in the spell handling (just as an example). So I would recommend you not to get lost in implementation details before you have the big picture. And by "big picture" I refer to the three classic things every program needs to do: main() { Initialize(); while(running) DoStuff(); CleanUp(); } Hope it helps, apologies for the rather lengthy post... Shlainn
rhaziel Posted October 7, 2011 Report Posted October 7, 2011 Excelent! This is what i need - will go through it in detail once i get home. More lenghty posts are more than welcome!
Recommended Posts