Jump to content

Ikarus_

Developer
  • Posts

    402
  • Joined

  • Last visited

  • Days Won

    20
  • Feedback

    0%

Posts posted by Ikarus_

  1. Here is wher your db is crashing:

     

      

    void CClientManager::UpdateItemCache()
    {
    	if (m_iCacheFlushCount >= m_iCacheFlushCountLimit)
    		return;
    
    	TItemCacheMap::iterator it = m_map_itemCache.begin();
    
    	while (it != m_map_itemCache.end())
    	{
    		CItemCache * c = (it++)->second;
    
    		
    		if (c->CheckFlushTimeout()) // Boom right here
    		{
    			if (g_test_server)
    				sys_log(0, "UpdateItemCache ==> Flush() vnum %d id owner %d", c->Get()->vnum, c->Get()->id, c->Get()->owner);
    
    			c->Flush();
    
    			if (++m_iCacheFlushCount >= m_iCacheFlushCountLimit)
    				break;
    		}
    	}
    }

     

     

    It make me think you are getting dangling pointers in your cache map.
    It's impossible to me to give you an exact cause of why your cache looks corrupted.

    You can read more about dangling pointers here.

     

     

  2. On 1/18/2017 at 8:14 AM, DarkOne said:

    Here is another method of fixing the same problem. With this method, one can change the ip in the config files.Both of these methods take like 30 secs or so to show a connection after starting the server. So lets begin.

     

    In Config Auth,Ch's,Game99 Use

    CONNECTION_IP: Your Wan IP

    Game\config.cpp

    Go to line 56 and add:

    
    char        g_ipfix[16] = "0";

    Go to the 1169 line and add:
     

    
    TOKEN("connection_ip")
         {
           strlcpy(g_ipfix, value_string, sizeof(g_ipfix));
         }

    Game \ config.h

    Go to line 56 and add:

    
    extern char     g_ipfix[16];

    Game\desc_client.cpp

    Go to line 149 and replace:

    
    memcpy(p.szIP, g_szPublicIp, 16);

    with:

    
    memcpy(p.szIP, g_ipfix, 16);

    Go to line 159 and replace:

    
    strlcpy (p.szPublicIP, g_szPublicip, sizeof (p.szPublicIP));

    with:

    
    strlcpy(p.szPublicIP, g_ipfix, sizeof(p.szPublicIP));

    Compile and your done. Just put CONNECTION_IP: Your Wan IP in your configs and your done.

    Credit goes to Arves100

     

    You shouldn't use line number in your tutorials, they are as you list them only in your source code.

  3. I can't tell you how to solve it, i can just try to explain you what's happen here:
     

    LUA_ERROR: locale/hungary/quest/object/state/mb_igshop:984: attempt to call field `give_item_with' (a nil value)

     

    The Error is saying us that a quest is calling give_item_with (i guess you might find it as pc.give_item_with) which is not defined in the module (it might be pc module) and the attempt to call it returned a nil value (because can't find its function body defined). 
    The way to solve it is to define the body of the function.

    Usually the lua modules are defined by passing a function table e.g. here we have:

     

    void RegisterPCFunctionTable()
    {
      luaL_reg pc_functions[] =
        {
        { "get_wear",		pc_get_wear			},
        { "get_player_id",	pc_get_player_id	},
        { "get_account_id", pc_get_account_id	},
        { "get_account",	pc_get_account		},
        //[........]
        //[........]
        //[........]			
        { NULL,			NULL			}
      };
    
      CQuestManager::instance().AddLuaFunctionTable("pc", pc_functions);
    }

     

    As you can see here we have a list of methods defined by giving them a name (callable from lua) and a definition which is defined in the .cpp file (e.g. questlua_pc.cpp)

     

    Conclusion is that you need to define your function which is giving you that error and to add it to the appropriate function table.

    • Love 1
  4. On 10/27/2020 at 1:11 PM, Ikarus_ said:

    Warning : Here it is adding the name of the character independently on the chat type, so take care of check the type of chat before to add the level of the player (if you really want to add it only on guild chat).

    As you can see here, i ve explained you right here to warn you about your issue kek

    You may just add a if else like this:

     

    if (CHAT_TYPE_GUILD == pinfo->type)
    {
    	// do stuff for guild chat
    }
    
    else
    {
    	// do stuff as default
    }

     

     

    • Love 1
  5. By searching into the source server, i ve found where the chat packet is received from the player, and sent to the guild members.

    int CInputMain::Chat(LPCHARACTER ch, const char * data, size_t uiBytes)

    here is where it is adding the name of the player to the chat text before to send it to guild members.
    You might not find the chat color system part.
     

    
    	char chatbuf[CHAT_MAX_LEN + 1];
    #ifdef ENABLE_CHAT_COLOR_SYSTEM
    	// static const char* colorbuf[] = {" |h|r[ãÑÇÞÈ]|cFFffa200|h", " |h|r[ÔíäÓæ]|cFFff0000|h", " |h|r[ÔæäÌæ]|cFFffc700|h", " |h|r[Ìíäæ]|cFF000bff|h"}; // Arab
    	static const char* colorbuf[] = {"|cFFffa200|H|h[Staff]|h|r", "|cFFff0000|H|h[Shinsoo]|h|r", "|cFFffc700|H|h[Chunjo]|h|r", "|cFF000bff|H|h[Jinno]|h|r"};
    	int len = snprintf(chatbuf, sizeof(chatbuf), "%s %s : %s", (ch->IsGM()?colorbuf[0]:colorbuf[MINMAX(0, ch->GetEmpire(), 3)]), ch->GetName(), buf);
    #else
    	int len = snprintf(chatbuf, sizeof(chatbuf), "%s : %s", ch->GetName(), buf);
    #endif

     

    Warning : Here it is adding the name of the character independently on the chat type, so take care of check the type of chat before to add the level of the player (if you really want to add it only on guild chat).

    • Love 1
  6. On 7/7/2018 at 11:47 AM, Heathcliff™ said:

    Thank you for this release, but it has a small bug. Make your GM character invisible, then zoom in your chatracter. You will se your character all it effects like GM logo, and skill effects. Then use Ninja hiding skill, and make this camera movement again with another character next to the ninja char. You will see the armor effects on the ninja :)

     

     

    • Metin2 Dev 1
  7.  

     

    252709OrangeWarning.pngWARNING: If your teleporter panel in lua doesn't use pc.can_warp you must add it obv !  It's important to check if a player can warp using pc.can_warp before to call pc.warp

     

     

     

     

     

    Hello community,

     

    I have always seen people go crazy for this problem which is solved with 2 lines of code, in particular with the various offlineshops (mine, or the free release great and ken) that are unfairly blamed for having duplication bugs. No!


    I believe that if you warp a player on another core without performing any checks you can't blame those who made the other systems which are then used to take advantage of the vulnerability you caused.


    If you implement something you need to make sure there are adequate checks to avoid causing vulnerabilities. In my opinion the cause of the duplication is not the various offlineshops, but the channel switcher which does not perform not even half checks before executing the warp.

     

    Anyway, no more chatter.
    I will explain here how to fix this problem.

     

    The first thing to check is if the channel switcher is using CHARACTER :: CanWarp to check if the player can be connected on a new channel or not.

     

    here i wanna paste a commonly seen function channel switcher to connect the player (char.cpp):
     

    
    void CHARACTER::ChannelSwitch(int iNewChannel){
        long lAddr;
        long lMapIndex;
        WORD wPort;
        long x = this->GetX();
        long y = this->GetY();
    
        if (!CMapLocation::instance().Get(x, y, lMapIndex, lAddr, wPort))
        {
            return;
        }
    
        if(lMapIndex >= 10000){
            return;
        }
    
        std::map<WORD, int>ch;
    
        for(int i = 0; i < 4; i++){
            for(int i2 = 1; i2 < 9; i2++){
                ch[30*1000 + i*100 + i2] = i+1;
            }
        }
        int chan;
        if(ch.find(wPort) != ch.end()){
            chan = ch[wPort];
        }else{return;}
        Stop();
        Save();
    
        if(GetSectree()){
            GetSectree()->RemoveEntity(this);
            ViewCleanup();
    
            EncodeRemovePacket(this);
        }
    
        TPacketGCWarp p;
        p.bHeader    = HEADER_GC_WARP;
        p.lX    = x;
        p.lY    = y;
        p.lAddr    = lAddr;
        p.wPort    = (wPort - 100*(chan-1) + 100*(iNewChannel-1));
    
        GetDesc()->Packet(&p, sizeof(TPacketGCWarp));
    }


    How you can see, no checks are performed to check if the character are using any systems which may give problems.

    So Here what we need is to add CanWarp check at the beginning of the method.

     

    void CHARACTER::ChannelSwitch(int iNewChannel){
        //* START DUPLICATION FIX
        //* prevent problems about duplication of items
        //* using safebox/exchange/shop/acce
        if(!CanWarp()){
          return;
        }
        //* END DUPLICATION FIX
    
        long lAddr;
        long lMapIndex;
        WORD wPort;
        long x = this->GetX();
        long y = this->GetY();
    
        if (!CMapLocation::instance().Get(x, y, lMapIndex, lAddr, wPort))
        {
          return;
        }
    
        if(lMapIndex >= 10000){
          return;
        }
    
        std::map<WORD, int>ch;
    
        for(int i = 0; i < 4; i++){
          for(int i2 = 1; i2 < 9; i2++){
            ch[30*1000 + i*100 + i2] = i+1;
          }
        }
        int chan;
        if(ch.find(wPort) != ch.end()){
          chan = ch[wPort];
        }else{return;}
        Stop();
        Save();
    
        if(GetSectree()){
          GetSectree()->RemoveEntity(this);
          ViewCleanup();
    
          EncodeRemovePacket(this);
        }
    
        TPacketGCWarp p;
        p.bHeader    = HEADER_GC_WARP;
        p.lX    = x;
        p.lY    = y;
        p.lAddr    = lAddr;
        p.wPort    = (wPort - 100*(chan-1) + 100*(iNewChannel-1));
    
        GetDesc()->Packet(&p, sizeof(TPacketGCWarp));
    }

     

    This is enoght to solve 100% of the problems if your CanWarp is a complete check about all your system installed.

    If not, you just need to adapt CanWarp with the systems you have installed.
    I will make an example with my offlineshop so that the speech is clear to anyone.

     

     

    Let's take a look to the Default CanWarp method.
    The first thing to note is that its purpose is obviously to return true if the player is able to reconnect without any problems.

     

    
    bool CHARACTER::CanWarp() const
    {
    	const int iPulse = thecore_pulse();
    	const int limit_time = PASSES_PER_SEC(g_nPortalLimitTime);
    
    	if ((iPulse - GetSafeboxLoadTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetExchangeTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetMyShopTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetRefineTime()) < limit_time)
    		return false;
    
    	if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen())
    		return false;
    	return true;
    }

     

    How you can see here you can find a lot of checks which they are checking the last time of every auction may be used to take exploit the warp.
    What we need to do here is to add new checks, to cover all the systems installed and fix all vulnerabilities.

     

    An example about an offlineshop would be:
     

    bool CHARACTER::CanWarp() const
    {
    	const int iPulse = thecore_pulse();
    	const int limit_time = PASSES_PER_SEC(g_nPortalLimitTime);
    
    	if ((iPulse - GetSafeboxLoadTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetExchangeTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetMyShopTime()) < limit_time)
    		return false;
    
    	if ((iPulse - GetRefineTime()) < limit_time)
    		return false;
    
    	if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen())
    		return false;
    
    #ifdef __ENABLE_NEW_OFFLINESHOP__
    	if (iPulse - GetOfflineShopUseTime() < limit_time)
    		return false;
    
    	if (GetOfflineShopGuest() || GetAuctionGuest())
    		return false;
    #endif
    
    	return true;
    }

     

     

    Note: I m using GetOfflineShopGuest and GetAuctionGuest which are methods used on my shop to get the pointer to the opened offlineshop/auction but if you are using another offlineshop system you need to find the equivalent way to check if the player is guest into a offline shop.

    The method GetOfflineShopUseTime is a new method which i m implementing to check the last use time of the system.

    Let's see how to implement it (char.cpp)

     

    //SEARCH 
    		void			ResetStopTime();
    		DWORD			GetStopTime() const;
    
    //ADD UNDER 
    
    #ifdef __ENABLE_NEW_OFFLINESHOP__
      public:
    		int			GetOfflineShopUseTime() const {return m_iOfflineShopUseTime;}
    		void			SetOfflineShopUseTime(){m_iOfflineShopUseTime = thecore_pulse();}
    
      private:
    		int			m_iOfflineShopUseTime = 0;
    #endif

     

    Here we are instantiating a new int where we can store the current time when player use the systemUsing SetOfflineShopUseTime the method will update the value of m_iOfflineShopUseTime and using GetOfflineShopUseTime we can check the last time player used the system (as done into CanWarp).

     

    What's missing to do?
    We need to use SetOfflineShopUseTime where the player is using our offlineshop (buy item, open shop, edit shop, close shop, ecc.) , so that the last use time is actually updated when needed, making the check in can warp effective.

    A similar check can be done for other systems (eg acce system) to make our CanWarp safer and more effective.


    I hope it's usefull.
    Bye ;)

    • Metin2 Dev 1
    • Good 1
    • Love 21
  8. are you trying to freeze the game? xd
    what is this check ? 0 to 100k for vid it's a slow way to check the nearest characters.

    you could make a new method in CPythonCharacterManager to get what you need, rather than use your way.

    you could iterate all the character instances rather than iterate a number from 0 to 100.000 using the GetInstancePtr 100.000 times (which is a find into a map, which is slower than iterating the directly the map)

  9. Spoiler

     i guess i ve found the problem but since i ve just read the code i can't test it.

     

    Let me know

     

    
    //SEARCH
    			else
    			{
    				if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1))
    				{
    					owner = this;
    
    					if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
    					{
    						owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼ÒÁöÇÏ°í ÀÖ´Â ¾ÆÀÌÅÛÀÌ ³Ê¹« ¸¹½À´Ï´Ù."));
    						return false;
    					}
    				}
    			}
    
    			item->RemoveFromGround();
    
    			if (item->IsDragonSoul())
    				item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
    #ifdef ENABLE_SPECIAL_STORAGE
    			else if (item->IsSpecialStorageItem())
    				item->AddToCharacter(this, TItemPos(item->GetSpecialWindowType(), iEmptyCell));
    #endif
    
    
    
    
    //REPLACE WITH
    			else
    			{
    				if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1))
    				{
    					owner = this;
    
    					if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
    					{
    						owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼ÒÁöÇÏ°í ÀÖ´Â ¾ÆÀÌÅÛÀÌ ³Ê¹« ¸¹½À´Ï´Ù."));
    						return false;
    					}
    				}
    			}
    
    			item->RemoveFromGround();
    
    			if (item->IsDragonSoul())
    				item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
    #ifdef ENABLE_SPECIAL_STORAGE
    			else if (item->IsSpecialStorageItem())
    				item->AddToCharacter(owner, TItemPos(item->GetSpecialWindowType(), iEmptyCell));
    #endif

     

     

     

     

    in short:
    spacer.png

     

     

     

    mmmh i m sorry for reposting the solution which is already written, the page was looking not correctly loaded and i ve not read it 

  10. Hi guys,

     

    A guy reported to me a weird bug about shamans w/m which are skipping collision when they are too fast to attack.

    On default source files it is still an unresolved bug which appear when the shaman's attack speed is more than 145/150.

     

    here a video which show how it is not getting the damage text for each hit on the stone.

     

     

    here the

    This is the hidden content, please
    .

     

    Spoiler

     

    ActorInstance.h 


    //search:

    protected:
            void __RunNextCombo();
            void __ClearCombo();
            void __OnEndCombo();
    
            void __ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill = 0, BOOL isSendPacket = TRUE);
            void __ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim);
            void __ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim);


    //add under

    #ifdef __ENABLE_SHAMAN_ATTACK_FIX__
            float __GetInvisibleTimeAdjust(const UINT uiSkill, const NRaceData::TAttackData& c_rAttackData);
    #endif


    ActorInstanceBattle.cpp

     

    //search : 

    void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket)
    {
        if (NRaceData::HIT_TYPE_NONE == c_rAttackData.iHittingType)
            return;
    
        InsertDelay(c_rAttackData.fStiffenTime);
    
        if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f)
        {
            __PushCircle(rVictim);
    
            // VICTIM_COLLISION_TEST
            const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
            rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
    
            // VICTIM_COLLISION_TEST_END
        }
    
        // Invisible Time
        if (IS_PARTY_HUNTING_RACE(rVictim.GetRace()))
        {
            if (uiSkill) // ÆÄƼ »ç³É ¸ó½ºÅÍ¶óµµ ½ºÅ³ÀÌ¸é ¹«Àû½Ã°£ Àû¿ë
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
    
            if (m_isMain) // #0000794: [M2KR] Æú¸®¸ðÇÁ - ¹ë·±½Ì ¹®Á¦ ŸÀÎ °ø°Ý¿¡ ÀÇÇÑ ¹«Àû ŸÀÓÀº °í·ÁÇÏÁö ¾Ê°í ÀڽŠ°ø°Ý¿¡ ÀÇÇѰ͸¸ üũÇÑ´Ù
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
        }
        else // ÆÄƼ »ç³É ¸ó½ºÅÍ°¡ ¾Æ´Ò °æ¿ì¸¸ Àû¿ë
        {
            rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
        }

    //make it like this: (take a look where __ENABLE_SHAMAN_ATTACK_FIX__ is used)

    void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket)
    {
        if (NRaceData::HIT_TYPE_NONE == c_rAttackData.iHittingType)
            return;
    
        InsertDelay(c_rAttackData.fStiffenTime);
    
        if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f)
        {
            __PushCircle(rVictim);
    
            // VICTIM_COLLISION_TEST
            const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
            rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
    
            // VICTIM_COLLISION_TEST_END
        }
    
    #ifdef __ENABLE_SHAMAN_ATTACK_FIX__
        // Invisible Time
        if (IS_PARTY_HUNTING_RACE(rVictim.GetRace()))
        {
            if (uiSkill) // ÆÄƼ »ç³É ¸ó½ºÅÍ¶óµµ ½ºÅ³ÀÌ¸é ¹«Àû½Ã°£ Àû¿ë
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + (c_rAttackData.fInvisibleTime - __GetInvisibleTimeAdjust(uiSkill, c_rAttackData));
    
            if (m_isMain) // #0000794: [M2KR] Æú¸®¸ðÇÁ - ¹ë·±½Ì ¹®Á¦ ŸÀÎ °ø°Ý¿¡ ÀÇÇÑ ¹«Àû ŸÀÓÀº °í·ÁÇÏÁö ¾Ê°í ÀڽŠ°ø°Ý¿¡ ÀÇÇѰ͸¸ üũÇÑ´Ù
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + (c_rAttackData.fInvisibleTime - __GetInvisibleTimeAdjust(uiSkill, c_rAttackData));
        }
        else // ÆÄƼ »ç³É ¸ó½ºÅÍ°¡ ¾Æ´Ò °æ¿ì¸¸ Àû¿ë
        {
            rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + (c_rAttackData.fInvisibleTime - __GetInvisibleTimeAdjust(uiSkill, c_rAttackData));
        }
    #else
        // Invisible Time
        if (IS_PARTY_HUNTING_RACE(rVictim.GetRace()))
        {
            if (uiSkill) // ÆÄƼ »ç³É ¸ó½ºÅÍ¶óµµ ½ºÅ³ÀÌ¸é ¹«Àû½Ã°£ Àû¿ë
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
    
            if (m_isMain) // #0000794: [M2KR] Æú¸®¸ðÇÁ - ¹ë·±½Ì ¹®Á¦ ŸÀÎ °ø°Ý¿¡ ÀÇÇÑ ¹«Àû ŸÀÓÀº °í·ÁÇÏÁö ¾Ê°í ÀڽŠ°ø°Ý¿¡ ÀÇÇѰ͸¸ üũÇÑ´Ù
                rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
        }
        else // ÆÄƼ »ç³É ¸ó½ºÅÍ°¡ ¾Æ´Ò °æ¿ì¸¸ Àû¿ë
        {
            rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
        }
    #endif
    
        // Stiffen Time
        rVictim.InsertDelay(c_rAttackData.fStiffenTime);

    //at the end of the file paste:

    #ifdef __ENABLE_SHAMAN_ATTACK_FIX__
    float CActorInstance::__GetInvisibleTimeAdjust(const UINT uiSkill, const NRaceData::TAttackData& c_rAttackData) {
    
        static const int shamanw = 3, shamanm = 7;
    
        if ((GetRace() != shamanw && GetRace() != shamanm) ||
            uiSkill != 0 ||
            m_fAtkSpd < 1.3)
            return 0.0f;
    
        const auto scale = (m_fAtkSpd - 1.3) / 1.3;
        const auto inv = c_rAttackData.fInvisibleTime * 0.5;
        return inv * scale;
    }
    #endif

     

     

     

    ATTENTION:
    Since the problem is the InvisibleTime on Attack.msa which it is too high, we could think to reduce it without need to edit nothing in our source (and it may be more efficient), but honestly i preferred to make a function which calculating the "adjustment" of the invisible time using the speed attack to don't risk to get the reversed problem (2 damage on 1 hit when the attack speed is low)

    feel free to use one of the two options.

     

     

    • Metin2 Dev 117
    • Eyes 3
    • Facepalm 1
    • Dislove 1
    • Angry 1
    • Confused 3
    • Lmao 1
    • Good 28
    • Love 7
    • Love 80
  11. 3 hours ago, 3bd0 said:

    This worked! I copied all the devil libs from the 9.2 machine and compiled it and its working now perfectly! Will try to upgrade it later.

     

    I am guessing the static flag makes the linker pack every library needed into the binary, which makes it work on every machine even if that library is not installed, am I right?

    Is there any disadvantages to using the static flag vs dynamic linking?

    Yes, the static linking links the whole code.

    Sometimes static linking could conflict when the machines are not using the same OS but very rarely.

     

    Why did moderator removed my message with the libs list? lol
    btw good luck with ur work bye bye

  12. Visual studio has an option "attach to process" in "Debug" section of the menù near the top of the window.

    So you can attach the debugger to the process is running in ur client.

    If you don't get a correct "crash dump" because the debugger is saying "no symbols loaded" you must set "generate debug information" on your UserInterface Linker/Debug properties

     

    Martysama has a tutorial to make it on his web-site/github profile

    This is the hidden content, please

    • Metin2 Dev 139
    • kekw 3
    • Eyes 1
    • Facepalm 1
    • Angry 2
    • Not Good 1
    • Sad 2
    • Cry 1
    • Think 1
    • Confused 3
    • Good 21
    • Love 7
    • Love 63
×
×
  • 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.