xFranko Posted November 26, 2025 Posted November 26, 2025 (edited) I’ve set everything up correctly and I'm using the 5615 client from Spirited’s post. I compiled CSV3Hook and updated csv3config.ini with the correct IPs and ports. My GameServer is running on port 5816, and the AuthServer on 5817. I can get past the auth server when logging in, but the connection fails when reaching the game server with the following message: Client disconnected: Unknown (Reason: DhExchange() - connection aborted) I tried debugging but haven’t had any success. The client is sending 0 bytes, which is causing the failure, but I can’t figure out why. I’m also using the launcher included with the source. Do I need to use the exact same client version as the source (5619)? I can’t even locate that version anywhere. Edited December 28, 2025 by xFranko Quote
kennylovecode Posted November 27, 2025 Posted November 27, 2025 This prompt is already very obvious. Try setting a breakpoint on the socket connection accept connection and debug the DHKeyExchange with the client. Only after successfully exchanging keys with the client can your socket receive the correct content Quote
xFranko Posted November 27, 2025 Author Posted November 27, 2025 @kennylovecode I tried but I'm starting to give up, I thought it would be an issue from my client itself as to why it's sending 0 bytes? also can't tell why the exchance fails, I tried to debug but it feels like I can't get any valuable info, also tried print debugging...I feel like the issue could be with my character initilization? === CONNECTION DEBUG: GameConnect START === New client connected from: 26.25.24.42:56606 Socket connected: True, Alive: True GameClient created, GameId: 1 DH Feedback object created: True Invoking handshake handler... === DH EXCHANGE DEBUG: InitHandshake START === Client: 26.25.24.42:56606 DH DEBUG: Generated public key length: 128 DH DEBUG: Public key (first 32 bytes): 44 43 46 39 34 34 37 41 34 34 37 36 42 46 38 38 36 37 38 38 39 44 41 36 44 38 31 46 45 35 39 36 DH DEBUG: Handshake packet size: 333 bytes DH DEBUG: Handshake packet (first 64 bytes): Offset 0000: 26 00 1A 27 45 1B 06 00 00 00 00 42 01 00 00 0A Offset 0010: 00 00 00 00 86 00 00 00 32 00 32 00 00 08 00 00 Offset 0020: 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 Offset 0030: 00 00 00 00 00 80 00 00 00 45 37 41 36 39 45 42 DH DEBUG: Sending handshake via DirectSend (unencrypted)... DH DEBUG: DirectSend completed === DH EXCHANGE DEBUG: InitHandshake END === Handshake handler completed Before BeginReceive - Socket connected: True, Available: 0 bytes BeginReceive started, waiting for client reply... === CONNECTION DEBUG: GameConnect END === === DH EXCHANGE DEBUG: DhExchange callback START === Client: 26.25.24.42:56606 Socket connected: True, Available: 0 bytes DH DEBUG: EndReceive returned size: 0 bytes DH DEBUG: ERROR - Received 0 bytes, connection aborted DH DEBUG: Client closed connection gracefully (0 bytes) Quote
Tkblackbelt Posted November 27, 2025 Posted November 27, 2025 (edited) Based on your log it appears the client connected, and you successfully sent back some data related to the dh exchange? I see that the last log says client closed connection. Did it automatically disconnect after your server sent that packet? If so, then it seems likely that the client didn’t like your servers response and killed the connection. You mentioned using different source and client versions, that could possibly be it if there was any changed made to the protocol. To rule that out spirits client page has a link to download patches. Maybe try patching your client up to the exact version of the source your using. If that doesn’t work, you will likely need to do some more debugging. Edited November 27, 2025 by Tkblackbelt Quote
xFranko Posted November 27, 2025 Author Posted November 27, 2025 @TkblackbeltYep the client disconnects right after the login server sends that 333 bytes packet, and I tried to find a patch from 5615 to 5619 but couldn't find any..I don't think during these 4 patches any major change happened that would cause the issue I'm having right now..so it must be something else.. Quote
kennylovecode Posted November 27, 2025 Posted November 27, 2025 18 minutes ago, xFranko said: @TkblackbeltYep the client disconnects right after the login server sends that 333 bytes packet, and I tried to find a patch from 5615 to 5619 but couldn't find any..I don't think during these 4 patches any major change happened that would cause the issue I'm having right now..so it must be something else.. When setting up a private service for the first time, it is best to ensure that your client is the official original client. This way, you don't have to encounter DHKey exchange failures due to client issues. If you are using someone else's client, please solve the problem I mentioned first, and there is a high probability that you will be able to resolve it. For example, if you use the 5619 client, you don't necessarily need 5619. You can use any version between 5600-5930, and the difference between them won't be significant Quote
Konichu Posted November 27, 2025 Posted November 27, 2025 5619 already have that md5 hash on the DH Key exchange, doesn't it? Like this public byte[] ProcessDHSecret() { using MD5 md5 = MD5.Create(); byte[] key = PrivateKey.ToByteArrayUnsigned(); string sz1 = md5.ComputeHash(key, 0, key.TakeWhile(x => x != 0).Count()).ToHexString(); string sz2 = md5.ComputeHash(Encoding.ASCII.GetBytes(string.Concat(sz1, sz1))).ToHexString(); return Encoding.ASCII.GetBytes(string.Concat(sz1, sz2)); } Quote
xFranko Posted November 27, 2025 Author Posted November 27, 2025 26 minutes ago, Konichu said: 5619 already have that md5 hash on the DH Key exchange, doesn't it? Like this public byte[] ProcessDHSecret() { using MD5 md5 = MD5.Create(); byte[] key = PrivateKey.ToByteArrayUnsigned(); string sz1 = md5.ComputeHash(key, 0, key.TakeWhile(x => x != 0).Count()).ToHexString(); string sz2 = md5.ComputeHash(Encoding.ASCII.GetBytes(string.Concat(sz1, sz1))).ToHexString(); return Encoding.ASCII.GetBytes(string.Concat(sz1, sz2)); } @Konichu Hmm not really looks a bit different, here's the entire DHExchange file from the GameServer using System; using System.Text; using CO2_CORE_DLL.Security.Cryptography; namespace ConquerServerV3 { // // Special thanks unknownone/Sparkie, CptSky // public class DHExchange { private const string PStr = "E7A69EBDF105F2A6BBDEAD7E798F76A209AD73FB466431E2E7352ED262F8C558F10BEFEA977DE9E21DCEE9B04D245F300ECCBBA03E72630556D011023F9E857F"; private const string GStr = "05"; public static readonly byte[] P = Encoding.ASCII.GetBytes(PStr); public static readonly byte[] G = Encoding.ASCII.GetBytes(GStr); private static string Hex(byte[] bytes) { char[] c = new char[bytes.Length * 2]; byte b; for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx) { b = ((byte)(bytes[bx] >> 4)); c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); b = ((byte)(bytes[bx] & 0x0F)); c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); } return new string(c); } private static string PostProcessDHKey(byte[] key) { var hashService = new System.Security.Cryptography.MD5CryptoServiceProvider(); var s1 = Hex(hashService.ComputeHash(key, 0, key .CountWhile(x => x != 0) ) ); var s2 = Hex(hashService.ComputeHash(Encoding.ASCII.GetBytes(String.Concat(s1, s1)))); var sresult = String.Concat(s1, s2); return sresult; } public static DiffieHellman New() { return new DiffieHellman(PStr, GStr); } [PacketAttribute(PacketType.HandShake)] private static void InitHandshake(GameClient user, Packet msg) { byte[] publicKey = Encoding.ASCII.GetBytes(user.Feedback.GenerateRequest()); user.Send(msg.Handshake(P, G, publicKey)); } [PacketAttribute(PacketType.HandshakeReply)] private static void CompleteHandshake(GameClient user, Packet msg) { string otherPublicKey; if (msg.GetHandshakeReplyKey(out otherPublicKey)) { user.Feedback.HandleResponse(otherPublicKey); var compute = PostProcessDHKey(user.Feedback.ToBytes()); user.Network.Language.SetKey(Encoding.ASCII.GetBytes(compute)); user.Feedback = null; // allow resources to be freed } } } } Quote
Konichu Posted November 28, 2025 Posted November 28, 2025 I noticed that you sent the DH Key exchange request and received 0 bytes, which means that the client disconnected. Is your Cast5 Default Seed correct? Quote
kennylovecode Posted November 28, 2025 Posted November 28, 2025 I can almost be sure that if you can find a matching client, there won't be any problems. Quote
xFranko Posted November 28, 2025 Author Posted November 28, 2025 (edited) 8 hours ago, kennylovecode said: I can almost be sure that if you can find a matching client, there won't be any problems. @kennylovecode I got my v5615 client from Spirited's post, so it is clean, I patched it up to 5619 also from his links..and this didn't fix the issue. Also got the database from the comments in e*pvpers, someone left it under the thread since it wasn't originally uploaded with the source. https://www.assembla.com/spaces/conquerserverv3/documents/aL-N--KmGr4Pg0acwqEsg8/download/aL-N--KmGr4Pg0acwqEsg8 8 hours ago, Konichu said: I noticed that you sent the DH Key exchange request and received 0 bytes, which means that the client disconnected. Is your Cast5 Default Seed correct? @Konichu From what I got from the code, The Cast5 default seed (initialization vector/IV) is all zeros. In ConquerServerShared\Cryptography\TQCast5.cs, the Reset() method initializes the IVs like this: public void Reset() { EncIvec = new byte[16]; DecIvec = new byte[16]; DecNum = new int[8]; EncNum = new int[8]; } Full file: namespace ConquerServerV3.Cryptography { public unsafe class TQCast5 { private byte[] EncIvec; private byte[] DecIvec; private int[] EncNum; private int[] DecNum; private TQCast5Impl Impl; public TQCast5() { Impl = new TQCast5Impl(); Reset(); } public void GenerateKey(byte[] kb) { var key = new byte[16]; for (int i = 0; i < 16; i++) key[i] = kb[i]; Impl.SetKey(key); } public void Reset() { EncIvec = new byte[16]; DecIvec = new byte[16]; DecNum = new int[8]; EncNum = new int[8]; } public void Encrypt(byte* buffer_in, int in_off, byte[] buffer_out, int out_off, int length) { byte c; for (int l = length, n = EncNum[0], inc = in_off, outc = 0; l > 0; l--) { if (n == 0) { Impl.EncryptBlock(EncIvec, 0, EncIvec, 0); } c = (byte)((buffer_in[inc++] ^ EncIvec[n]) & 0xff); buffer_out[outc++] = c; EncIvec[n] = c; n = (n + 1) & 0x07; EncNum[0] = n; } } public void Decrypt(byte[] buffer_in, int in_off, byte* buffer_out, int out_off, int length) { byte c, cc; for (int l = length, n = DecNum[0], inc = in_off, outc = 0; l > 0; l--) { if (n == 0) { Impl.EncryptBlock(DecIvec, 0, DecIvec, 0); } cc = buffer_in[inc++]; c = DecIvec[n]; DecIvec[n] = cc; buffer_out[out_off + outc] = (byte)((c ^ cc) & 0xff); outc++; n = (n + 1) & 0x07; DecNum[0] = n; } } } } If it matters, the default encryption key used in GameCipher.cs is: "C238xs65pjy7HU9Q" ____________________________ Also I really just want any source that's before patch 5622 (Chi release), me and my friends just hate Chi and all that stuff that came after, we wanted to play with the Pirate and that's all and this seemed to be the only source around this patch Edited November 28, 2025 by xFranko Quote
xFranko Posted November 28, 2025 Author Posted November 28, 2025 Looking at the client I noticed it's producing some debug logs..which seems to indicate it's indeed the handshake.. ERROR: CGameSocket::ReceiveMsg() OnShakeHand failed at f:\cq2clientrelease-50.0.5\3drole\network\socket.h, 528 -- Fri Nov 28 10:54:45 2025 Also not sure where this path comes from 'f:\cq2clientrelease-50.0.5\3drole\' I don't have that on my PC.. Quote
Konichu Posted November 28, 2025 Posted November 28, 2025 3 hours ago, xFranko said: Looking at the client I noticed it's producing some debug logs..which seems to indicate it's indeed the handshake.. ERROR: CGameSocket::ReceiveMsg() OnShakeHand failed at f:\cq2clientrelease-50.0.5\3drole\network\socket.h, 528 -- Fri Nov 28 10:54:45 2025 Also not sure where this path comes from 'f:\cq2clientrelease-50.0.5\3drole\' I don't have that on my PC.. It's a compile time constant that they use on logs so you know where the exception has been thrown etc. It's the path and line from the original source code. "__FILE__, __LINE__" Your handshake request is breaking, it could be because of P on DH but it's the same as mine and TQ uses it until today. Maybe it could be the Cast5 seed, it's the same as mine as well and I'm running 6609. Your source is originally built for 5619? Or did you adapt anything? Quote
xFranko Posted November 28, 2025 Author Posted November 28, 2025 (edited) 47 minutes ago, Konichu said: It's a compile time constant that they use on logs so you know where the exception has been thrown etc. It's the path and line from the original source code. "__FILE__, __LINE__" Your handshake request is breaking, it could be because of P on DH but it's the same as mine and TQ uses it until today. Maybe it could be the Cast5 seed, it's the same as mine as well and I'm running 6609. Your source is originally built for 5619? Or did you adapt anything? @Konichu The source is originally built for 5619 yes as per what Spirited wrote, it's the Conquer Server V3 source mentioned in this post: Also another memeber seems to have had such issue here: but well he wasn't using the Launcher provided with the source..I do use the launcher so not sure what's wrong Also there was this member having similar issue with the same debug error line in their client, but he is using another source and version.. Idk how to approach this further tbh Edited November 28, 2025 by xFranko Quote
Konichu Posted November 28, 2025 Posted November 28, 2025 8 hours ago, xFranko said: @Konichu The source is originally built for 5619 yes as per what Spirited wrote, it's the Conquer Server V3 source mentioned in this post: Also another memeber seems to have had such issue here: but well he wasn't using the Launcher provided with the source..I do use the launcher so not sure what's wrong Also there was this member having similar issue with the same debug error line in their client, but he is using another source and version.. Idk how to approach this further tbh Let me see your handshake packet structure Quote
xFranko Posted November 30, 2025 Author Posted November 30, 2025 On 11/28/2025 at 11:52 PM, Konichu said: Let me see your handshake packet structure @Konichucould you guide me a little how to find that ? Quote
kennylovecode Posted December 1, 2025 Posted December 1, 2025 23 hours ago, xFranko said: @Konichucould you guide me a little how to find that ? using System; using System.IO; namespace ConquerServer_v2.Client { public static class DHKeyExchange { public class ServerKeyExchange { OpenSSL.DH _keyExchange; byte[] _serverIv; byte[] _clientIv; public byte[] CreateServerKeyPacket() { _clientIv = new byte[8]; _serverIv = new byte[8]; string P = "E7A69EBDF105F2A6BBDEAD7E798F76A209AD73FB466431E2E7352ED262F8C558F10BEFEA977DE9E21DCEE9B04D245F300ECCBBA03E72630556D011023F9E857F"; string G = "05"; _keyExchange = new OpenSSL.DH(OpenSSL.BigNumber.FromHexString(P), OpenSSL.BigNumber.FromHexString(G)); _keyExchange.GenerateKeys(); return GeneratePacket(_serverIv, _clientIv, P, G, _keyExchange.PublicKey.ToHexString()); } public GameCryptography HandleClientKeyPacket(string PublicKey, GameCryptography cryptographer) { byte[] key = _keyExchange.ComputeKey(OpenSSL.BigNumber.FromHexString(PublicKey)); cryptographer.SetKey(key); cryptographer.SetIvs(_clientIv, _serverIv); return cryptographer; } public byte[] GeneratePacket(byte[] ServerIV1, byte[] ServerIV2, string P, string G, string ServerPublicKey) { Random Random = new Random(); int PAD_LEN = 11; int _junk_len = 12; string tqs = "TQServer"; MemoryStream ms = new MemoryStream(); byte[] pad = new byte[PAD_LEN]; Random.NextBytes(pad); byte[] junk = new byte[_junk_len]; Random.NextBytes(junk); int size = 47 + P.Length + G.Length + ServerPublicKey.Length + 12 + 8 + 8; BinaryWriter bw = new BinaryWriter(ms); bw.Write(pad); bw.Write(size - PAD_LEN); bw.Write((UInt32)_junk_len); bw.Write(junk); bw.Write((UInt32)ServerIV2.Length); bw.Write(ServerIV2); bw.Write((UInt32)ServerIV1.Length); bw.Write(ServerIV1); bw.Write((UInt32)P.ToCharArray().Length); foreach (char fP in P.ToCharArray()) { bw.BaseStream.WriteByte((byte)fP); } bw.Write((UInt32)G.ToCharArray().Length); foreach (char fG in G.ToCharArray()) { bw.BaseStream.WriteByte((byte)fG); } bw.Write((UInt32)ServerPublicKey.ToCharArray().Length); foreach (char SPK in ServerPublicKey.ToCharArray()) { bw.BaseStream.WriteByte((byte)SPK); } foreach (char tq in tqs.ToCharArray()) { bw.BaseStream.WriteByte((byte)tq); } byte[] Packet = new byte[ms.Length]; Packet = ms.ToArray(); ms.Close(); return Packet; } } } } you are using this code , right? Quote
kennylovecode Posted December 1, 2025 Posted December 1, 2025 23 hours ago, xFranko said: @Konichucould you guide me a little how to find that ? May I ask if GameServer crashes when you disconnect from the client? Quote
xFranko Posted December 1, 2025 Author Posted December 1, 2025 @kennylovecode Hmm, the entire DHExchange file I shared it in previous reply here Also your code mentions v2 I am using v3 Quote May I ask if GameServer crashes when you disconnect from the client? Nope it doesn't crash..only the client disconnects...the client entirely crashes in case I set the IPs to 127.0.0.1 (which is expected I believe) Quote
kennylovecode Posted December 1, 2025 Posted December 1, 2025 1 hour ago, xFranko said: @kennylovecode Hmm, the entire DHExchange file I shared it in previous reply here Also your code mentions v2 I am using v3 Nope it doesn't crash..only the client disconnects...the client entirely crashes in case I set the IPs to 127.0.0.1 (which is expected I believe) where the v3 download from, i try to slove the problem Quote
xFranko Posted December 1, 2025 Author Posted December 1, 2025 (edited) 7 minutes ago, kennylovecode said: where the v3 download from, i try to slove the problem @kennylovecode Thank you! It's from Spirited's post here https://mega.nz/file/4RYh1QqB#wFWD65PgEatq05GD2pjld_7w-D7fO8t1wHznkqhvNNQ Also got the database from the comments in e*pvpers, someone left it under the thread since it wasn't originally uploaded with the source. https://www.assembla.com/spaces/conquerserverv3/documents/aL-N--KmGr4Pg0acwqEsg8/download/aL-N--KmGr4Pg0acwqEsg8 Edited December 1, 2025 by xFranko Quote
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.