Jump to content

Mali

Honorable Member
  • Posts

    919
  • Joined

  • Days Won

    888
  • Feedback

    100%

Posts posted by Mali

  1. 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:

    Spoiler
    • chatm2g -> kqKNavM
    • playerm2g2 -> EPoqMjnDAG
    • exchange -> THboFfqI
    • ime -> PYL
    • grpImage -> fGxVTGEk
    • grpText -> PDnfKAG
    • wndMgr -> skUCjC
    • systemSetting -> KHIDKDuRHpAwD

    and 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:

    Spoiler
    # import chatm2g as chat
    # import playerm2g2 as player
    import kqKNavM as chat
    import EPoqMjnDAG as player
    
    name = player.GetName()
    chat.AppendChat(chat.CHAT_TYPE_INFO, "my name is {}".format(name))

     

     

    • Metin2 Dev 11
    • Think 1
    • Scream 1
    • Lmao 2
    • Good 4
    • Love 2
    • Love 9
  2. 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

     

     

    My topics

     

  3. 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

    • Love 1
  4. 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

    .png

    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

  5. 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❤️

  6. 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.

    • Metin2 Dev 1
    • Good 1
    • Love 2
    • Love 1
  7. Video: 

     

     

    Added to the game with this update:

    .png

     

    You need this function to use it:

    .png

     

    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.

    • Metin2 Dev 17
    • Good 4
    • Love 1
    • Love 12
  8. 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:

    .png

    • Good 1
    • Love 1
  9. 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.

  10. 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:

    Spoiler
    bool 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;
    }

     

     

    • Good 1
    • Love 1
×
×
  • 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.