Jump to content
Returning Members: Password Reset Required ×

Server: Comet, Open Source


Spirited

Recommended Posts

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.

XH1oq6u.jpg

Link to comment
Share on other sites

  • Replies 70
  • Created
  • Last Reply

Top Posters In This Topic

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. 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 Started

To get started with Comet, clone the project and follow the guide in the readme.

Example.jpg

Just to add a note here, the item composition system is added on 5066. 5065 still use the old one.

Link to comment
Share on other sites

  • 3 weeks later...

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.

Link to comment
Share on other sites

... 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".

Link to comment
Share on other sites

... 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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

1000000 - 1999999999 to spawn a player properly

Did 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.

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 |

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

writer.Write(this.CharacterName); // 53

For some reason does. Have to check how that happens

Sadly 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 |

Link to comment
Share on other sites

writer.Write(this.CharacterName); // 53

For some reason does. Have to check how that happens

Sadly 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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...