Jump to content

Block Drop Hack | Binary Check Name | Get IP | Get Version | Disconnect | Delayed DC


Recommended Posts

  • Premium

M2 Download Center

This is the hidden content, please
( Block Drop Hack | Binary Check Name )

This is the hidden content, please
( Quest Functions - Get IP | Get Version | Disconnect | Delayed DC )

Hi everyone,
 
It's finally time to open a topic for the small tutorials, it's better than flooding the board with one sentence topics.

 

1. Binary name check: Sure, it's possible to do it on client-side, but if we can do it on server-side, theres no reason to do it on client-side.
 
     1. Search for this function in game/input.cpp:

void CInputProcessor::Version(LPCHARACTER ch, const char* c_pData)

     2. Replace the entire function with this:

	if (!ch)
	{
		return;
	}

	TPacketCGClientVersion * p = (TPacketCGClientVersion *) c_pData;

	// If the file name is not metin2client.exe and the GM level is not equal with GM_IMPLEMENTOR kick the player
	if (strcmp(p->filename, "metin2client.exe") && ch->GetGMLevel() != GM_IMPLEMENTOR)
	{
		// immediately close the connection with the player
		sys_err("%s[%d] has been disconnected: %s", ch->GetName(), ch->GetPlayerID(),  p->filename);
		ch->GetDesc()->SetPhase(PHASE_CLOSE);
		return;
	}

	sys_log(0, "VERSION: %s %s %s", ch->GetName(), p->timestamp, p->filename);
	ch->GetDesc()->SetClientVersion(p->timestamp);

 
2. Block the drop hacks: This issue is surely known by everybody, the server gets overloaded when dropping too many items in short time.
 
     1. Open game/char_item.cpp and search for this:

if (pkItemToDrop->AddToGround(GetMapIndex(), pxPos))

     2. Add this under that:

// Clear the variable, it looks the player does not dropped any item in the past second.
if (thecore_pulse() > LastDropTime + 25)
	CountDrops = 0;
	
// It looks the player dropped min. 4 items in the past 1 second
if (thecore_pulse() < LastDropTime + 25 && CountDrops >= 4)
{
	// Set it to 0
	CountDrops = 0;
	sys_err("%s[%d] has been disconnected because of drophack using", GetName(), GetPlayerID());
        // Disconnect the player
	GetDesc()->SetPhase(PHASE_CLOSE);
	return false;
}

     3. Search for this still in game/char_item.cpp:

LogManager::instance().ItemLog(this, pkItemToDrop, "DROP", szHint);

     4. Add this under that:

		LastDropTime = thecore_pulse();
		CountDrops++;

     5. Open game/char.h and add these:

		int					LastDropTime;
		int					CountDrops;

     6. Open game/char.cpp and search for this:

void CHARACTER::Initialize()

     7. Add these to the function:

	CountDrops    = 0;
	LastDropTime  = 0;
  • Metin2 Dev 14
  • Dislove 1
  • Good 10
  • Love 51
Link to comment
Share on other sites

  • Premium

Here are some new small Quest functions:
 
Get the IP address of the player:
 

	int pc_get_ip(lua_State* L)
	{
		lua_pushstring(L, CQuestManager::instance().GetCurrentCharacterPtr()->GetDesc()->GetHostName());
		return 1;
	}

 
Get the client version of the player:
 

	int pc_get_version(lua_State* L)
	{
		lua_pushstring(L, CQuestManager::instance().GetCurrentCharacterPtr()->GetDesc()->GetClientVersion());
		return 1;
	}

 
Delayed disconnect the player:
 

	int pc_delayed_dc(lua_State* L)
	{
		if (!lua_isnumber(L, 1))
			return 0;

		int dctime = (int)lua_tonumber(L, 1);

		if (dctime <= 0)
			return 0;

		CQuestManager::instance().GetCurrentCharacterPtr()->GetDesc()->DelayedDisconnect(dctime);
		return 0;
	}

 
Disconnect the player (with reason):
 

	int pc_dc(lua_State* L)
	{
		const char * reason = lua_tostring(L, 1);

		CQuestManager::instance().GetCurrentCharacterPtr()->Disconnect(reason);
		return 0;
	}
			{ "get_ip",			pc_get_ip },
			{ "get_version",	pc_get_version },
			{ "delayed_dc",		pc_delayed_dc },
			{ "disconnect",		pc_dc },
  • Metin2 Dev 1
  • Love 17
