Premium Sanchez 2464 Posted February 24, 2014 Premium Share Posted February 24, 2014 M2 Download Center This is the hidden content, please Sign In or Sign Up ( Block Drop Hack | Binary Check Name ) This is the hidden content, please Sign In or Sign Up ( 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; 14 1 10 51 Link to comment Share on other sites More sharing options...
Premium Sanchez 2464 Posted March 2, 2014 Author Premium Share Posted March 2, 2014 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 }, 1 17 Link to comment Share on other sites More sharing options...
metin2team 757 Posted June 24, 2014 Share Posted June 24, 2014 (edited) these are useful stuff. Thanks for sharing them. Edited September 6, 2015 by metin2team Link to comment Share on other sites More sharing options...
doNaLs 4 Posted July 1, 2014 Share Posted July 1, 2014 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 More sharing options...
CrazyBear 2 Posted July 5, 2014 Share Posted July 5, 2014 Hello, Any diff for the drop hack thingy? Thanks Link to comment Share on other sites More sharing options...
Ken 904 Posted July 11, 2014 Share Posted July 11, 2014 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 More sharing options...
Premium Sanchez 2464 Posted August 4, 2014 Author Premium Share Posted August 4, 2014 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 8 Link to comment Share on other sites More sharing options...
Adrian1428 31 Posted August 7, 2014 Share Posted August 7, 2014 Many thanks How can I change the path to the exp table in locale / xx ? I know I have to change this line: std::ifstream exp_table_open("exptable.txt"); I tried something but not work Link to comment Share on other sites More sharing options...
Premium Sanchez 2464 Posted August 7, 2014 Author Premium Share Posted August 7, 2014 std::ifstream exp_table_open("locale/english/exptable.txt"); 1 Link to comment Share on other sites More sharing options...
Adrian1428 31 Posted August 20, 2014 Share Posted August 20, 2014 std::ifstream exp_table_open("locale/english/exptable.txt"); This I did in the end but I was referring to something else. I wanted to detect the locale use only. Link to comment Share on other sites More sharing options...
Shichirojii 8 Posted August 20, 2014 Share Posted August 20, 2014 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 More sharing options...
Aurora 46 Posted December 19, 2014 Share Posted December 19, 2014 Is there a tutorial for item proto server to use .sql instead of .txt and the other way around? Link to comment Share on other sites More sharing options...
Risan 115 Posted December 20, 2014 Share Posted December 20, 2014 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 More sharing options...
daredevil09 5 Posted February 17, 2015 Share Posted February 17, 2015 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 More sharing options...
Premium Cataclismo 86 Posted February 18, 2015 Premium Share Posted February 18, 2015 (edited) 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 EDIT: Add check for level. Have fun. Edited February 18, 2015 by Cataclismo 2 Link to comment Share on other sites More sharing options...
newja 53 Posted February 19, 2015 Share Posted February 19, 2015 (edited) @Cataclismo 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 August 18, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
ScreamMyName 100 Posted February 19, 2015 Share Posted February 19, 2015 Can I make a suggestion ? I Think the topic will be much more clearer and organized if you do sections in first post and add everything to the first post in spoilers. Link to comment Share on other sites More sharing options...
daredevil09 5 Posted February 19, 2015 Share Posted February 19, 2015 @Cataclismo: Error in putty: EXP_TABLE load: LINE 100 LEVEL 100 EXP -2144967296 EXP_TABLE load: LINE 101 LEVEL 101 EXP -2084967296 Link to comment Share on other sites More sharing options...
newja 53 Posted February 19, 2015 Share Posted February 19, 2015 @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 More sharing options...
Premium Cataclismo 86 Posted February 19, 2015 Premium Share Posted February 19, 2015 (edited) @Cataclismo 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 August 18, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
ionutxp 72 Posted February 19, 2015 Share Posted February 19, 2015 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 More sharing options...
daredevil09 5 Posted February 19, 2015 Share Posted February 19, 2015 (edited) my exp_table.txt: Maximum value in my exp_table is: 2.500.000.000 but maximum value of DWORD can be 4,294,967,295, but i have this error in putty: (exp negative) Edited August 18, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Premium Cataclismo 86 Posted February 19, 2015 Premium Share Posted February 19, 2015 (edited) my exp_table.txt: error in putty: (exp negative) 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 August 18, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
daredevil09 5 Posted February 19, 2015 Share Posted February 19, 2015 Don't work... error in putty exp negative (-) I changed DWORD exp = 0; to unsigned long exp = 0; but no difference... Link to comment Share on other sites More sharing options...
newja 53 Posted February 19, 2015 Share Posted February 19, 2015 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. //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 More sharing options...
Recommended Posts