This thread is basically for posting your code snippets that you have developed for client/server modification.
LINKS
Asm function - geons
Spoiler:
by mar
Example of using:Code:push ebp mov ebp,esp mov ecx,[ebp+08] mov edx,[ecx+448] test edx,edx jz FINISH1 mov eax,[edx+34] jmp FINISH2 FINISH1: xor eax,eax FINISH2: mov esp,ebp pop ebp ret
Code:push userId (beginning of player's memory) call FUNCTION add esp,04 cmp eax,.................. check if player have at least X geons......
Asm function - time
by mar
Spoiler:
Function returns in EAX current day of week(0=sunday...6=saturday)
Example of using:Code:push ebp mov ebp,esp sub esp,08h push 00h call 0049f7c2 add esp,04h mov [ebp-08h],eax lea eax,[ebp-08h] push eax call 0049f7fb add esp,04h mov [ebp-04],eax mov edx,[ebp-04h] mov eax,[edx+18h] mov esp,ebp pop ebp ret
Code:CALL FUNCTION cmp eax,00 ....check day of week and do something / or not ....
A bunch of code snippets for client side hackshield
by Justei
Spoiler:
So, this code is compiled and works fine in Visual C++ 6.0.
I used a proxy dll to run it and well, if you don't know how to do that then I recommend staying away from modding the client anyway lol.
First snippet, most requested so far. How to change icon of kal window after injection:
How to check for autobattleCode:hwndWindow = FindWindow(NULL, "KalOnline"); SetWindowText(hwndWindow, "KalOnline - KalmaX 2006 [Protected by Elmo] - Coded by: Justei. Extra credits: MaX"); if(ServerSelected == 0 && IconLoop < 500){ HANDLE hIcon = LoadImage(NULL, "data/sesame/icon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE); if(hIcon){ SendMessage(hwndWindow, WM_SETICON, ICON_BIG, (LPARAM)hIcon); }else{ // Insert a logging function or whatever here... } HANDLE hIconSm = LoadImage(NULL, "data/sesame/icon.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); if(hIconSm){ SendMessage(hwndWindow, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); }else{ // Insert a logging function or whatever here... } IconLoop++; }
(not sure this works 100%, but the function is good to have in general to fetch info from .ini files).
Check if a file exists, so u can check if ppl put .dll files in the same folder:Code:char curdir[4096]; char inifile[4096]; GetCurrentDirectory(4000, curdir); sprintf(inifile, "%s\\system.ini", curdir); // check for autobattle, sigh... char autobattle[256]; GetPrivateProfileString("CLIENTVERSION", "AUTO_BATTLE", "null", autobattle, 4000, inifile); if(strcmp(autobattle, "2") == 0){ // KickPlayer. }
Code:bool FileExist(string FileName) { struct stat stFileInfo; bool blnReturn; int intStat; intStat = stat(FileName.c_str(),&stFileInfo); if(intStat == 0) { blnReturn = true; } else { blnReturn = false; } return(blnReturn); }
Check what windows are open:
Code:char WinText[200] = {NULL}; if(!hwnd || !IsWindowVisible(hwnd)) return 1; GetWindowTextA(hwnd,WinText,sizeof(WinText)); // Example of how to use. if(strcmp(WinText, "Let's Engine 3.0 by Be_Sk8 - www.LetsPlayCheats.navega.uni.cc") == 0){ // KickPlayer(); just kick player... }
FPS Limiter for client
by Kealy
Spoiler:
In the first place, this is an add-on for C++ projects, and NOT a complete project on its own.
If you want to use it, you will have to create a proxy dll project yourself.
Now about the rights, if you use my code, I DEMAND credits.
Besides, since this is the very first and only fps limiter, I will know whenever someone uses it or not.
Beware.
About the code :
The code is commented. Not everything, but enough to get the idea, I hope.
I redirect the 2 calls to that WorldRefreshing function to mine, and hold the whole loop inside it.
This allows me to easily add/modify/remove anything, at any time.
To install the FPS Limiter, you have to call CTweaks::HookWorldRefresh().
And this HAS to be done before engine.exe code is executed. (In theory it's possible to to do before the 3d environment is loaded, but it's quite risky.)
Here it goes.
PHP Code:/* Tweaks.h */
#include <iostream>
#include <Windows.h>
using namespace std;
class CTweaks
{
public:
CTweaks(); // Constructor
void HookWorldRefresh(); // World refreshing function hooker
private:
// This function has to be static, otherwise it wouldn't be possible to get a pointer to it.
static WPARAM __thiscall WorldRefresh(void*); // Engine World refreshing thread
typedef int (__cdecl *WREngineFunc)(void); // Unknown WorldRefresh function's prototype
typedef int (__thiscall *RefreshEntities)(void*); // Entity worldrefreshing function's prototype
DWORD WREngineFuncPtr; // Pointer to unknown worldrefreshing function
DWORD RefreshEntitiesPtr; // Pointer to entity worldrefreshing function
BYTE *WREngineActive; // Pointer to possible 'this' instance
int MaxFPS; // Maximum frames per second
int MaxTime; // Maximum milliseconds accepted to engage frame blocker
DWORD SleepTime; // Time to block the frame each round
};
extern CTweaks *Tweaks;
PHP Code:/* Tweaks.cpp */
#include "Tweaks.h"
// Only one single instance of this class is needed
// So there is no need to worry about where nor how we initialize it.
CTweaks *Tweaks = new CTweaks;
CTweaks::CTweaks()
{
// Engine addresses pointers
this->WREngineFuncPtr = 0x004a73b0;
this->RefreshEntitiesPtr = 0x00425960;
this->WREngineActive = (BYTE*)0x006ddf58;
}
void CTweaks::HookWorldRefresh()
{
this->MaxFPS = 30;
// Right here it is possible to load the max fps from a configuration file, or what so ever.
// Example : this->MaxFPS = Config->Engine.FPSLimit;
// Two calls to our WorldRefresh function, only one of them is used, but the second one is just in case.
this->MaxTime = (1000/this->MaxFPS);
Core->Intercept(INST_CALL,0x00505869,(DWORD)this->WorldRefresh,5);
Core->Intercept(INST_CALL,0x00505bfc,(DWORD)this->WorldRefresh,5);
#ifndef SILENT_MODE
cout << "FPS Limiter installed." << endl;
#endif
}
WPARAM __thiscall CTweaks::WorldRefresh(void *thisPointer)
{
// Since this function is running as a thread, InixSoft had to declare it as static (just as done here)
// Therefore, since the 'this' instance can only be used with non-static member functions,
// The calling convention is not __thiscall anymore but __fastcall, and the 'this' pointer is passed as argument.
// EDIT: After some tests, I figured __thiscall is sometimes required, so try it like this.
// If it doesn't work out, change it back to __fastcall
// Default function vars
void *that;
char state;
struct tagMSG Msg;
HACCEL hAccel;
// Our variables
// We will be using high resolution timers
// <3 precision
int PerformanceTime;
unsigned __int64 lpFrequency;
unsigned __int64 lpPerformanceCount;
unsigned __int64 lpPerformanceStep;
// This > That. Ok ?
that = thisPointer;
// Checking for the CPU's frequency, unit is in Herz.
QueryPerformanceFrequency((LARGE_INTEGER*)&lpFrequency);
hAccel = LoadAcceleratorsA(NULL, (LPCSTR)0x71);
Msg.message = 0;
PeekMessageA(&Msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE);
while (Msg.message != 0x12)
{
// EXTREMELY important!!
// Since we call functions that weren't compiled with the same compiler (type, version, et cetera) as we use
// There are high chances that those functions modify, either the stack or the registers in a way OUR compiler would never expect.
// Such corruption is especially noticeable in loops, causing crashes in most cases.
// This is why it is critical to save the stack before and after those functions are executed.
__asm pushad
if (*((BYTE*)that+0x9d)) state = (!!PeekMessageA(&Msg, NULL, WM_NULL, WM_NULL, PM_REMOVE));
else state = (!!GetMessageA(&Msg, NULL, 0, 0));
if (state)
{
if ((!hAccel) || (!(*(DWORD*)that+0x38)) || (!TranslateAcceleratorA(*((HWND*)that+0x38), hAccel, &Msg)))
{
TranslateMessage(&Msg);
DispatchMessageA(&Msg);
}
// Not quite sure about what this function really does
// I know it's executed when the mouse is moved.
((WREngineFunc)Tweaks->WREngineFuncPtr)();
}
else
{
if ((*((BYTE*)that+0x9d)) && (*(BYTE*)Tweaks->WREngineActive))
{
// Querying the performance count before and after world refreshing function
QueryPerformanceCounter((LARGE_INTEGER*)&lpPerformanceCount);
// This function refreshes the whole kal world, including object movements in time, daytime, et cetera, well, pretty much everything.
// Could also be called rendering function.
int tmpActive = ((RefreshEntities)Tweaks->RefreshEntitiesPtr)(that);
QueryPerformanceCounter((LARGE_INTEGER*)&lpPerformanceStep);
if (tmpActive < 0) SendMessageA(*((HWND*)that+0x38), WM_COMMAND, 0x9C46, 0);
// From here on, we will calculate the difference between the two counters
// And base the time we'll need to block the frames from being displayed for on that amount.
PerformanceTime = (int)(lpFrequency / (lpPerformanceStep-lpPerformanceCount));
if (PerformanceTime) PerformanceTime = 1000 / PerformanceTime;
if (Tweaks->MaxTime > PerformanceTime)
{
// This var could be used as local variable, but let's rather keep it global.
Tweaks->SleepTime = (Tweaks->MaxTime - PerformanceTime);
Sleep(Tweaks->SleepTime);
}
}
}
// Restoring the stack.
__asm popad
}
if (hAccel) DestroyAcceleratorTable(hAccel);
return Msg.wParam;
}
Seriously, this game doesn't need to run at any higher than 30fps.
Using this FPS limiter, I managed to drop the CPU usage by nearly 60%, whilst having the game still completely playable.
PS: If I ever find another tweak that could be useful here, I will update this thread only and ask a moderator to change its title.
Edit: Added namespace use and includes. Oh and I forgot to mention I compile every of my projects with VisualC++ 2010 Express SP1.
Edit2: Moved namespace and includes to the correct file and fixed a critical error in the code.
GB-Structure C++
by BakaBug
Spoiler:
It's everything you need to load a GB .. nothing more .. and about where is vertex data where is index data ... HUCH Oo you can load them directPHP Code:#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <vector>
using std::cout;
using std::cin;
using std::endl;
typedef
#pragma pack(1)
struct t_Vector3
{
DWORD x;
DWORD y;
DWORD z;
} Vector3;
typedef
#pragma pack(1)
struct t_gb_ver_08
{
BYTE Version;
BYTE BoneCount;
BYTE BoneIdentifier;
BYTE MaterialCount;
//DWORD CheckSum;
//char Name[64];
DWORD NameLength;
WORD TotalVertexCount[6];
WORD TotalIndexCount;
WORD TotalBoneCount;
WORD TotalKeyFrameCount;
WORD Unknown0;
WORD MaterialDescriptorLength;
WORD Unknown1;
WORD KeyFrameTransformationCount;
BYTE AnimationCount;
WORD MeshCount;
WORD Unknown2;
//Vector3 BoundingBoxMin;
//Vector3 BoundingBoxMax;
//Vector3 BoundingSphereCenter;
//float BoundingSphereRadius;
} GB_V08;
typedef
#pragma pack(1)
struct t_gb_ver_09
{
BYTE Version;
BYTE BoneCount;
BYTE BoneIdentifier;
BYTE MaterialCount;
//DWORD CheckSum;
//char Name[64];
DWORD NameLength;
WORD TotalVertexCount[12];
WORD TotalIndexCount;
WORD TotalBoneCount;
WORD TotalKeyFrameCount;
WORD ukwn0;
WORD MaterialDescriptorLength;
WORD ukwn3;
DWORD CollisionSize;
WORD KeyFrameTransformationCount;
BYTE AnimationCount;
BYTE ukwn1;
WORD MeshCount;
WORD Unknown2;
//Vector3 BoundingBoxMin;
//Vector3 BoundingBoxMax;
Vector3 BoundingSphereCenter;
float BoundingSphereRadius;
} GB_V09;
typedef
#pragma pack(1)
struct t_gb_ver_0a
{
BYTE Version;
BYTE BoneCount;
BYTE BoneIdentifier;
BYTE MaterialCount;
DWORD CheckSum;
//char Name[64];
DWORD NameLength;
WORD TotalVertexCount[12];
WORD TotalIndexCount;
WORD TotalBoneCount;
WORD TotalKeyFrameCount;
WORD ukwn0;
WORD MaterialDescriptorLength;
WORD ukwn3;
DWORD CollisionSize;
WORD KeyFrameTransformationCount;
BYTE AnimationCount;
BYTE ukwn1;
WORD MeshCount;
WORD Unknown2;
//Vector3 BoundingBoxMin;
//Vector3 BoundingBoxMax;
Vector3 BoundingSphereCenter;
float BoundingSphereRadius;
} GB_V10;
typedef
#pragma pack(1)
struct t_gb_ver_0B
{
BYTE Version;
BYTE BoneCount;
BYTE BoneIdentifier;
BYTE MaterialCount;
DWORD CheckSum;
//char Name[64];
DWORD NameLength;
WORD TotalVertexCount[12];
WORD TotalIndexCount;
WORD TotalBoneCount;
WORD TotalKeyFrameCount;
WORD ukwn0;
WORD MaterialDescriptorLength;
WORD ukwn3;
DWORD CollisionSize;
WORD KeyFrameTransformationCount;
BYTE AnimationCount;
BYTE ukwn1;
WORD MeshCount;
WORD Unknown2;
Vector3 BoundingBoxMin;
Vector3 BoundingBoxMax;
Vector3 BoundingSphereCenter;
float BoundingSphereRadius;
} GB_V11;
typedef
#pragma pack(1)
struct t_gb_ver_0c
{
BYTE Version;
BYTE BoneCount;
BYTE BoneIdentifier;
BYTE MaterialCount;
DWORD CheckSum;
char Name[64];
DWORD NameLength; //includes sizeof(CheckSum)
WORD TotalVertexCount[12];
WORD TotalIndexCount;
WORD TotalBoneCount;
WORD TotalKeyFrameCount;
WORD Unknown0;
WORD MaterialDescriptorLength;
WORD Unknown1;
DWORD CollisionSize;
WORD KeyFrameTransformationCount;
WORD AnimationCount;
WORD MeshCount;
WORD Unknown2;
Vector3 BoundingBoxMin;
Vector3 BoundingBoxMax;
Vector3 BoundingSphereCenter;
float BoundingSphereRadius;
} GB_V12;
typedef
#pragma pack(1)
struct t_gb_material_header
{
DWORD TextureFileNameOffset;
WORD Unknown0;
DWORD TextureFileNameLength;
WORD Unknown1;
WORD Unknown2;
DWORD MaterialOffset;
} GB_MATERIAL_HEADER;
// DWORD WORD DWORD DWORD DWORD
typedef
#pragma pack(1)
struct t_gb_mesh_header
{
DWORD NameOffset;
DWORD MaterialIndex;
BYTE VertexType;
BYTE PrimitiveType;
WORD VertexCount;
WORD IndexCount;
BYTE BoneCount;
} GB_MESH_HEADER;
typedef
struct
{
D3DCOLOR Ambient;//D3DCOLOR_ARGB
D3DCOLOR Diffuse;
D3DCOLOR Specular;
float Opacity; //1 = max
float Shine;
float ShineStrength;
float Transparency;
float Wiresize;
float SelfIllum;
} GB_MATERIAL;
as you see .. direct copy from memory into mesh-data..PHP Code:meshes[i].VertexSize = 32+((VertexType % 5) * 4);
...
...
/* For files with bones FVF = FVF | BONE */
switch (VertexType)
{
case 0:
printf("FVF_0\n"); //correct
meshes[i].FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
break;
case 1:
printf("FVF_1\n");
meshes[i].FVF = D3DFVF_XYZ | D3DFVF_SPECULAR| D3DFVF_NORMAL | D3DFVF_TEX1;
break;
case 2:
printf("FVF_2\n"); //correct
meshes[i].FVF = D3DFVF_XYZB1 | D3DFVF_SPECULAR | D3DFVF_NORMAL | D3DFVF_TEX1;
break;
case 3:
printf("FVF_3\n");
meshes[i].FVF = D3DFVF_XYZB2 | D3DFVF_SPECULAR | D3DFVF_NORMAL | D3DFVF_TEX1;
break;
case 4:
printf("FVF_4\n");
meshes[i].FVF = D3DFVF_XYZB3 | D3DFVF_SPECULAR | D3DFVF_NORMAL | D3DFVF_TEX1;
break;
default:
printf("unknown vertextype\n");
}
...
...
// Create + Initialize vertexbuffer //
D3DDevice->CreateVertexBuffer(
gbMeshHeader->VertexCount * meshes[i].VertexSize,
0, D3DFVF, D3DPOOL_MANAGED, &meshes[i].D3DVertexBuffer, 0);
LPVOID pVertices;
meshes[i].D3DVertexBuffer->Lock(0, gbMeshHeader->VertexCount * meshes[i].VertexSize, &pVertices, D3DLOCK_NOSYSLOCK);
CopyMemory(pVertices, seeker, gbMeshHeader->VertexCount * meshes[i].VertexSize);
meshes[i].D3DVertexBuffer->Unlock();
seeker += gbMeshHeader->VertexCount * meshes[i].VertexSize;
//***********************************
// Create + Initialize indexbuffer //
D3DDevice->CreateIndexBuffer(
gbMeshHeader->IndexCount * sizeof(WORD),
0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &meshes[i].D3DIndexBuffer, NULL);
LPVOID pIndices;
meshes[i].D3DIndexBuffer->Lock(0, gbMeshHeader->IndexCount * sizeof(WORD), &pIndices, D3DLOCK_NOSYSLOCK);
CopyMemory(pIndices, seeker, gbMeshHeader->IndexCount * sizeof(WORD));
meshes[i].D3DIndexBuffer->Unlock();
it's easy for everyone who knows the basics of GB..
and 3D programming ! and about material -.- peeh you should know that
the material-header saves the relative offsets from the footer
CryptKalOnline for C++
by BakaBug
Spoiler:
Original Post: BakaBug's Blog
Here is my first release of it ..
Full working ! for PacketSystem and for DAT
You can direct decrypt Dat-Files with it (newest INT Files)...
Encrypten ? Yes you would able..
But Encrypt Key != Decrypt Key
You would able to generate a Encrypt Key for the Decrypt Key..
I have a idea how-to .. but i didn't got time yet xD
I will re-release it when I have it ^^
INFO:
The variable UNKNOW[520] includes the AES-KEY's (when it's really AES)
For decrypting Packets , you need to change the key's !!!
It's looks like the key for packets are dynamic generated..
I am still looking for it ;)
EDIT:
Ohe yeah copyrights ?!
Use it how you want, do what ever you want
But when you don't give credits to me..
I only can say ... hello, big wannabe
Everything (by TamaGo), or something like that
by BakaBug
Spoiler:
PACKET STRUCKTUR
PACKET CRYPTING
Some easy Kal-Packet: (Yeah I can't help you how to write a Sniffer)
So Yeah the first we see is .. the first 2 bytes is the size (means a word ..)Code:0500161215 04001248 030047
So the rest everytime changes .. can only mean crypted.. so packet structure is
This is first step..Code:type TKalPacket = packed record size:word; data:array of char; end;
CRYPT TABLE
So .. after sniffing a lot at login (easyer to sniff) we will see something like
a login packet :) .. becosue it's the login packet you know what you have entered .. so
(I used some nummbers they aren't correct .. but it works this way
??= I am to boring to count the bytes)
(I entered acc:BakaBug pass:BakaBug)Code:????04 B0 A1 C0 A1 B0 F1 AA 12 B0 A1 C0 A1 B0 F1 AA 12 B a k a B u g \0 B a k a B u g \0
Why we know there it must be BakaBug ?
When you look good you will see ..
Kal Crypt every letter .. 1 time ! means a crypte "a" at position 1...
looks like a crypte "a" at position 3..
Now wtf is this ? .. after a lot of trying .. first we know It's not working like
XOR mean haven't something like a key.. So it muss be something static
Which says A->! B->A C->& ... so ABC would be crypted to !A&
Yeah WTF a easy crypt .. and easy to crack..
so how to get this crypt-table ?
DECRYPT PACKETS
BTW. this way only works with a decompressed engine.exe
My first thought was some where in engine.exe must be a table ..
So .. starting hex-editor .. opening engine.exe
Entered in Login
Sniff the Crypted oacket .. search this hex ... an WOOLLLLAAAACode:Username: abcdefgh Passwort: ijklmop
And the first thing is .. WTF ? the table is uncrypted saved..
InixSoft makes hacking really easy.. ;)
..
So how to get the full Crypt-Table from the engine.exe (or mainsvr.exe works there too)
SO starting a disambler (I am using IDA) .. let disamble engine.exe ..
when everythings is loaded I scroll in the hex window .. to the offset where I found the abcde.. (crypted) click ... go to disambler window .. and WOLLLAAA
there is a area .. from START to END of the full CRYPT-Table ;)
So we copy this Area .. into our hexeditor and save it as CRYPT.dat (or how you want)
So how to laod this table ?.. We know each letter is crypted with a other key!
so 256 letters .. our file is .. 200*256 bytes big ( I am to boring to multiplizier it .. I already know there are 200 keys) so how many keys are here ?
Yeah FileSize / 256 ;)
How to load ? (in delphi)
Btw this is the encrypt ( i think ) for decrypt you need to genereat your own file.. mean when you know "A->!" you will know "!->A" easy to write -.-Code:type TCryptRow = packed record Byte: array[0..255] of char; end; var CryptTable: array[0..199] of TCryptRow; .. .. fil.read(CryptTable,sizeof(CryptTable)); //finish ;)
ADDITIONAL CRYPT AT INT SERVER
Yeah we updating the source of out Sniffer (yeah write your own or you wont able to do this way)
We adding our CryptTable..
So what we know ?
- Kal is using Nullterminated strings
- the row of the crypt changes everytime (we know this after a lot of testing)
..Special the point Nullterminated strings *grins*
We are adding to the sniffer that he try's all rows to decrypt the last Byte
when it's decrypted \0 key found ..
So this way only works on chat packet ;) becouse there they use string..
So we chat a lot ingame .. and look at our log..
KEY: 12
KEY: 13
KEY: 14
KEY: 15
KEY: 16
KEY: 17
..
WTF yeah the row(key) increase every packet ;)
..
KEY: 60
KEY: 61
KEY: 62
KEY: 63
KEY: 0
So ahhhh after 63 (or was it 64) it starts at 0 ..
hehe good to know so after 1 time getting the key you can decrypt everything ;)
GTX Texture files
Yeah ~.~ when you have your decoder .. you sniff a lot of packes (chat is easyest)
And try to write this in chat:
Than you will see first..Code:a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa aaaaaaaaaaa aaaaaaaaaaaa
New packet system have 4 bytes more .. why ? no idea.. (i never looked after it.. i can decryot them but dosn't help much ...)
We allso see .. .. that the decrypted stuff is wrong..
So we know our text is "aaaaaaaa..."
So we see all over 16 bytes (after sniffing) is a other crypt again (AES .. a lot of guys say this ..)
We also know Kal is yeah lol.. becouse first packet (at login, means welcome packet which is crypted with 0) they don't use the new crypt (but the old ..)
So we write a easy rotine..
CryptedStuff (but decryted with CryptTable) xor "aaaaaa...." = OUR XOR KEY
Wolllaaa.. after a lot of testing you will see
that you can crypt all <16 Bytes Packtes.. It's enought to write a KsBot (you wee some ingame ? some are suing my hack..)
MORE INFO ? Sorry can't help you ;)
KSM KalServerMap
Ahm yeah I opend it with my Hex editor and have seen
DTX (or was it DXT .. nvm)
DXT3
DXT1
DXT5
...
So a file which have the abilitiy to change the texture-format (A8R8G8B8 X8R8G8B8 ... )
The only file i knowed which work so .. was DDS
so i saved a dds .. looked my gtx .. and it was 1:1 the same..
(okay.. the header was crypted.. so after a little testing we see ..
the crypt key is 4 ..)
I decrypt the header part ...
Changed the first 3 bytes to DDS..
WOOLLLLAAAA
Can load GTX's -.-
KCM Kal Cell Map ?
Yeah .. I really got no clue what this file should be ..
so i written a easy programm to show a file as graphic..
means:(full source when someone want try out..)
Yeah when you resize the window and let redraw the picture..Code:unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var x,y:integer; myByte:dword; fil:tmemorystream; begin image1.Picture.Bitmap.Width:=form1.Width; image1.Picture.Bitmap.Height:=form1.Height+3000; //neue size //soooooo bild malen fil:=tmemorystream.Create; fil.LoadFromFile('C:\Dokumente und Einstellungen\BakaBug\Desktop\MainSvr-Crack\Map\n_032_032.ksm'); fil.Position:=0; //an dne anfang.. repeat for x:= 0 to image1.Width do begin //auslesen fil.Read(myByte,4); image1.Canvas.Pixels[x,y]:=myByte; end; y:=y+1; until fil.Position>=fil.Size; fil.Free; end; end.
*grins* ..Yeah after a lot of resizing you will start to see a structure
after you are near ~256 (width) .. you say WTF .. that is it ?
Yeah.. KSM are like a picture.. it's a 255x255 (or was it 256x256 ?) shoot of the coolision zones and castle war zones .. saveones etc.
after a little time you will have this script for loading:
Code:type TArea= packed record a,b:word; end; type TKSM=packed record Pixel:array[0..255,0..255] of TArea; end; var KSM:TKSM; .. ... .. fil.read(KSM,sizeof(KSM)); //finish ;)
OPL Object Postion list
Yeah I found it out the same why like KSM ;)
With showing it as picture ^^ (I wont tell you everything)
But 1 tip: "Load it from end of the file.. to the begin of the file"
So it's easyer to laod .. I already know how the Header works..
but also KaME loads it from end to begin ;) becouse it's easyer
HISTORY OF KAL CRYPT
Yeah open it with Hex-Editor and learn reading ~.~
I can't tell you much .. lol such easy..
..
Yeah maybe someon is interrested
- DYNAMIC CryptTableStart, DYNAMIC CrypTableEnd (0-200)
- STATIC CryptTableStart (0), STATIC CryptTableEnd (64)
- Changed CryptTable
- Added Crypt to type-variable
- Changed CryptTable
- Changed type-variables //private server version
- Added a XOR like crypt
- updated the XOR like crypt //offizial version
so thats all for the moment..
When you miss something write it here ;)
OTHER USEFUL STUFF
1909 MainSvrT Functions
by BakaBug
Link: http://forum.ragezone.com/attachment...9kalonline.rar
This list is pretty short, gonna add more to it soon, just threw this together fast now.
If you have any more please post it here.






