Spirited Posted November 22, 2020 Share Posted November 22, 2020 This is a skeleton server project for those interested in game server design / network programming Introduction I started working on Comet as a three-week coding challenge, but later developed a base out of it. Comet is a two-server project, containing an account server and game server connected over RPC. The account server authenticates players, while the game server services players in the game world. This simple two-server architecture acts as a good introduction into server programming and networking, but may be a bit too advanced for beginners (no features are implemented). The server is interoperable with a few patches... Supported Patches The following patches are supported (the list below describes the patch, not features provided by the server). 4274: One of the last stable patches for Conquer 1.0 with the legacy brown wood interface. 4294: One of the first stable patches for Conquer 2.0 with the blue fabric and stone interface. 4343: Adds potency and new currency, but does not include the pay-to-win shopping mall. 5017: Adds pay-to-win shopping mall, +12 items, WuXing Oven, new fonts, and more. 5065: Adds new watercolor client, new hairstyles, new equipment, and more. 5187: Adds talismans, ninjas, enlightenment, quiz show, mounts, clans, arena, and more. Notable Features This base project includes the following helpful features: Written in .NET 6, so can run on Windows, Linux, or MacOS. Asynchronous server socket system using SocketTaskExtensions. Asynchronous RPC system between Account and Game servers. Asynchronous database access layer using Entity Framework 6. Parallel packet processing using channels and background services. Supports running servers in Docker containers. Supports multiple game versions / patches. Implements character creation and login into Birth Village. Getting Started To get started with Comet, clone the project and follow the guide in the readme. Quote Link to comment Share on other sites More sharing options...
Konichu Posted November 24, 2020 Share Posted November 24, 2020 IntroductionI started working on Comet as a three-week coding challenge, but later developed a base out of it. Comet is a two-server project, containing an account server and game server connected over RPC. The account server authenticates players, while the game server services players in the game world. This simple two-server architecture acts as a good introduction into server programming and networking. The server is interoperable with a few patches...Supported Patches 4274: One of the last stable patches for Conquer 1.0 with the legacy brown wood interface. 4294: One of the first stable patches for Conquer 2.0 with the blue fabric and stone interface. 4343: Adds potency and new currency, but does not include the pay-to-win shopping mall. 5017: Adds pay-to-win shopping mall, +12 items, WuXing Oven, new fonts, and more. 5065: Adds new watercolor client, hairstyles, equipment, item composition, and more. 5187: Adds talismans, ninjas, enlightenment, quiz show, mounts, clans, arena, and more.Getting StartedTo get started with Comet, clone the project and follow the guide in the readme.Just to add a note here, the item composition system is added on 5066. 5065 still use the old one. Quote Link to comment Share on other sites More sharing options...
Spirited Posted November 24, 2020 Author Share Posted November 24, 2020 Thanks, fixed. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 11, 2020 Share Posted December 11, 2020 Hello there. I have one question. How do I access all connected Clients. Do I have to create new List with logged users and manage it that way? And is there a "right way" to do it. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 11, 2020 Author Share Posted December 11, 2020 Hello there. I have one question. How do I access all connected Clients. Do I have to create new List with logged users and manage it that way? And is there a "right way" to do it.Hey, thanks for asking. That's a good small feature I should add to the project. It's necessary for validating that the same account doesn't log in twice from two separate clients. To do it yourself, I recommend adding a ConcurrentDictionary to Kernel where the other state caches are. You would probably key on the account id, and add the client when processing MsgConnect. Just remember to remove it from the dictionary on Disconnect as well (just like I do for character Registrations). I'll see to adding that this weekend, and let me know if you have any other questions. Thanks. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 11, 2020 Share Posted December 11, 2020 ... I recommend adding a ConcurrentDictionary to Kernel where the other state caches are. You would probably key on the account id, and add the client when processing MsgConnect. Just remember to remove it from the dictionary on Disconnect as well (just like I do for character Registrations). I'll see to adding that this weekend, and let me know if you have any other questions. Thanks.heh ... this made me so happy. That was how I did it, but didn't know about ConcurrentDictionary. Async tasks and C# are still ... new thing for me. Thanks a bunch for replaying. I feel bad for asking questions.Btw: Your "How to start".. does not mention how important is to name your server (in client ) with same name as in source. But that might be issue only for "newbies". Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 11, 2020 Author Share Posted December 11, 2020 ... I recommend adding a ConcurrentDictionary to Kernel where the other state caches are. You would probably key on the account id, and add the client when processing MsgConnect. Just remember to remove it from the dictionary on Disconnect as well (just like I do for character Registrations). I'll see to adding that this weekend, and let me know if you have any other questions. Thanks.heh ... this made me so happy. That was how I did it, but didn't know about ConcurrentDictionary. Async tasks and C# are still ... new thing for me. Thanks a bunch for replaying. I feel bad for asking questions.Btw: Your "How to start".. does not mention how important is to name your server (in client ) with same name as in source. But that might be issue only for "newbies".Thanks for the feedback, I'll see to adding that as well. And don't feel bad about asking questions. That's what this thread is for, and async-await is new for me as well. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 12, 2020 Author Share Posted December 12, 2020 Made a few fixes and updates:- Add client pool and duplicated login check.- Add details regarding realm name for server setup guide.- Reclaim buffer and release socket semaphore on exchange failure. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 12, 2020 Share Posted December 12, 2020 As I'm working with 4274. Does it have some packet structure as 4267? Then I could use CoFuture 4267 as references for packet structure.I'm having issue to send MsgPlayer packet to players. Wiki does not hold info for older versions of packets. Any pointer to right direction were to look would be appreciated. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 12, 2020 Author Share Posted December 12, 2020 As I'm working with 4274. Does it have some packet structure as 4267? Then I could use CoFuture 4267 as references for packet structure.I'm having issue to send MsgPlayer packet to players. Wiki does not hold info for older versions of packets. Any pointer to right direction were to look would be appreciated.I don't think there's a difference between the versions in terms of packet structures. The wiki relies on developers to contribute, so if it's not there, it just means nobody's developing on that patch and contributing at the same time. Quote Link to comment Share on other sites More sharing options...
Doc Posted December 15, 2020 Share Posted December 15, 2020 Just wanted to pop in and say this looks great! I'll be sure to try it out soon. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 15, 2020 Author Share Posted December 15, 2020 Just wanted to pop in and say this looks great! I'll be sure to try it out soon.Thanks, let me know if there's anything I can help with. Just to tamper expectations, this is a base source - so nothing's programmed besides the login for multiple patches. It's very much a DIY server project, not a partially completed project like some others. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 16, 2020 Share Posted December 16, 2020 Can I ask direct question about why what I'm trying to do - does not work? It should make copy of me right with dif id? https://pastebin.com/NZMi51SP. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 16, 2020 Author Share Posted December 16, 2020 Can I ask direct question about why what I'm trying to do - does not work? It should make copy of me right with dif id? https://pastebin.com/NZMi51SP.Character IDs are special. They need to be in the range 1000000 - 1999999999 to spawn a player properly. Other than that, it's a bit hard to help without knowing the patch you're working with. Can you give me a bit more info, like the patch number, anything you're seeing in the client, how you're calling this, how you're debugging the server, etc. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 16, 2020 Share Posted December 16, 2020 1000000 - 1999999999 to spawn a player properlyDid not know that. Thanks.Path is 4274. And I see or get nothing. No wierdness or anything. Console output and breakpoints.I call this purely by testing purposes case ActionType.MapJump: await client.SendAsync(new MsgPlayer(client.Character)); break; I did same for MsgMapItem and MsgNpcInfo and worked just fine. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 17, 2020 Author Share Posted December 17, 2020 From a quick glance, I couldn't find anything notably wrong besides some of the offsets in the comments (comments were wrong though, not the actual offsets). You could try using a different character name. I'm not sure how the client handles duplicate character names on screen. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 17, 2020 Share Posted December 17, 2020 Name thing did not change a thing. Yea... comments could be wrong since I'm struggling with issue for days now and have done things - like packet length checks, copy/paste Packetbuilders/ packet structures from other sources. Its just like I'm missing something obvious. Found this old link ( from you know what forum ). Dude had same issue, but hes answer / resolve did not click with me. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 17, 2020 Author Share Posted December 17, 2020 Name thing did not change a thing. Yea... comments could be wrong since I'm struggling with issue for days now and have done things - like packet length checks, copy/paste Packetbuilders/ packet structures from other sources. Its just like I'm missing something obvious. Found this old link ( from you know what forum ). Dude had same issue, but hes answer / resolve did not click with me.Hm. Could you post a packet dump of the completed message just before encrypting and sending? Aka. calling this function after this line of code. Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 18, 2020 Share Posted December 18, 2020 Hm. Could you post a packet dump of the completed message just before encrypting and sending? Aka. calling this function after this line of code.0000: 3B 00 F6 03 F5 32 F9 41 AB BA 06 00 00 00 00 00 | ;....2.A........ |0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |0020: 00 00 00 00 00 00 00 00 3E 01 01 00 3D 00 6D 00 | ........>...=.m. |0030: 67 02 01 64 01 04 04 72 6F 6F 37 | g..d...roo7 | Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 18, 2020 Author Share Posted December 18, 2020 Hm. Could you post a packet dump of the completed message just before encrypting and sending? Aka. calling this function after this line of code.0000: 3B 00 F6 03 F5 32 F9 41 AB BA 06 00 00 00 00 00 | ;....2.A........ |0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |0020: 00 00 00 00 00 00 00 00 3E 01 01 00 3D 00 6D 00 | ........>...=.m. |0030: 67 02 01 64 01 04 04 72 6F 6F 37 | g..d...roo7 |Hm. Maybe I'm wrong, but it looks like it's writing the length of your name twice? Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 19, 2020 Share Posted December 19, 2020 writer.Write(this.CharacterName); // 53For some reason does. Have to check how that happensSadly bypassing that issue does not fix spawn ether. 0000: 3A 00 F6 03 15 58 0F 00 AB BA 06 00 00 00 00 00 | :....X.......... | 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ | 0020: 00 00 00 00 00 00 00 00 31 03 00 00 3D 00 6D 00 | ........1...=.m. | 0030: 67 02 01 64 01 04 72 6F 6F 39 | g..d..roo9 | Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 21, 2020 Author Share Posted December 21, 2020 writer.Write(this.CharacterName); // 53For some reason does. Have to check how that happensSadly bypassing that issue does not fix spawn ether. 0000: 3A 00 F6 03 15 58 0F 00 AB BA 06 00 00 00 00 00 | :....X.......... | 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ | 0020: 00 00 00 00 00 00 00 00 31 03 00 00 3D 00 6D 00 | ........1...=.m. | 0030: 67 02 01 64 01 04 72 6F 6F 39 | g..d..roo9 | If it's not appearing at all, then that leads me to believe the coordinates are wrong or at the wrong offset. Are your character's coordinates supposed to be the birth village spawn coordinates? Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 21, 2020 Share Posted December 21, 2020 If it's not appearing at all, then that leads me to believe the coordinates are wrong or at the wrong offset. Are your character's coordinates supposed to be the birth village spawn coordinates?Im passing Clients ( the one Im playing) coords to that packet - birth village. They do match and are set. As for offsets.. have tested most publicly available. P.S I haven't actually changed anything in code. Just added nonworking MsgPlayer.cs file. Quote Link to comment Share on other sites More sharing options...
Spirited Posted December 21, 2020 Author Share Posted December 21, 2020 Im passing Clients ( the one Im playing) coords to that packet - birth village. They do match and are set. As for offsets.. have tested most publicly available. P.S I haven't actually changed anything in code. Just added nonworking MsgPlayer.cs file.Just to confirm, you're not using the same character ID as the character already on screen, right? Have you tried using a different name as well? Quote Link to comment Share on other sites More sharing options...
roo7 Posted December 22, 2020 Share Posted December 22, 2020 Just to confirm, you're not using the same character ID as the character already on screen, right? Have you tried using a different name as well?I have tried different names / UID / Mesh ... about every value that I could change in all kinds of combinations. Have tried spawn monster. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.