Link to comment
Share on other sites

  • 3 months later...

Error :( 

In file included from char.cpp:25:
shop_manager.h:40:7: warning: no newline at end of file
In file included from char.cpp:62:
PetSystem.h:163:31: warning: no newline at end of file
char.cpp:7237: warning: this decimal constant is unsigned only in ISO C90
char.cpp:7245:2: warning: no newline at end of file
In file included from char_battle.cpp:27:
shop_manager.h:40:7: warning: no newline at end of file
In file included from char_item.cpp:47:
belt_inventory_helper.h:108:42: warning: no newline at end of file
In file included from PetSystem.cpp:8:
PetSystem.h:163:31: warning: no newline at end of file
PetSystem.cpp:637:2: warning: no newline at end of file
PetSystem.cpp: In member function 'virtual bool CPetActor::_UpdateFollowAI()':
PetSystem.cpp:246: warning: unused variable 'bDoMoveAlone'
PetSystem.cpp: In member function 'CPetActor* CPetSystem::Summon(DWORD, CItem*, const char*, bool, DWORD)':
PetSystem.cpp:552: warning: unused variable 'petVID'
constants.cpp:291: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:292: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:293: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:294: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:295: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:296: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:297: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:298: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:299: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:300: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:301: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:302: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:303: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:304: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:305: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:306: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:307: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:308: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:309: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:310: warning: this decimal constant is unsigned only in ISO C90
constants.cpp:311: warning: this decimal constant is unsigned only in ISO C90
char.cpp:131: error: expected initializer before 'CountDrops'
char.cpp:132: error: expected constructor, destructor, or type conversion before '=' token
char.cpp:133: error: expected unqualified-id before '{' token
In file included from char_item.cpp:47:
belt_inventory_helper.h: In static member function 'static BYTE CBeltInventoryHelper::GetBeltGradeByRefineLevel(int)':
belt_inventory_helper.h:28: warning: comparison between signed and unsigned integer expressions
char_item.cpp: In member function 'bool CHARACTER::IsEmptyItemGrid(TItemPos, BYTE, int) const':
char_item.cpp:642: warning: comparison is always false due to limited range of data type
char_item.cpp:668: warning: comparison is always false due to limited range of data type
char.cpp: In member function 'void CHARACTER::PointChange(BYTE, int, bool, bool)':
char.cpp:3082: warning: comparison between signed and unsigned integer expressions
char_item.cpp: In member function 'bool CHARACTER::UseItemEx(CItem*, TItemPos)':
char_item.cpp:2389: warning: format '%d' expects type 'int', but argument 6 has type 'long int'
char_item.cpp:2393: warning: format '%d' expects type 'int', but argument 6 has type 'long int'
char_item.cpp:2405: warning: format '%d' expects type 'int', but argument 5 has type 'long int'
char_item.cpp:2409: warning: format '%d' expects type 'int', but argument 5 has type 'long int'
char_item.cpp:2436: warning: format '%d' expects type 'int', but argument 6 has type 'long int'
char_item.cpp:2444: warning: format '%d' expects type 'int', but argument 5 has type 'long int'
char_item.cpp: In member function 'bool CHARACTER::UseItem(TItemPos, TItemPos)':
char_item.cpp:5156: warning: unused variable 'wDestCell'
char_item.cpp:5157: warning: unused variable 'bDestInven'
char_item.cpp: In member function 'bool CHARACTER::EquipItem(CItem*, int)':
char_item.cpp:6145: warning: array subscript has type 'char'
char_item.cpp: In member function 'void CHARACTER::BuffOnAttr_AddBuffsFromItem(CItem*)':
char_item.cpp:6209: warning: comparison between signed and unsigned integer expressions
char_item.cpp: In member function 'void CHARACTER::BuffOnAttr_RemoveBuffsFromItem(CItem*)':
char_item.cpp:6221: warning: comparison between signed and unsigned integer expressions
char_item.cpp: In member function 'bool CHARACTER::CanEquipNow(CItem*, const TItemPos&, const TItemPos&)':
char_item.cpp:7405: warning: unused variable 'itemType'
char_item.cpp:7406: warning: unused variable 'itemSubType'
char_state.cpp: In member function 'virtual void CHARACTER::StateMove()':
char_state.cpp:901: warning: unused variable 'rider'
In file included from desc_manager.cpp:15:
ClientPackageCryptInfo.h:117:41: warning: no newline at end of file
char_item.cpp: In member function 'bool CHARACTER::IsEmptyItemGrid(TItemPos, BYTE, int) const':
char_item.cpp:681: warning: control reaches end of non-void function
gmake: *** [OBJDIR/char.o] Error 1
gmake: *** Waiting for unfinished jobs....
cmd_gm.cpp: In function 'void do_set_stat(CHARACTER*, const char*, int, int)':
cmd_gm.cpp:3926: warning: NULL used in arithmetic
config.cpp: In function 'void config_init(const std::string&)':
config.cpp:453: warning: NULL used in arithmetic
config.cpp:477: warning: NULL used in arithmetic
config.cpp:501: warning: NULL used in arithmetic
config.cpp:523: warning: unused variable 'line'
cube.cpp: In function 'bool Cube_make(CHARACTER*)':
cube.cpp:544: warning: comparison between signed and unsigned integer expressions
cube.cpp: In function 'void Cube_MakeCubeInformationText()':
cube.cpp:716: warning: unused variable 'npcVNUM'
cube.cpp: In function 'void Cube_InformationInitialize()':
cube.cpp:783: warning: comparison between signed and unsigned integer expressions
desc_client.cpp: In member function 'void CLIENT_DESC::UpdateChannelStatus(DWORD, bool)':
desc_client.cpp:299: warning: comparison between signed and unsigned integer expressions
char_item.cpp: In member function 'void CHARACTER::BuffOnAttr_ValueChange(BYTE, BYTE, BYTE)':
char_item.cpp:6256: warning: 'pBuff' may be used uninitialized in this function
cmd_gm.cpp:3968: warning: 'n' may be used uninitialized in this function
cmd_gm.cpp: In function 'void do_use_item(CHARACTER*, const char*, int, int)':
cmd_gm.cpp:4348: warning: 'cell' may be used uninitialized in this function
cmd_gm.cpp: In function 'void do_mob_ld(CHARACTER*, const char*, int, int)':
cmd_gm.cpp:852: warning: 'x' may be used uninitialized in this function
cmd_gm.cpp:852: warning: 'y' may be used uninitialized in this function

Lib_Error 
 

compile BattleArena.cpp
compile FSM.cpp
compile MarkConvert.cpp
compile MarkImage.cpp
compile MarkManager.cpp
compile OXEvent.cpp
compile TrafficProfiler.cpp
compile ani.cpp
compile arena.cpp
compile banword.cpp
compile battle.cpp
compile blend_item.cpp
compile block_country.cpp
compile buffer_manager.cpp
compile building.cpp
compile castle.cpp
compile char.cpp
compile char_affect.cpp
compile char_battle.cpp
compile char_change_empire.cpp
compile char_horse.cpp
compile char_item.cpp
compile char_manager.cpp
compile char_quickslot.cpp
compile char_resist.cpp
compile char_skill.cpp
compile char_state.cpp
compile PetSystem.cpp
compile cmd.cpp
compile cmd_emotion.cpp
compile cmd_general.cpp
compile cmd_gm.cpp
compile cmd_oxevent.cpp
compile config.cpp
compile constants.cpp
compile crc32.cpp
compile cube.cpp
compile db.cpp
compile desc.cpp
compile desc_manager.cpp
compile desc_client.cpp
compile desc_p2p.cpp
compile dev_log.cpp
compile dungeon.cpp
compile empire_text_convert.cpp

Help me please

Link to comment
Share on other sites

Error :(


char.cpp:131: error: expected initializer before 'CountDrops'
char.cpp:132: error: expected constructor, destructor, or type conversion before '=' token
char.cpp:133: error: expected unqualified-id before '{' token

Help me please

 

You did mistake something in char.cpp check again

 

Best Regards

Ellie

Do not be sorry, be better.

Link to comment
Share on other sites

  • 4 weeks later...
  • Premium

I just answered a question here about how to load up the exp_table from a txt file, but maybe it will be useful for someone else too:

 

Open main.cpp and add this to the top:

#include "fstream"

Search for this still in main.cpp:

PanamaLoad();

Add this under that:

	// START_OF_EXP_TABLE_LOADING
	std::string temp_exp_line;
	std::ifstream exp_table_open("exptable.txt");

	if (!exp_table_open.is_open())
		return 0;

	int exp_table_counter = 0;
	while (!exp_table_open.eof())
	{
		exp_table_open >> temp_exp_line;
		str_to_number(exp_table_common[exp_table_counter], temp_exp_line.c_str());
		exp_table_counter++;
	}
	// END_OF_EXP_TABLE_LOADING

Open constants.cpp and replace this:

const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] =
{
   ...
};

With this:

DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1];

