-
Posts
919 -
Joined
-
Days Won
888 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Mali
-
-
-
- 3
- 4
- 8
-
I'm opening this topic so that I can post some tests here from time to time.
The Death Of Inventory Buttons:
- 5
- 1
- 1
- 3
- 2
- 11
-
-
13 minutes ago, duwen123 said:
Hello, Mali!
Hi
13 minutes ago, duwen123 said:Why did you removed your repositories on GitHub? Is everything OK?
Yes, everything is OK. Thanks for asking.
I made such a decision, I had some reasons.
13 minutes ago, duwen123 said:I'm curious because I had some links to your repos, for me to further implement on my project.
All my projects are in this forum and forum has my repos's backups:
Spoiler -
9 hours ago, ‚Point‘ said:
Thanks for your reply. To be honest i don't really know how to do this.
Could you give me an example please i you have time?
Best Regards
ActorInstance.h:
Spoiler//Find bool IsPoly(); ///Add bool IsPet() const;
ActorInstance.cpp:
Spoiler//Find bool CActorInstance::IsPoly() { ... } ///Add bool CActorInstance::IsPet() const { //for 2014 default proto if (TYPE_NPC != m_eActorType) return false; switch (m_eRace) { case 34005: case 34006: return true; default: return false; } } //Find /*if (GetActorType() == EType::TYPE_PET || GetActorType() == EType::TYPE_PET_PAY) m_bRenderActor = CPythonGraphicOnOff::Instance().CanRenderPet();*/ ///Change if (IsPet()) m_bRenderActor = CPythonGraphicOnOff::Instance().CanRenderPet();
you add the vnum of the pets to the function
- 1
-
2 minutes ago, ‚Point‘ said:
Thanks for the release, appreciate a lot!
Everything is working like a charm, execpt the Pet Show/Hide.
Any ideas on it?
https://metin2.download/picture/p1o80Gi6QMHR8dIjQh4Um7kGOlC33Ydm/.gif
Best Regards
There is a special type for pets in the official proto, but we don't have them.
You can use this with a control function like IsPet or sth like that
-
2 minutes ago, xP3NG3Rx said:
masodi made it by himself from scratch, analyzing the rendercode itself, how it works, afaik.
The difference between me and Bela is he knows how it works.(i said this on discord too)
I just took what the GF did.
I still don't know the main logic
5 minutes ago, xP3NG3Rx said:They are us, to collect ideas which can make money or can be useful.
100%
5 minutes ago, xP3NG3Rx said:About the pain around RE, when you finish something and it works, that's the best, the pain floats away.
I don't know if I would do it again if I had my current mind. When I look back and see how much time was wasted, the pain continues
I see you were doing these reverse things even in 2015(7 years ago, time flies).
If you hadn't done these things, I wouldn't have even thought of doing it.(I guess)
Thank you for opening our horizons
-
On 11/23/2022 at 8:13 PM, Kafa said:
he is a god xD
thank you
On 11/23/2022 at 8:05 PM, Legion said:Nice
How long did it take you?Clipmask was my first reverse engineering project.
I was very amateur, it would have taken less time if I did it now.
- 1
- 1
- 2
- 1
-
Video:
Added to the game with this update:
You need this function to use it:
I reverse engineered it from official binary and had a hard time doing it.(Bela and other guys knows this)
GUI is ok right now, i don't want to make it full official.(Paying to use it etc.)
I've hidden the save and reset settings buttons for now, maybe I'll activate them in the future.
I have no plans to sell, I always share stuff for free.
- 17
- 4
- 1
- 12
-
-
-
3 minutes ago, 𝐏𝐲𝐭𝐡𝐨𝐧 said:
Ok, I have already written to you so that we can see the system and we can make a deal.
Greetings.
It was a bad joke
I am not selling anything.
System will be shared for free in june-july next year.
Have a good day
- 1
-
change branch: https://metin2.download/picture/aK9gt3eD0eRRTJQZMG0mvpSdo6C3v8RJ/.gif
see changes by version: https://metin2.download/picture/2Zw9IWSBYHOvJIePIM2ig17mbxTe3cJt/.gif- 237
- 8
- 11
- 1
- 2
- 1
- 1
- 2
- 1
- 3
- 59
- 11
- 174
-
1 hour ago, Owsap said:
Here is an easier way to write and read quest translations, a function that will filter and return the complete token.
nice idea, I was using sth like this on the server side in the first version:
enum class LOCALE_TYPE { LOCALE_STRING, LOCALE_QUEST_STRING, LOCALE_OX_STRING, }; template<LOCALE_TYPE type, int id, typename... Args> std::string LOCALE_STRING(Args&& ... args) { std::stringstream stream; stream << '['; switch (type) { case LOCALE_TYPE::LOCALE_STRING: stream << "LS;" << id; break; case LOCALE_TYPE::LOCALE_QUEST_STRING: stream << "LC;" << id; break; case LOCALE_TYPE::LOCALE_OX_STRING: stream << "LOX;" << id; break; default: return ""; } #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) ((stream << ';' << std::forward<Args>(args)), ...); // fold expression #else int dummy[] = { 0, ((stream << ';' << std::forward<Args>(args)), 0)...}; static_cast<void>(dummy); // Avoid warning for unused variable #endif stream << ']'; return stream.str(); }
LOCALE_STRING<LOCALE_TYPE::LOCALE_STRING, 3>(); LOCALE_STRING<LOCALE_TYPE::LOCALE_STRING, 16>("BLACK", "XD");
then I removed it because I saw official not do like that:
- 1
- 1
-
2 hours ago, m2Ciaran said:
Very nice thread, thank you.
I think the functions are called wrong in PythonApplication. I mean, their names are differenet here and in PythonLocale according to github.
Thank you, fixed
2 hours ago, m2Ciaran said:Also, for monster chat you can use something like that:
#if defined(__BL_CLIENT_LOCALE_STRING__) if (pkInstChatter->IsNPC() || pkInstChatter->IsEnemy()) { CPythonLocale::Instance().FormatString(buf, sizeof(buf)); _snprintf(line, sizeof(line), "%s", buf); break; } #endif
You don't have to add this.
Except for the messages written by the players, other messages are already formatting.
-
13 minutes ago, filipw1 said:
Are you into this now or is this @ xP3NG3Rx contributing?
My work; after he get banned, someone needs to do this job
13 minutes ago, filipw1 said:BTW is this Saul as a GTA V character on your profile picture?
yes it is xddd
- 4
- 1
-
Q: Do they really use boost::format?
A: No, They wrote a function that checks the arguments one by one. I preferred boost::format which makes this job more professional and clean.
Here is real function:
Spoilerbool sub_27D1C0(std::string& sMessage, std::vector<std::string>& args) { std::stringstream ss; size_t _c_ = 0; size_t arg_i = 1; const size_t sMessage_size = sMessage.size(); while (_c_ < sMessage_size) { char current_character = sMessage[_c_]; if (current_character == '%') { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; switch (current_character) { case '%': { ss << '%'; break; } case '*': { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character == 's' && arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << _arg; } } break; } case '.': { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character >= '1' && current_character <= '9' && ++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character == 'f' && arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << _arg; } } } break; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character == 'd' && arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << _arg; } } break; } case 'd': { if (arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << boost::lexical_cast<int>(_arg); } break; } case 'l': { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character == 'l') { if (++_c_ < sMessage_size) { current_character = sMessage[_c_]; if (current_character == 'd' && arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << boost::lexical_cast<long long>(_arg); } } } else if (current_character == 'u' && arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << boost::lexical_cast<unsigned long>(_arg); } } break; } case 's': { if (arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << _arg; } break; } case 'u': { if (arg_i < args.size()) { std::string& _arg = args[arg_i++]; ss << boost::lexical_cast<unsigned int>(_arg); } break; } default: return false; } } } else { ss << current_character; } ++_c_; } sMessage = ss.str(); return true; }
pseudo:
char __stdcall sub_27D1C0(_DWORD *sMessage, int args) { char *v3; // [esp+10h] [ebp-1F8h] _DWORD *v4; // [esp+18h] [ebp-1F0h] _DWORD *v5; // [esp+20h] [ebp-1E8h] char *v6; // [esp+28h] [ebp-1E0h] _DWORD *v7; // [esp+30h] [ebp-1D8h] _DWORD *v8; // [esp+3Ch] [ebp-1CCh] _DWORD *v9; // [esp+44h] [ebp-1C4h] char *v10; // [esp+4Ch] [ebp-1BCh] char *v11; // [esp+54h] [ebp-1B4h] _DWORD *v12; // [esp+5Ch] [ebp-1ACh] _DWORD *v13; // [esp+64h] [ebp-1A4h] _DWORD *v14; // [esp+68h] [ebp-1A0h] _DWORD *v15; // [esp+9Ch] [ebp-16Ch] int v16; // [esp+C0h] [ebp-148h] unsigned int v17; // [esp+C4h] [ebp-144h] int v18; // [esp+C8h] [ebp-140h] unsigned int v19; // [esp+CCh] [ebp-13Ch] int v20; // [esp+D0h] [ebp-138h] char v21[4]; // [esp+D4h] [ebp-134h] BYREF int v22; // [esp+D8h] [ebp-130h] unsigned int v23; // [esp+DCh] [ebp-12Ch] _DWORD *v24; // [esp+E0h] [ebp-128h] char v25[4]; // [esp+E4h] [ebp-124h] BYREF int v26; // [esp+E8h] [ebp-120h] unsigned int v27; // [esp+ECh] [ebp-11Ch] unsigned int v28; // [esp+F0h] [ebp-118h] char v29[4]; // [esp+F4h] [ebp-114h] BYREF int v30; // [esp+F8h] [ebp-110h] unsigned int v31; // [esp+FCh] [ebp-10Ch] unsigned int v32; // [esp+100h] [ebp-108h] char v33[4]; // [esp+104h] [ebp-104h] BYREF int v34; // [esp+108h] [ebp-100h] unsigned int v35; // [esp+10Ch] [ebp-FCh] unsigned int v36; // [esp+110h] [ebp-F8h] unsigned int v37; // [esp+114h] [ebp-F4h] unsigned int v38; // [esp+118h] [ebp-F0h] unsigned int v39; // [esp+11Ch] [ebp-ECh] int v40; // [esp+120h] [ebp-E8h] int v41; // [esp+124h] [ebp-E4h] char v42; // [esp+12Bh] [ebp-DDh] int v43[7]; // [esp+12Ch] [ebp-DCh] BYREF char v44; // [esp+14Bh] [ebp-BDh] __int64 v45; // [esp+14Ch] [ebp-BCh] int v46; // [esp+158h] [ebp-B0h] int v47; // [esp+15Ch] [ebp-ACh] int v48; // [esp+160h] [ebp-A8h] char v49[8]; // [esp+164h] [ebp-A4h] BYREF char v50[76]; // [esp+16Ch] [ebp-9Ch] BYREF int v51[13]; // [esp+1B8h] [ebp-50h] BYREF unsigned __int8 current_character; // [esp+1EFh] [ebp-19h] int sMessage_size; // [esp+1F0h] [ebp-18h] unsigned int _c_; // [esp+1F4h] [ebp-14h] unsigned int arg_i; // [esp+1F8h] [ebp-10h] int v56; // [esp+204h] [ebp-4h] v41 = 0; sub_2845D0(3, 1); v56 = 0; v40 = sMessage[5]; sMessage_size = v40; current_character = 0; _c_ = 0; arg_i = 1; while ( _c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v14 = sMessage + 1; else v14 = sMessage[1]; current_character = *(v14 + _c_); if ( current_character == '%' ) { if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v13 = sMessage + 1; else v13 = sMessage[1]; current_character = *(v13 + _c_); switch ( current_character ) { case '%': if ( v49 ) sub_1B7650(v50, '%'); else sub_1B7650(0, '%'); break; case '*': if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v7 = sMessage + 1; else v7 = sMessage[1]; current_character = *(v7 + _c_); if ( current_character == 's' && arg_i < (*(args + 16) - *(args + 12)) / 28 ) { if ( v49 ) v6 = v50; else v6 = 0; v19 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v18 = *(args + 12) + 28 * v19; ++arg_i; if ( *(v18 + 24) < 0x10u ) sub_287790(v6, (v18 + 4)); else sub_287790(v6, *(v18 + 4)); } } break; case '.': if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v5 = sMessage + 1; else v5 = sMessage[1]; current_character = *(v5 + _c_); if ( current_character >= '1' && current_character <= '9' && ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v4 = sMessage + 1; else v4 = sMessage[1]; current_character = *(v4 + _c_); if ( current_character == 'f' && arg_i < (*(args + 16) - *(args + 12)) / 28 ) { if ( v49 ) v3 = v50; else v3 = 0; v17 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v16 = *(args + 12) + 28 * v17; ++arg_i; if ( *(v16 + 24) < 0x10u ) sub_287790(v3, (v16 + 4)); else sub_287790(v3, *(v16 + 4)); } } } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v12 = sMessage + 1; else v12 = sMessage[1]; current_character = *(v12 + _c_); if ( current_character == 'd' && arg_i < (*(args + 16) - *(args + 12)) / 28 ) { if ( v49 ) v11 = v50; else v11 = 0; v39 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v38 = *(args + 12) + 28 * v39; ++arg_i; if ( *(v38 + 24) < 0x10u ) sub_287790(v11, (v38 + 4)); else sub_287790(v11, *(v38 + 4)); } } break; case 'd': if ( arg_i < (*(args + 16) - *(args + 12)) / 28 ) { v35 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v32 = *(args + 12) + 28 * v35; v34 = 1; v48 = sub_28ACD0(v32, v33, 1); ++arg_i; (sub_283330)(v48); } break; case 'l': if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v9 = sMessage + 1; else v9 = sMessage[1]; current_character = *(v9 + _c_); if ( current_character == 'l' ) { if ( ++_c_ < sMessage_size ) { if ( sMessage[5] <= _c_ ) sub_56B930(); if ( sMessage[6] < 0x10u ) v8 = sMessage + 1; else v8 = sMessage[1]; current_character = *(v8 + _c_); if ( current_character == 'd' && arg_i < (*(args + 16) - *(args + 12)) / 28 ) { v23 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v20 = *(args + 12) + 28 * v23; v22 = 1; v45 = sub_28B0A0(v20, v21, 1); ++arg_i; sub_283C00(v45, HIDWORD(v45)); } } } else if ( current_character == 'u' && arg_i < (*(args + 16) - *(args + 12)) / 28 ) { v27 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v24 = (*(args + 12) + 28 * v27); v26 = 1; v46 = sub_28AF80(v24, v25, 1); ++arg_i; sub_283930(v46); } } break; case 's': if ( arg_i < (*(args + 16) - *(args + 12)) / 28 ) { if ( v49 ) v10 = v50; else v10 = 0; v37 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v36 = *(args + 12) + 28 * v37; ++arg_i; if ( *(v36 + 24) < 0x10u ) sub_287790(v10, (v36 + 4)); else sub_287790(v10, *(v36 + 4)); } break; case 'u': if ( arg_i < (*(args + 16) - *(args + 12)) / 28 ) { v31 = arg_i; if ( arg_i >= (*(args + 16) - *(args + 12)) / 28 ) fuck_it(); v28 = *(args + 12) + 28 * v31; v30 = 1; v47 = sub_28AE60(v28, v29, 1); ++arg_i; sub_283660(v47); } break; default: v44 = 0; v56 = -1; sub_2846D0(); v51[0] = &std::ios_base::`vftable'; sub_56BA2C(v51); return v44; } } } else if ( v49 ) { sub_1B7650(v50, current_character); } else { sub_1B7650(0, current_character); } ++_c_; } v15 = sub_284BB0(v43); LOBYTE(v56) = 1; std::string::assign_0(sMessage, v15, 0, 0xFFFFFFFF); LOBYTE(v56) = 0; fuck_it_0(v43, 1, 0); v42 = 1; v56 = -1; sub_2846D0(); v51[0] = &std::ios_base::`vftable'; sub_56BA2C(v51); return v42; }
- 1
- 1
-
UPDATE:
Fix of the problem that occurred while loading files(some languages).
- 2
- 1
- 2
-
-
6.1.0.0:
+fishing.txt
+mob_drop_item.txt
+special_item_group.txt
- 3
- 1
- 1
- 1
-
-
Spoiler
- 8
- 1
-
Yes that was in my to do list but I am waiting may month to update it for some reasons.
Does one missing check make this system bad?
- 1
Official Unpacked Updates Metin2 🚫 No Spam 🚫
in Guides & HowTo
Posted · Edited by Mali
I was trying some ui tests on official.
Then I realized modules(chatm2g, playerm2g2, etc.) with the last update is not working anymore
It was work on 22.5.3 but now with 22.5.7 update, they are not working anymore.
Some Changed Module Names:
chatm2g-> kqKNavMplayerm2g2-> EPoqMjnDAGexchange-> THboFfqIime-> PYLgrpImage-> fGxVTGEkgrpText-> PDnfKAGwndMgr-> skUCjCsystemSetting-> KHIDKDuRHpAwDand more.
Not all modules have changed(app, pack, etc.)
I will also check for new versions to see if they change dynamically.
Example Working Script: