Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Welcome to our site

Take a moment to join our board

Leaderboard


Popular Content

Showing content with the highest reputation since 05/27/2019 in all areas

  1. 2 points
    It's been about 5 years since I've done anything Conquer related. Had the itch to dink around with it again. Excited to try your source and especially exited that it's on git and vscode. Thanks spritied. Former epvper myself.
  2. 2 points
    Introduction Conquer Online's older clients do not support higher resolution by default so in this guide I will be explaining how to edit the client's resolution to support higher resolutions, There will be no coding an I will try to explain the assembly instructions as I go, I will be using a 5095 client for this guide but the process should remain the same. Note that this is simply a guide to how it can be accomplished and I recommended doing through coding a dll instead of directly editing the executable to be able to configure it to any resolution without the need of multiple executables. All the numbers shown in the pictures are in hexadecimal (base16). Finding Window Resolution By doing a simple search in the client's executable (Conquer.exe) for the constant values 1024 or 768, we find two occurrences which are being stored in a global variable. In the first image we have the value of ecx register being set to 2 and being compared to the value of eax , if they aren't equal it jumps to the other image where the value is being compared against 3 by doing some backtracking we realize that the value of ScreenMode in GameSetUp.ini is being checked with 2 in the first and the 3 in the second image which represent 1024x768 window and full screen modes respectively, now by simply editing those values (400h and 300h) we can change the window resolution to any value we want which will only take effect if the client is in 1024x768 resolution mode, I.e. only if the ScreenMode value is set to 2 or 3. Having accomplished that we are faced with a few problems one being the client doesn't render the map edges properly if the resolution exceeds a certain value, to fix this we look for another two constants, which after doing some research and debugging ourselves we notice that aren't 1024 or 768 so by trying to identify/link any values to the ScreenMode value we find that there is no such value meaning that there is no actual correlation between the ScreenMode and the rendering resolution so by then trying the other default resolution to the client 800x600 we find the following. In that instruction block we find that there is some calculation being made and loop being executed just after that, by changing those values to our desired resolution values we fix the rendering problem , our next problem to fix is the alignment of the UI elements. Changing UI Alignment Since we aren't doing any coding, we will have to change the positions in the GUI.ini but we quickly find that some UI elements do not use the GUI.ini values but rather are hard-coded one of which is the player's heath/action bar/panel,(Skip this part if you don't want to center the player's panel) to find it we use the value we find to be the actual size or position of the panel by doing some searching in the GUI.ini and using the mouse position at the topmost pixel of the panel and the bottommost pixel and subtracting we find that the panel height is 141 ,we obtained the height specifically because we realize that the panel is being correctly positioned on the Y-Axis regardless of the resolution which means that the client uses it's height to determine the y value (being Screen Height - Panel Height) and after looking for that value we find the following. we see at the bottom a call to the function CWnd::MoveWindow which takes x,y,width,height and a repaint Boolean as parameters now depending on the function's calling convention the parameters are pushed to the stack in a specific order, since this is a _thiscall function we push the parameters in reverse order repaint>height>width>y>x which storing the class instance in ECX (being CWnd in this case), and so by looking at the instructions we see a call to GetWindowRect which we will ignore as the return value isn't being used then we see a 1 being pushed to the stack which represent a true value as the repaint parameter and then a 8Dh(141) which represent the height and so on. and as we look down we see a call to GetScreenHeight after which 141 is subtracted from the return value stored in EAX(being height) and later on pushing EAX to the stack as the Y parameter, we also see 0 being pushed as the x parameter which we need to change to center the panel but we notice that there is only a space enough for signed byte which can only take up to 0x7f or (127) as a positive number to fix this we will have to rewrite/change the instructions to push a constant Y value and skip the calculation. ("db 0" represent an empty byte) As seen above, we can edit the to push the y value directly so we have enough space to push a bigger x value as well. Other elements like the help window button follow similar principles but it's redrawn in a block of code than the original drawing so you will need to patch it twice and the arrow's quiver is a bit trickier but can be done (hint:It's being drawn constantly in a loop, and has several parts that are drawn a few bytes away from each other). IDA is used to disassemble the executable.
  3. 1 point
    Hey everyone, I have made a few posts already but I figured I would give an introduction as well. I'm currently in school for Computer Science, and going to hopefully continue until I get my masters in Data Analytics. I'm older than most college students as I chose to serve in the military before going. I've played Conquer for a long time, the earliest that I can remember is that CP's didn't exist, and top + was 8 I believe. I primarily use Go, although I have used C# but mostly just using the Unity library. I'm currently working on a Go 5017 source, but the scope for this is a lot smaller than Spirited's Chimera project. So that's pretty much it, hope to see you all around!
  4. 1 point
    Hey, W1cked! Welcome to the forum. I'm glad to see that there's still some interested members of the development community.
  5. 1 point
    Wao.... Another one.... PS. Welcome
  6. 1 point
    I am an overly confident programmer who makes simple binary mistakes, and refuses to acknowledge that it could have possibly been me who messed up. This has caused me a great deal of time wasted. I was using the wrong method of the binary littlendian package.
  7. 1 point
    I had help from @Spirited to figure this stuff out and port it to Go. I know a lot of people in the emulator communities don't use Go, but I hope with more packages released it will lift the barrier for people to use it. It's pretty straight forward, use the NewRC5 method instead of a struct literal. Encrypt by calling Encrypt and supplying a dst byte slice the same size as the src slice. For Decrypting, do the same thing. This adheres to the Cipher.Block interface, so for your client/conn structs you can just use that interface type. package rc5 import ( "encoding/binary" "math/bits" ) const ( WordSize = 16 Rounds = 12 KeySize = WordSize / 4 SubSize = 2 * (Rounds + 1) ) type RC5 struct { Key []uint32 Sub []uint32 } func NewRC5() RC5 { c := RC5{} c.Key = make([]uint32, KeySize) c.Sub = make([]uint32, SubSize) //Conquer default key c.generateKeys([]byte{ 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E, 0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE, }) return c } func (r *RC5) generateKeys(buf []byte) { //Initialize key expansion //seedLength := len(buf) / WordSize * WordSize for i := 0; i < KeySize; i++ { r.Key[i] = binary.LittleEndian.Uint32(buf[i*4:]) } //Generate r.Sub r.Sub[0] = 0xB7E15163 for i := 1; i < SubSize; i++ { r.Sub[i] = r.Sub[i-1] - 0x61C88647 } //Generate key vector var a, b uint32 var i, j int for x := 0; x < 3*SubSize; x++ { r.Sub[i] = bits.RotateLeft32(r.Sub[i]+(a+b), 3) a = r.Sub[i] r.Key[j] = bits.RotateLeft32(r.Key[j]+(a+b), int(a+b)) b = r.Key[j] i = (i + 1) % SubSize j = (j + 1) % KeySize } } func (r *RC5) Encrypt(dst, src []byte) { length := len(src) / 8 if (len(src) % 8) > 0 { length = length + 1 } copy(dst, src) for word := 0; word < length; word++ { a := binary.LittleEndian.Uint32(dst[8*word:]) + r.Sub[0] b := binary.LittleEndian.Uint32(dst[(8*word + 4):]) + r.Sub[1] for round := 1; round <= Rounds; round++ { a = bits.RotateLeft32(a^b, int(b)) + r.Sub[2*round] b = bits.RotateLeft32(b^a, int(a)) + r.Sub[2*round+1] } binary.LittleEndian.PutUint32(dst[8*word:], a) binary.LittleEndian.PutUint32(dst[8*word+4:], b) } } func (r *RC5) Decrypt(dst, src []byte) { length := len(src) / 8 if (len(src) % 8) > 0 { length = length + 1 } copy(dst, src) for word := 0; word < length; word++ { a := binary.LittleEndian.Uint32(dst[8*word:]) b := binary.LittleEndian.Uint32(dst[(8*word)+4:]) for round := Rounds; round > 0; round-- { b = bits.RotateLeft32(b-r.Sub[2*round+1], -int(a)) ^ a a = bits.RotateLeft32(a-r.Sub[2*round], -int(b)) ^ b } binary.LittleEndian.PutUint32(dst[8*word:], a-r.Sub[0]) binary.LittleEndian.PutUint32(dst[8*word+4:], b-r.Sub[1]) } } func BlockSize() int { return 8 }
  8. 1 point
    You are correct. I don't think I reference that function, but feel free to log a bug against it and I'll fix it once I return home (I'll be out for another few days). Thanks!
  9. 1 point
    Welcome to the community, very cool. Another Go programmer! Whoo-hoo! Please don't look at my older Go code, it's really embarrassing. 😅 Hope you stick around with us. Would be cool to see more from you. I see a lot of really bright engineers come from the military, so I'm sure you'll do well. Word of advice though, Data Analytics is a very narrow field of study. If you take the general approach or take more classes that specialize in algorithms, machine learning, and data extraction, then you'll be right on track. Good luck with your studies.
  10. 1 point
    COServer.Security.Cryptography is a library exposing the TQ Digitial's legacy cipher that is used by Conquer Online 2.0 servers (pre-5018). It is developed in C++, with an translation layer in C++/CLI (to make it callable from C#). The library will automatically select the best implementation based on the CPU on which it is running. The source code is released under the BSD 2-clause license and is available here: GitHub tqcipher_1.0.0_msvc2013.zip
  11. 1 point
    This application will allow you to encrypt or decrypt most .dat files. I've attached both the original version I wrote in C# (with a C++ library for the cipher), and the second version I rewrote in pure C#. The source code of the C# version is released under the GPLv3 and is available here: GitHub Here's some keys: LevExp: 4D2 Silent: 2537 MapDestination: 2537 ItemType: 2537 Monster: 2537 UserHelpInfo: 2537 FileManager-Windows-x86-1.0.0.zip FileManager-Windows-x86-2.0.0.zip
  12. 1 point
    This application will allow you to edit the GameMap.dat file, which indicate the relation between a map ID and the DMap file. I've attached both the original version I wrote in C#, and the second version I rewrote in C++ using Qt much later. The source code of the C++ version is released under the GPLv3 and is available here: GitHub MapEditor-OSX-Universal-2.0.0.dmg MapEditor-Windows-x86_64-2.0.0.zip MapEditor-Windows-x86-2.0.0.zip MapEditor-Windows-x86-1.0.0.zip
  13. 1 point
    Introduction This is a simple command-line tool for editing portals in dmaps. It outputs a list of portals from a dmap in the format index,x,y, and allows you to write them back to the dmap in the same format. It can be compiled for Windows, Linux, or Mac using the Golang compiler, and I have attached the Windows build of the tool. I wrote the tool in about an hour, so it's a bit messy, but all open source and MIT licensed for whoever wants to do something with it. Figured that I'd write it on the third request. Links https://spirited.io/project/portals/
  14. 1 point
    I have been working on an API which I will be using for: I got the base working and wanted to share it. The API is made in .NET Core 2.1 using Pomelo Entity Framework and FluentValidation The project can be found on my Github: https://github.com/Sedatb23/EpochApi
×

Important Information

By using this site, you agree to our Terms of Use.