Open constants.h and replace this:

extern const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1];

With this:

extern DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1];

exptable.txt example: http://pastebin.com/KPMGPY38

  • Love 8
Link to comment
Share on other sites

  • 2 weeks later...

 

Aquí están algunas nuevas funciones pequeña de Quest: Obtener la dirección IP del jugador :

 

 

	int pc_get_ip (lua_State * L)
	{
		lua_pushstring (. L, CQuestManager :: ejemplo () GetCurrentCharacterPtr () -> GetDesc () -> GetHostName ());
		return 1;
	}

 

Obtener la versión del cliente del jugador:

 

	int pc_get_version (lua_State * L)
	{
		lua_pushstring (. L, CQuestManager :: ejemplo () GetCurrentCharacterPtr () -> GetDesc () -> GetClientVersion ());
		return 1;
	}

 

Retraso desconecte el reproductor:

 

	int pc_delayed_dc (lua_State * L)
	{
		if (! lua_isnumber (L, 1))
			return 0;

		int dctime = (int) lua_tonumber (L, 1);

		if (dctime <= 0)
			return 0;

		. CQuestManager :: ejemplo () GetCurrentCharacterPtr () -> GetDesc () -> DelayedDisconnect (dctime);
		return 0;
	}

 

Desconecte el reproductor (con razón):

 

	int pc_dc (lua_State * L)
	{
		const char * = razón lua_tostring (L, 1);

		. CQuestManager :: ejemplo () GetCurrentCharacterPtr () -> Disconnect (razón);
		return 0;
	}
			{"Get_ip", pc_get_ip},
			{"Get_version", pc_get_version},
			{"Delayed_dc", pc_delayed_dc},
			{"Desconexión", pc_dc},

 

