rendered paste body#include <time.h>#include <memory.h>#include <fcntl.h>#include <sys/timeb.h>#include <math.h>#include <vector>#include <string>#include <sstream>#include <jni.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifdef WIN32#include <io.h>#else#include <sys/ipc.h>#include <sys/shm.h>#include <sys/mman.h>#include <unistd.h>#endif#include "geodata.h"#ifdef WIN32BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}#endifvoid* GeoData_Offset[32*32][65536]; // 65536 offsets per regionvoid* GeoData_Cells[32*32]; // 32x32 regionsint getRegionOffset(int x, int y);short getHeight(int x, int y, int z);short getType(int x, int y);void loadGeo(const char* fname);static int E = 1;static int W = 2;static int S = 4;static int N = 8;JNIEXPORT void JNICALL Java_net_sf_l2j_gameserver_GeoEngine_NinitGeodata (JNIEnv *env, jclass jniclass){ memset(GeoData_Offset,0,32*32*65536); memset(GeoData_Cells,0,1024); FILE* idx = fopen("geodata/geo_index.txt","r"); if(!idx) { printf("[%s][%d] error opening geodata index file!\n",__FILE__,__LINE__); return; } char buf[1024]; do { fscanf(idx,"%s\n",buf); loadGeo(buf); }while(!feof(idx)); return;}void loadGeo(const char* fname){ char geoX,geoY; char fullname[256]; int cptr=0; int i; int flor =0; sprintf(fullname,"geodata/%s_conv.dat",fname); printf("Loading %s ",fname);#ifndef WIN32 int fd = open(fullname,O_RDONLY); if(fd == -1) { printf("[ERR]\n"); return; }#else HANDLE hFile = CreateFile(fullname,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("[ERR]\n"); return; }#endif struct stat fstat; stat(fullname,&fstat); int sz = fstat.st_size;#ifndef WIN32 char* mapPtr = (char*)mmap(0,sz,PROT_READ,MAP_SHARED,fd,0);#else HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,sz,fname); char* mapPtr = (char*)MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,sz); #endif if(mapPtr == NULL) { printf("[%s][%d] MemoryMap failed!\n",__FILE__,__LINE__); return; } geoX = *(char*)mapPtr; geoY = *(char*)(mapPtr+1); printf(" X: %d Y: %d ",geoX,geoY); char *ptr = mapPtr+18; GeoData_Cells[geoX*32+geoY] = ptr; printf("[%dKb][%d]\n",sz/1024,(geoX*32+geoY)); //repeat 256x256 times for(i=0;i<65535;i++) { short *type; type = (short*)ptr; GeoData_Offset[geoX*32+geoY][cptr] = ptr; cptr++; ptr+=2; //type -> juz wczytane if(*type == 0x0000) { ptr+=4; // 2x short } else if(*type == 0x0040) { ptr+=128; // 64x short } else { int b; for(b=0;b<64;b++) { short layers = *(short*)ptr; ptr+= (layers*2)+2; if (layers > flor) flor = layers; } } } //close(fd); printf("Max Layers: %d\n",flor);}JNIEXPORT jshort JNICALL Java_net_sf_l2j_gameserver_GeoEngine_NgetType (JNIEnv *env, jclass jniclass, jint x, jint y){ int region = getRegionOffset(x,y); int blockX,blockY; if(GeoData_Cells[region] == NULL) { printf("[%s][%d] geo NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } getBlock(x,y,(int&)blockX,(int&)blockY); return *(short*)GeoData_Offset[region][(blockX*256)+(blockY)]; }JNIEXPORT jshort JNICALL Java_net_sf_l2j_gameserver_GeoEngine_NgetHeight (JNIEnv *env, jclass jniclass, jint x, jint y, jint z){ int region = getRegionOffset(x,y); int blockX,blockY,cellX,cellY; if(GeoData_Cells[region] == NULL) { printf("[%s][%d] geo NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } getBlock(x,y,(int&)blockX,(int&)blockY); short* blockOff = (short*)GeoData_Offset[region][(blockX*256)+(blockY)]; // ptr now on type field if(blockOff == NULL) { printf("[%s][%d] geo_block NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } short type = *(short*)blockOff; blockOff++; if(type == 0) { return (*(short*)blockOff)&0x0fff0; } else if(type == 0x0040) { getCell(x,y,(int&)cellX,(int&)cellY); blockOff+=cellX*8+cellY; short height = *(short*)blockOff; height = height&0x0fff0; height /= 2; return height; } else { getCell(x,y,(int&)cellX,(int&)cellY); int offset = cellX*8+cellY; //printf("Ofseet: %d\n",offset); while(offset > 0) { short lc = *(short*)blockOff; //printf("[%s][%d] lc %d\n",__FILE__,__LINE__,lc); blockOff += lc+1; offset--; } short layers = (*(short*)blockOff); short height=-1; if(layers <= 0 || layers > 60) { printf("[%s][%d] invalid layers count: %d at %d %d\n",__FILE__,__LINE__,layers,x,y); return height; } short temph = -9000; while(layers > 0) { blockOff++; height = *blockOff; height = height&0x0fff0; height /= 2; //printf("layer: %d height: %d\n",layers,height); if ((z-temph)*(z-temph) > (z-height)*(z-height)) temph = height; layers--; } //printf("Return: %d\n",temph); return temph; }}JNIEXPORT jshort JNICALL Java_net_sf_l2j_gameserver_GeoEngine_NcanMoveNext (JNIEnv *env, jclass jnic, jint x, jint y, jint z, jint tz, jint heading){ int region = getRegionOffset(x,y); int blockX,blockY,cellX,cellY; short NSWE; if(GeoData_Cells[region] == NULL) { printf("[%s][%d] geo NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } getBlock(x,y,(int&)blockX,(int&)blockY); short* blockOff = (short*)GeoData_Offset[region][(blockX*256)+(blockY)]; // ptr now on type field if(blockOff == NULL) { printf("[%s][%d] geo_block NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } short type = *(short*)blockOff; blockOff++; if(type == 0) { return true; } else if(type == 0x0040) { getCell(x,y,(int&)cellX,(int&)cellY); blockOff+=cellX*8+cellY; short height = *(short*)blockOff; NSWE = height&0x0F; } else { getCell(x,y,(int&)cellX,(int&)cellY); int offset = cellX*8+cellY; while(offset > 0) { short lc = *(short*)blockOff; //printf("[%s][%d] lc %d\n",__FILE__,__LINE__,lc); blockOff += lc+1; offset--; } short layers = (*(short*)blockOff); short height=-1; if(layers <= 0 || layers > 60) { printf("[%s][%d] invalid layers count: %d at %d %d\n",__FILE__,__LINE__,layers,x,y); return false; } short tempz = -9000; short tempz2 = -9000; while(layers > 0) { blockOff++; height = *blockOff; height = height&0x0fff0; height /= 2; if ((z-tempz)*(z-tempz) > (z-height)*(z-height)) { tempz = height; NSWE = *blockOff; NSWE = NSWE&0x0F; } if ((z-tempz2)*(z-tempz2) > (z-height)*(z-height)) { tempz2 = height; } layers--; } if(tempz != tempz2) { return false; } } //Sprawdz NSWE if(NSWE == 15) return true; else if(8192 < heading && heading < 24576) //S { if ((NSWE & S) == 0) return false; else return true; } else if(24576 < heading && heading < 40960) //W { if ((NSWE & W) == 0) return false; else return true; } else if(40960 < heading && heading < 57344) //N { if ((NSWE & N) == 0) return false; else return true; } else if(57344 < heading || heading < 8192) //E { if ((NSWE & E) == 0) return false; else return true; } else if(heading == 8192) //SE { if ((NSWE & S) == 0 || (NSWE & E) == 0) return false; else return true; } else if(heading == 24576) //SW { if ((NSWE & S) == 0 || (NSWE & W) == 0) return false; else return true; } else if(heading == 40960) //NW { if ((NSWE & N) == 0 || (NSWE & W) == 0) return false; else return true; } else if(heading == 57344) //NE { if ((NSWE & N) == 0 || (NSWE & E) == 0) return false; else return true; } else { printf("LOS: ERROR! Heading = %d \n",heading); return false; } return false; }JNIEXPORT jshort JNICALL Java_net_sf_l2j_gameserver_GeoEngine_NgetNSWE (JNIEnv *env, jclass jnic, jint x, jint y, jint z){ int region = getRegionOffset(x,y); int blockX,blockY,cellX,cellY; short NSWE; if(GeoData_Cells[region] == NULL) { printf("[%s][%d] geo NULL at %d %d!\n",__FILE__,__LINE__,x,y); return 0; } getBlock(x,y,(int&)blockX,(int&)blockY); short* blockOff = (short*)GeoData_Offset[region][(blockX*256)+(blockY)]; // ptr now on type field short type = *(short*)blockOff; blockOff++; if(type == 0) { return 15; } else if(type == 0x0040) { getCell(x,y,(int&)cellX,(int&)cellY); blockOff+=cellX*8+cellY; short height = *(short*)blockOff; NSWE = height&0x0F; } else { getCell(x,y,(int&)cellX,(int&)cellY); int offset = cellX*8+cellY; //printf("Ofseet: %d\n",offset); while(offset > 0) { short lc = *(short*)blockOff; //printf("[%s][%d] lc %d\n",__FILE__,__LINE__,lc); blockOff += lc+1; offset--; } short layers = (*(short*)blockOff); short height=-1; if(layers <= 0 || layers > 60) { printf("[%s][%d] invalid layers count: %d at %d %d\n",__FILE__,__LINE__,layers,x,y); NSWE = height; } short temph = -9000; while(layers > 0) { blockOff++; height = *blockOff; height = height&0x0fff0; height /= 2; //printf("layer: %d height: %d\n",layers,height); if ((z-temph)*(z-temph) > (z-height)*(z-height)) { temph = height; NSWE = *blockOff; NSWE = NSWE&0x0F; } layers--; } } return NSWE; }inline int getRegionOffset(int x, int y){ int rx = x / 2048; // 256 * 8 int ry = y / 2048; return ((rx+16)*32 + (ry+10));}inline void getBlock(int x, int y, int &blockX, int &blockY){ blockX = (x/8) % 256; blockY = (y/8) % 256;}inline void getCell(int x, int y, int &cellX, int &cellY){ cellX = x % 8; cellY = y % 8;}