Jump to content

Abel(Tiger)

Active+ Member
  • Posts

    196
  • Joined

  • Last visited

  • Days Won

    14
  • Feedback

    0%

Abel(Tiger) last won the day on July 14 2018

Abel(Tiger) had the most liked content!

4 Followers

About Abel(Tiger)

  • Birthday 04/09/1998

Informations

  • Gender
    Male
  • Country
    Romania
  • Nationality
    Romanian

Social Networks

  • Discord
    Mr. Tiger#1267

Recent Profile Visitors

3322 profile views

Abel(Tiger)'s Achievements

Proficient

Proficient (10/16)

  • Dedicated
  • Reacting Well
  • Very Popular Rare
  • First Post
  • Collaborator

Recent Badges

1.1k

Reputation

  1. You don't need to train it on your source code. You just need to take a good model and give it more context. For example I use Github Copilot to help me with some trivial task while coding. If I need info about the whole source I just use @workspace in the chat when I ask it a question and then he has more context about the source.
  2. You can install it in rescue mode like this: (this is a workaround and is not the best way) 1. Buy the vps 2. Restart in rescue mode 3. get the data from email and login using winscp 4. run command: wipefs -a /dev/sdb 5. run command: wget [Hidden Content] 6. run command: xz -dc FreeBSD-12.4-RELEASE-i386.raw.xz | dd of=/dev/sdb bs=1M 7. run command: reboot vps Please note this is an already configured freebsd image and it might not be the way you will configure it. If you want to do a clean install (didn't try this yet) I guess you can just mount the install image from here [Hidden Content]
  3. Everyone has this "problem". The problem is in uiShop.py in the function def SellAttachedItem. if item.IsAntiFlag(item.ANTIFLAG_SELL): popup = uiCommon.PopupDialog() popup.SetText(localeInfo.SHOP_CANNOT_SELL_ITEM) popup.SetAcceptEvent(self.__OnClosePopupDialog) popup.Open() self.popup = popup return Add a mouseModule.mouseController.DeattachObject() before the popup appears like this: if item.IsAntiFlag(item.ANTIFLAG_SELL): mouseModule.mouseController.DeattachObject() popup = uiCommon.PopupDialog() popup.SetText(localeInfo.SHOP_CANNOT_SELL_ITEM) popup.SetAcceptEvent(self.__OnClosePopupDialog) popup.Open() self.popup = popup return
  4. what if I just edit the pack before opening the client
  5. Hello, As the title says, there is a significant exploit in the chat link system. Given that many servers utilize this system, I believe most private servers are affected by this exploit. Essentially, someone can execute any CMD command they want on a player's computer by instructing them to click on an item. How does it work? [Hidden Content] He sends this through whisper or public chat, and the player clicks on the item. The command opens notepad.exe. How can you fix it? Firstly, STOP using os.system to open links. There are special libraries for that, such as the one I will use to implement this fix. Please note that this is a straightforward fix and may not be 100% foolproof because malicious links can still be sent to open in the browser. I recommend using a link validation technique on the server side and allowing only specific links. [Hidden Content]
  6. Hello, Today I will present you two new features for affect. Real time affects: Long time ago a client of mine wanted some of his affects to be real time. As you may know the affects in metin2 are consumed only if you are online (except premium, but that is another story). The easier way to achieve this was to create a new variable inside the affect called bIsRealTime, set it to 1 and store the duration as unix time instead of seconds. You can use this new functionality by adding True at the end of the AddAffect function call and everything will work automaticaly. Update affect: In a version some time ago the official servers added this new functionality to only update an affect. This is used for the Summer Event Roulette minigame to update the collected souls count in real time in client. I didn't create a easy way to use this because it depends on what you update for the affect. Here is an example of how I used it on this event to update lApplyValue: CAffect * pAffect = pkChar->FindAffect(AFFECT_LATE_SUMMER_EVENT_BUFF); if(pAffect) { pAffect->lApplyValue += 1; pAffect->bIsUpdate = true; // Update the client SendAffectAddPacket(pkChar->GetDesc(), pAffect); } Download link: [Hidden Content]
  7. 5 loading images made full hd with Photoshop Beta new Generative AI: [Hidden Content]
  8. This is a nasty bug where a boss can throw you inside a wall if he hits you with a skill that has SKILL_FLAG_CRUSH or SKILL_FLAG_CRUSH_LONG. // char_skill.cpp // Search: if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_CRUSH | SKILL_FLAG_CRUSH_LONG) && !IS_SET(pkChrVictim->GetAIFlag(), AIFLAG_NOMOVE)) { ... } // Replace the if with: if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_CRUSH | SKILL_FLAG_CRUSH_LONG) && !IS_SET(pkChrVictim->GetAIFlag(), AIFLAG_NOMOVE)) { float fCrushSlidingLength = 200; if (m_pkChr->IsNPC()) fCrushSlidingLength = 400; if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_CRUSH_LONG)) fCrushSlidingLength *= 2; float fx, fy; float degree = GetDegreeFromPositionXY(m_pkChr->GetX(), m_pkChr->GetY(), pkChrVictim->GetX(), pkChrVictim->GetY()); if (m_pkSk->dwVnum == SKILL_HORSE_WILDATTACK) { degree -= m_pkChr->GetRotation(); degree = fmod(degree, 360.0f) - 180.0f; if (degree > 0) degree = m_pkChr->GetRotation() + 90.0f; else degree = m_pkChr->GetRotation() - 90.0f; } GetDeltaByDegree(degree, fCrushSlidingLength, &fx, &fy); long startX = (long)(pkChrVictim->GetX()); long startY = (long)(pkChrVictim->GetY()); long endX = (long)(pkChrVictim->GetX() + fx); long endY = (long)(pkChrVictim->GetY() + fy); // We asume all positions between the start and end point are movable bool allPositionsMovable = true; // Calculate the distance between the start and end points double distance = std::sqrt((endX - startX) * (endX - startX) + (endY - startY) * (endY - startY)); // Calculate the step size for each coordinate double stepX = (endX - startX) / distance; double stepY = (endY - startY) / distance; // Check if all points on the trajectory between startX, startY and endX, endY are movable for (double i = 0; i <= distance; ++i) { double currentX = startX + i * stepX; double currentY = startY + i * stepY; long roundedX = static_cast<long>(std::round(currentX)); long roundedY = static_cast<long>(std::round(currentY)); if (!SECTREE_MANAGER::instance().IsMovablePosition(pkChrVictim->GetMapIndex(), roundedX, roundedY)) { allPositionsMovable = false; break; } } if (allPositionsMovable) { sys_log(0, "CRUSH SUCCESS! %s -> %s (%d %d) -> (%d %d)", m_pkChr->GetName(), pkChrVictim->GetName(), pkChrVictim->GetX(), pkChrVictim->GetY(), (long)(pkChrVictim->GetX()+fx), (long)(pkChrVictim->GetY()+fy)); pkChrVictim->Sync(endX, endY); pkChrVictim->Goto(endX, endY); pkChrVictim->CalculateMoveDuration(); } else { sys_log(0, "CRUSH FAIL! %s -> %s (%d %d) -> (%d %d)", m_pkChr->GetName(), pkChrVictim->GetName(), pkChrVictim->GetX(), pkChrVictim->GetY(), (long)(pkChrVictim->GetX()+fx), (long)(pkChrVictim->GetY()+fy)); } if (m_pkChr->IsPC() && m_pkChr->m_SkillUseInfo[m_pkSk->dwVnum].GetMainTargetVID() == (DWORD) pkChrVictim->GetVID()) { SkillAttackAffect(pkChrVictim, 1000, IMMUNE_STUN, m_pkSk->dwVnum, POINT_NONE, 0, AFF_STUN, 4, m_pkSk->szName); } else { if (allPositionsMovable) pkChrVictim->SyncPacket(); } }
  9. There is a nasty bug where sometimes some items are not loaded in the safebox. This problem occurs because the function that interprets the data from the set packet (RecvSafeBoxSetPacket) is called too early. Fix: // PythonNetworkStream.cpp // 1. Search: Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); // 1. Replace with: Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet2), STATIC_SIZE_PACKET));
  10. If you use the code from the leaked Rubinum source, it does not mean you have solved the problem. Also, if you use modern coding techniques from C++ new standards, it does not mean all the code will fix itself. Your vector is still sorted, and the pointer in the map is still pointing to the old vector position. Add this code after the std::sort, and you will be surprised: for (auto it = m_map_itemTableByVnum.begin(); it != m_map_itemTableByVnum.end(); ++it) { DWORD key = it->first; // Access the key TItemTable* value = it->second; // Access the value if(value->dwVnum != key) { sys_err("Map Key %u --- Value vnum %u", key, value->dwVnum); } }
  11. Check if the FOXFS_MAGIC of the packer is the same with the FOXFS_MAGIC of the client.
  12. 1. The fix I posted is done because you can spam the database with queries. 2. With your "fix" you can delete all coments from the guild with no permissions :)))
  13. Hello, As you may already be aware, the official source code that was leaked some time ago includes code for saving window status. The code is designed to save various window attributes such as visibility, minimized status, x and y coordinates, and height. However, I have made some adjustments to only save the x and y coordinates. Please note that the logic I have utilized is different from the original planned approach. In order to ensure the proper functioning of the save function, it is imperative to address an issue where the function is called too late and the interfacehandler is null: ## 1. Open UserInterface/PythonSystem.cpp ## 1. Replace the following function: void CPythonSystem::SaveInterfaceStatus() { ... } ## 1. With: void CPythonSystem::SaveInterfaceStatus() { if(m_poInterfaceHandler) // This will always be null when this function is called PyCallClassMemberFunc(m_poInterfaceHandler, "OnSaveInterfaceStatus", Py_BuildValue("()")); FILE* File; File = fopen("interface.cfg", "wb"); if(!File) { TraceError("Cannot open interface.cfg"); return; } fwrite(m_WindowStatus, 1, sizeof(TWindowStatus) * WINDOW_MAX_NUM, File); fclose(File); } Now, let's explore how we can save window attributes, specifically for the inventory window as an example: ## 1. Go to interfaceModule.py: ## 1. Search: if self.wndInventory: self.wndInventory.Hide() self.wndInventory.Destroy() ## 1. Change it like this: if self.wndInventory: xInventory, yInventory = self.wndInventory.GetGlobalPosition() systemSetting.SaveWindowStatus(systemSetting.WINDOW_INVENTORY, False, True, xInventory, yInventory, 0) self.wndInventory.Hide() self.wndInventory.Destroy() ## 2. Now search: self.wndInventory = uiInventory.InventoryWindow() self.wndInventory.BindInterfaceClass(self) ## 2. Change it like this: self.wndInventory = uiInventory.InventoryWindow() self.wndInventory.BindInterfaceClass(self) (_, _, invX, invY, _) = systemSetting.GetWindowStatus(systemSetting.WINDOW_INVENTORY) if invX > 0 and invY > 0 and invX + self.wndInventory.GetWidth() < wndMgr.GetScreenWidth() and invY + self.wndInventory.GetHeight() < wndMgr.GetScreenHeight(): self.wndInventory.SetPosition(invX, invY) I hope you find this information useful.
  14. Hello, If you check the algorithm in char.cpp (DetermineDropMetinStone()) you will see that in some cases that is totaly posible. (for example pick randomly number 90 and folow the algorithm with the percentages from your table line 1 (40, 13, 5, 2, 0). If you look closely the last value from the table is not even used because the loop goes from 0 to 3 only (the 0 in your table). To fix this I consider the best way is to use discrete_distribution from stl: #include <random> void CHARACTER::DetermineDropMetinStone() { const int METIN_STONE_NUM = 14; static DWORD c_adwMetin[METIN_STONE_NUM] = { 28030, 28031, 28032, 28033, 28034, 28035, 28036, 28037, 28038, 28039, 28040, 28041, 28042, 28043, }; DWORD stone_num = GetRaceNum(); int idx = std::lower_bound(aStoneDrop, aStoneDrop+STONE_INFO_MAX_NUM, stone_num) - aStoneDrop; if (idx >= STONE_INFO_MAX_NUM || aStoneDrop[idx].dwMobVnum != stone_num) { m_dwDropMetinStone = 0; } else { const SStoneDropInfo & info = aStoneDrop[idx]; m_bDropMetinStonePct = info.iDropPct; std::random_device rd; std::mt19937 gen(rd()); std::discrete_distribution<> d(info.iLevelPct, info.iLevelPct + STONE_LEVEL_MAX_NUM + 1); int randomIndex = d(gen); // This will be a random number in range (0, 4) m_dwDropMetinStone = c_adwMetin[number(0, METIN_STONE_NUM - 1)] + (randomIndex * 100); } }
  15. Hello, This is because the values for hyperlink are sent as hexadecimal values (base 16) and not decimal values (base 10). You can use this converter if you want decimal values: [Hidden Content]
×
×
  • 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.