If I understand correctly. This is a record if some player has lag?

Link to comment
Share on other sites

  • 3 months later...

For ExpTable better Code:

// START_OF_EXP_TABLE_LOADING

		std::string temp_exp_line;
		char szExpTable[256];
		snprintf(szExpTable, sizeof(szExpTable), "%s/exptable.txt", LocaleService_GetBasePath().c_str());
		std::ifstream exp_table_open(szExpTable);

		if (!exp_table_open.is_open()) {
			sys_err("Failed to Load ExpTable from exptable.txt");
			return 0;
		}
		sys_log(0, "START_OF_EXP_TABLE_LOADING:");
		int exp_table_counter = 0;
		while (!exp_table_open.eof())
		{
			exp_table_open >> temp_exp_line;
			str_to_number(exp_table_common[exp_table_counter], temp_exp_line.c_str());
			exp_table_counter++;
			sys_log(0, "ExpTabele: Level: %u %s", exp_table_counter, temp_exp_line.c_str());

			if (exp_table_counter < gPlayerMaxLevel)
			{
				sys_err("Failed ExpTable is lower to MaxExp to Set");
				return 0;
			}

		}
		sys_log(0, "END_OF_EXP_TABLE_LOADING:");

		// END_OF_EXP_TABLE_LOADING
	}
Link to comment
Share on other sites

  • 1 month later...

 

For ExpTable better Code:

// START_OF_EXP_TABLE_LOADING

		std::string temp_exp_line;
		char szExpTable[256];
		snprintf(szExpTable, sizeof(szExpTable), "%s/exptable.txt", LocaleService_GetBasePath().c_str());
		std::ifstream exp_table_open(szExpTable);

		if (!exp_table_open.is_open()) {
			sys_err("Failed to Load ExpTable from exptable.txt");
			return 0;
		}
		sys_log(0, "START_OF_EXP_TABLE_LOADING:");
		int exp_table_counter = 0;
		while (!exp_table_open.eof())
		{
			exp_table_open >> temp_exp_line;
			str_to_number(exp_table_common[exp_table_counter], temp_exp_line.c_str());
			exp_table_counter++;
			sys_log(0, "ExpTabele: Level: %u %s", exp_table_counter, temp_exp_line.c_str());

			if (exp_table_counter < gPlayerMaxLevel)
			{
				sys_err("Failed ExpTable is lower to MaxExp to Set");
				return 0;
			}

		}
		sys_log(0, "END_OF_EXP_TABLE_LOADING:");

		// END_OF_EXP_TABLE_LOADING
	}

Your code is wrong...

Link to comment
Share on other sites

  • Premium

Here's an improved version of experience table.

 

In constants.h search for

extern const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1];

And change it to

extern DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1];

In constants.cpp search for

const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] =
{
	...
}

And change it to

DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] =
{
	...
}

Now search in config.cpp for

#include <sstream>

And add under

#include <fstream>

Still in config.cpp search for

TOKEN("mark_server")

And add above or under it

TOKEN("exp_table")
{
	if (strlen(value_string) > 0)
		LoadExpTable(value_string);

	continue;
}

Still in config.cpp search for

static void FN_log_adminpage()

And add above or under it

void LoadExpTable(char* name)
{
	std::ifstream f(name);

	printf("EXP_TABLE load: %s n", name);
	if (!f.is_open())
	{
		printf("EXP_TABLE load: FILE %s OPEN ERROR", name);
		return;
	}

	int level = 0;
	DWORD exp = 0;
	int line = 0;

	while (!f.eof())
	{
		f>>level;
		f>>exp;
		line++;
		
		if (level <= 0 || exp <= 0)
			printf("EXP_TABLE load !ERROR!: LINE %d LEVEL %d EXP %ld n", line, level, exp);
        else if (level > PLAYER_EXP_TABLE_MAX)
            printf("EXP_TABLE load !ERROR!: LINE %d LEVEL %d > MAX EXP LEVEL %dn", line, level, PLAYER_EXP_TABLE_MAX);
		else
		{
			printf("EXP_TABLE load: LINE %d LEVEL %d EXP %ld n", line, level, exp);
			exp_table_common[level] = exp;
		}
	}

	printf("EXP_TABLE load: done n");
}

So, a short description:

If you want to edit experience table you have to add in CONFIG of each channel

EXP_TABLE: /path/to/file/exp_table.txt

The file can be anywhere, but you must have the rights to read it.

You can edit experience for the levels you want. You don't need to change all levels. Also, the levels can be in any order you want.

That's the structure of the file:

1	2000
2	10000
89	10
5	0
7	30

The first column is for levels and the second is for experience. Between them can be space or tab or even new lines (but it must be one after another).

For the file I specified above you should get this in PuTTy or any SSH client you use (at the end of MAP_ALLOW probably):

EXP_TABLE load: /path/to/file/exp_table.txt
EXP_TABLE load: LINE 1 LEVEL 1 EXP 1000
EXP_TABLE load: LINE 2 LEVEL 2 EXP 20000
EXP_TABLE load: LINE 3 LEVEL 89 EXP 10
EXP_TABLE load !ERROR!: LINE 4 LEVEL 5 EXP 0
EXP_TABLE load: LINE 5 LEVEL 7 EXP 30
EXP_TABLE load: done

As you see if you specify 0 exp for a level it just skip it (as i did for level 5, line 4).

Also, if the file is empty or does not exists it will not load it.

Tip: I added lines to be easier for you to find where you did something wrong :D

 

EDIT: Add check for level.

 

Have fun.

Edited by Cataclismo
  • Love 2
Link to comment
Share on other sites

@Cataclismo

     

RttUDUB.png

Console spam annoys me so I had to make it look like this.

Anyway, thank you for your hard work, guess I wouldn't toy with *.txt tables if I hadn't seen your script.

It's clean, readable and really easy modifiable.

 

Regards,

newja

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 1
Link to comment
Share on other sites

 

@Cataclismo:

Error in putty:

 
EXP_TABLE load: LINE 100 LEVEL 100 EXP -2144967296
EXP_TABLE load: LINE 101 LEVEL 101 EXP -2084967296

 

It's not an error, it's more like display problem (in game everything should work).

When your DWORD has same size as int (clearly has) you can go to config.cpp and change

DWORD exp = 0;

to

long int exp =0;

if you need bigger size you can use long long int but then you'll have to replace every %ld with %lld

Link to comment
Share on other sites

  • Premium

@Cataclismo

     

RttUDUB.png

Console spam annoys me so I had to make it look like this.

Anyway, thank you for your hard work, guess I wouldn't toy with *.txt tables if I hadn't seen your script.

It's clean, readable and really easy modifiable.

 

Regards,

newja

 

I like clean code :) . I cleaned the source a lot xD

Glad to help.

 

 

 

@Cataclismo:

Error in putty:

 
EXP_TABLE load: LINE 100 LEVEL 100 EXP -2144967296
EXP_TABLE load: LINE 101 LEVEL 101 EXP -2084967296

 

It's not an error, it's more like display problem (in game everything should work).

When your DWORD has same size as int (clearly has) you can go to config.cpp and change

DWORD exp = 0;

to

long int exp =0;

if you need bigger size you can use long long int but then you'll have to replace every %ld with %lld

 

 

It's not really recommended to do this.

The experience table is type DWORD (and DON'T change the type if you don't know what you're doing) which is an unsigned long.

Maximum value of DWORD can be 4,294,967,295. If you wrote in experience table a value bigger than 4,294,967,295 then the things will fuck up. Try to adjust experience to fit in this value. Edit the rates of your server to fit in those values too. :)

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 1
Link to comment
Share on other sites

void LocaleService_LoadExpTable(const string& dir)
{
	string file = dir + "/exp_table.txt";

	FILE* f = fopen(file.c_str(), "r");

	if (!f) {
		fprintf(stdout, "Can't load players exp_table file. Using defaults.n");
		return;
	}

	DWORD level;
	DWORD exp;

	fprintf(stdout, "Loading exp_table file from %sn", file.c_str());
	while (!feof(f)) {
		fscanf(f, "%u: %u", &level, &exp);

		if (level > 0 && level <= PLAYER_EXP_TABLE_MAX) {
			exp_table[level] = exp;
			fprintf(stdout, "Level %u = %u EXP.n", level, exp);
		}
	}
	fclose(f);
}

LocaleService_LoadExpTable(g_stServiceBasePath);

Exp files:

1: 1000

2: 132131231

3: 131231

And so one

Link to comment
Share on other sites

  • Premium

my exp_table.txt:

 ay3tH9U.png?1

 

error in putty: (exp negative)

w2nVw2w.png?1

 

If you can see in he loaded experience table with maximum value of 4,278,420,394 which is much higher than your max. My guess is that you redefined type DWORD or is already defined wrong which would be strange. If you redefined DWORD then restore it. If you didn't then in config.cpp change

DWORD exp = 0;

to

unsigned long exp = 0;

Build game, start server and the most important step: test if the experience is correct by leveling in game!

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

Try that

void LoadExpTable(char* name)
{
    std::ifstream f(name);
 
    printf("EXP_TABLE load: %s n", name);
    if (!f.is_open())
    {
        printf("EXP_TABLE load: FILE %s OPEN ERROR", name);
        return;
    }
 
    int level = 0;
    long long int exp = 0;
    int line = 0;
 
    while (!f.eof())
    {
        f>>level;
        f>>exp;
        line++;
         
        if (level <= 0 || exp <= 0)
            printf("EXP_TABLE load !ERROR!: LINE %d LEVEL %d EXP %lld n", line, level, exp);
        else if (level > PLAYER_EXP_TABLE_MAX)
            printf("EXP_TABLE load !ERROR!: LINE %d LEVEL %d > MAX EXP LEVEL %dn", line, level, PLAYER_EXP_TABLE_MAX);
        else
        {
            printf("EXP_TABLE load: LINE %d LEVEL %d EXP %lld n", line, level, exp);
            exp_table_common[level] = exp;
        }
    }
 
    printf("EXP_TABLE load: done n");
}

 

There shouldn't be any problems unless your EXP table exceed this number 9223372036854775807 which I think won't happen.  :blink:

//Forgot to mention.. When you get bigger numbers in your EXP table than 4294967295, this line will start to make errors:

exp_table_common[level] = exp;

so be cautious.

Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.