Jump to content
metin2dev

Ken

Developer
  • Content count

    805
  • Joined

  • Last visited

Everything posted by Ken

  1. open Help fopen

    std::string GetFirstLineFromFile(std::string stFileName) { std::ifstream file(stFileName.c_str(), std::ios::in); if (!file.is_open()) return "Can not open the file"; std::string stLine = ""; if (!getline(file, stLine)) return "Can not get the first line!"; return stLine; } It will get the first line of the file. You can use this anywhere you want. (Don't forget to include fstream and string libraries) Best Regards Ken
  2. Hi, everyone. Most people know when you are trying to connect the server with a lot of people, the server can not respond to you or something might go wrong. This example is same for warp too. Webzen did something about this too and I'd like to share it with you. What are exactly are we doing? If the client can not connect to the server, the client will wait one second to connect the server again. Open NetStream.cpp. Find Connect function and replace with this bool CNetworkStream::Connect(const CNetworkAddress& c_rkNetAddr, int limitSec) { Clear(); m_addr = c_rkNetAddr; m_sock = socket(AF_INET, SOCK_STREAM, 0); if (m_sock == INVALID_SOCKET) { Clear(); OnConnectFailure(); return false; } DWORD arg = 1; ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode if (connect(m_sock, reinterpret_cast<PSOCKADDR>(&m_addr), m_addr.GetSize()) == SOCKET_ERROR) { int error = WSAGetLastError(); // If something went wrong, the client will wait one second to connect the server again. // Of course, it will clear and setting up everything again. if (error != WSAEWOULDBLOCK) { Sleep(1000); Clear(); m_sock = socket(AF_INET, SOCK_STREAM, 0); if (m_sock == INVALID_SOCKET) { Clear(); OnConnectFailure(); return false; } ioctlsocket(m_sock, FIONBIO, &arg); if (connect(m_sock, reinterpret_cast<PSOCKADDR>(&m_addr), m_addr.GetSize()) == SOCKET_ERROR) { Tracen("error != WSAEWOULDBLOCK"); Clear(); OnConnectFailure(); return false; } } } m_connectLimitTime = time(NULL) + limitSec; return true; } Best Regards Ken
  3. Hi, I'd like to share a small fix about the messenger system. what exactly are we fixing? The main problem is when you remove any person from your list, the companion's messenger list is not refreshing until relog in. Webzen has fixed this situation with a small packet. That packet will provide to remove the name from the list. There is no part of Python because it's already done by Ymir. For serverside For client side Best Regards Ken
  4. open [Request]Locking items on map

    The quest must know what's there in the item shop. You can create an array for this in questlib.lua or the quest. You can use a query to fetch what's there in the item shop. (I do not recommend this method because it might be a lag in the game.) You must cache it even If you want. Then you can check it with pc.get_wear() You can create an array for this in the quest or questlib.lua (I gave an example) The last thing is to combine all of them quest xxx begin state start begin when login with pc.get_map_index() == xx begin -- You can use a query to fetch the item vnums from the table. (I still do not recommend this method if you are not using cache method) local blockedItems = { 11209, 11409, 11609, 11809 } -- Wear positions, is exist in common/length.h if you want to check it out. local wearPositions = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 20, 21, 22 } -- Make a loop and check every wear position and check is equal to the blocked items in array or not. for i = 1, table.getn(blockedItems), 1 do for j = 1, table.getn(wearPositions), 1 do if (pc.get_wear(wearPositions[j]) == blockedItems[i]) then chat("You can't..") return end end end end end end Best Regards Ken
  5. [C++] [PARTY & DUNGEON] FIX CORE

    You're playing a multiplayer game. The member might lose his connection sometimes because of the internet provider or unknown packets. You can't pay this to the party members. If you do, most people are going to insult you in the game. Anyway, thanks for sharing with us. Best Regards Ken
  6. Hey, @Horinna thanks for feeding back. About the last bug, the system is not doing the same things for the companion. To fix this; Find this line in messenger_manager.cpp m_Relation[account].erase(companion); m_InverseRelation[companion].erase(account); And add this code blog m_Relation[companion].erase(account); m_InverseRelation[account].erase(companion); Best Regards Ken
  7. A small fix about a query of messenger system. When you remove any person on your list, the companion will continue to see your name on his list (when the companion relog in the game again). This query will remove both of them's contact in the database. Best Regards Ken
  8. I've updated the codes again. Good luck
  9. open Access to the brazilian servers?

    @Johnny69 I have looked at the binary file. The only way that you must need to have a Brazil IP Address. I have thought they're blocking it with block country feature of metin2 but when I look at a bit deeper, I saw it wasn't. They're blocking the whole IP addresses on their firewall. About Xigncode - Most people are saying that it's just joke. Also, I'm thinking about why Xigncode is forcing binary to close itself. (Could be incompatible because when I watch the process on Process Hacker 2, the operating system is only running WerFault.exe) When logininfo.py (I'm not talking about loginInfo.xml) is running, it's reading locale.cfg to change something inside. (Including IP Addresses)
  10. open Access to the brazilian servers?

    I tried to ping the ip addresses but it looks like it's dead. (Including many countries). I think, there is no way to login the server without brazil ip address. Did you try to login the server with a brazil ip address?
  11. open Access to the brazilian servers?

    After @Johnny69's file, the client is working fine. The only problem is why the server is not respond to client about '..' Did you figure out or still same?
  12. open Access to the brazilian servers?

    I have the same problem at the moment. Xigncode is forcing binary to close for one reason. I have thought that they have blocked the ip addresses. However, it looks like xigncode is blocking us If I find any way, I'll let you know about it. PS1: It looks like Xigncode is incompatible with Windows 10. (That's the reason why you can't open it - I guess) The operating system is trying to stop it (Werfault.exe) when you try to open metin2client.bin. I will test the server on the other operating system.
  13. open Access to the brazilian servers?

    Can you post the brazil server's ip address and ports? I'd like to test something on it, then I can tell you. Best Regards Ken
  14. This release is just information about fish event. I just made the class from their binary files. Some functions are not still accessible yet because of define flags. class FishEventGridSlotWindow(Window): def __init__(self): Window.__init__(self) self.startIndex = 0 def __del__(self): Window.__del__(self) def RegisterWindow(self, layer): self.hWnd = wndMgr.RegisterFishEventGridSlotWindow(self, layer) def ArrangeSlot(self, startIndex, xCount, yCount, xSize, ySize, xBlank, yBlank): self.startIndex = startIndex wndMgr.ArrangeSlot(self.hWnd, startIndex, xCount, yCount, xSize, ySize, xBlank, yBlank) def GetStartIndex(self): return self.startIndex # The newest compiled binary file is not contain this function yet. (ENABLE_FISH_EVENT) def SetPickedAreaRender(self, unkArg1): pass Best Regards Ken
  15. You might right about tetris game
  16. open Safebox function C++

    I agree with you about that. You don't have to follow what exactly ymir did until now. (Except a few things). About code's readability, you can use comment line for that. About naming variables, you're right. It still depends on you. You can use it or not. Best Regards Ken
  17. open Safebox function C++

    It depends on you. In my case, pkItem is useless if you're just using that for a condition. if (ch->GetItem(p->ItemPos) && ch->GetItem(p->ItemPos)->IsEquipped()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<Storage> You can't store an equiped item.")); return; } I think, it's much better now Best Regards Ken
  18. open Safebox function C++

    LPITEM pkItem = ch->GetItem(p->ItemPos); // Make sure pkItem is not null pointer. Without that condition, the channel might down. if (pkItem && true == pkItem->IsEquipped()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<Storage> You can't store an equiped item.")); return; } Best Regards Ken
  19. open [Bug]Football

    It looks like it's still NPC. Try this 20338 ???????? Soccer 1 0 3 250 0 STUN,SLOW,CURSE,TERROR 0 bkarcher 0 0 0 0 0 0 0 1000000 10 100 0 0 10 999 100 100 0 100 5000 0 0 0 0 0 0 0 0 100 100 100 100 100 100 100 100 100 100 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Also, I looked Metin2.SG's football event. A game master send a duel for each them and starting. (I know it's manual) Best Regards Ken
  20. You need to a trigger for that to start timer in that map. It could be a login or logout or kill or pick up and so on for trigger. when login with pc.get_map_index() == xx begin server_timer("WhatEverYouCall", Number) end when WhatEverYouCall.server_timer begin regen_in_map(mapindex, path) end I just wanted to give a basic simple for you to understand. Best Regards Ken
  21. open [Bug]Football

    Metin2.SG made the football as a mob not a npc. You just need to change type of the football. Then you can attack it Best Regards Ken
  22. solved Metin2 quest compile problem

    You just have to search the function name in the files. You just need to include it in the cpp file when you found. Best Regards Ken
  23. solved Metin2 quest compile problem

    It's probably missing the library in liblua folder (liblua.a). You just have to recompile liblua again. Best Regards Ken
  24. Second fix - Description (Totally fix) Even If you don't use escape string for the companion, the function will search companion and account in the maps. If the result is not positive, the function will stop itself and write a log in syserr. Search this in messenger_manager.cpp void MessengerManager::RemoveFromList(MessengerManager::keyA account, MessengerManager::keyA companion) Replace with this void MessengerManager::RemoveFromList(MessengerManager::keyA account, MessengerManager::keyA companion) { if (companion.empty()) return; // Second fix if (m_Relation[account].find(companion) == m_Relation[account].end() || m_InverseRelation[companion].find(account) == m_InverseRelation[companion].end()) { LPCHARACTER ch = CHARACTER_MANAGER::Instance().FindPC(account.c_str()); if (ch) { sys_err("MessengerManager::RemoveFromList: %s tries to use messenger sql injection", ch->GetName()); if (ch->GetDesc()) ch->GetDesc()->DelayedDisconnect(3); } else sys_err("MessengerManager::RemoveFromList: Omg! The ghost tried to use this function!"); return; } sys_log(1, "MessengerManager::RemoveFromList: Remove %s %s", account.c_str(), companion.c_str()); DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' AND companion = '%s'", get_table_postfix(), account.c_str(), companion.c_str()); __RemoveFromList(account, companion); TPacketGGMessenger p2ppck; p2ppck.bHeader = HEADER_GG_MESSENGER_REMOVE; strlcpy(p2ppck.szAccount, account.c_str(), sizeof(p2ppck.szAccount)); strlcpy(p2ppck.szCompanion, companion.c_str(), sizeof(p2ppck.szCompanion));; P2P_MANAGER::instance().Send(&p2ppck, sizeof(TPacketGGMessenger)); } If you want to ban who tries to use this SQL injection, here is a code for you. void MessengerManager::RemoveFromList(MessengerManager::keyA account, MessengerManager::keyA companion) { if (companion.empty()) return; // Second fix if (m_Relation[account].find(companion) == m_Relation[account].end() || m_InverseRelation[companion].find(account) == m_InverseRelation[companion].end()) { LPCHARACTER ch = CHARACTER_MANAGER::Instance().FindPC(account.c_str()); if (ch) { sys_err("MessengerManager::RemoveFromList: %s tries to use messenger sql injection", ch->GetName()); DBManager::Instance().DirectQuery("UPDATE account.account SET status = 'BAN' WHERE id = %u", ch->GetAID()); if (ch->GetDesc()) ch->GetDesc()->DelayedDisconnect(3); } else sys_err("MessengerManager::RemoveFromList: Omg! The ghost tried to use this function!"); return; } sys_log(1, "MessengerManager::RemoveFromList: Remove %s %s", account.c_str(), companion.c_str()); DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' AND companion = '%s'", get_table_postfix(), account.c_str(), companion.c_str()); __RemoveFromList(account, companion); TPacketGGMessenger p2ppck; p2ppck.bHeader = HEADER_GG_MESSENGER_REMOVE; strlcpy(p2ppck.szAccount, account.c_str(), sizeof(p2ppck.szAccount)); strlcpy(p2ppck.szCompanion, companion.c_str(), sizeof(p2ppck.szCompanion));; P2P_MANAGER::instance().Send(&p2ppck, sizeof(TPacketGGMessenger)); }
  25. New Item Proto

    With new changes, webzen is added new things in item proto. The newest item proto has two new bytes and vnum range. Here is the newest item proto struct typedef struct { DWORD dwVnum; DWORD dwVnumRange; char szName[ITEM_NAME_MAX_LEN + 1]; char szLocaleName[ITEM_NAME_MAX_LEN + 1]; BYTE bType; BYTE bSubType; BYTE bWeight; BYTE bSize; DWORD dwAntiFlags; DWORD dwFlags; DWORD dwWearFlags; DWORD dwImmuneFlag; DWORD dwGold; DWORD dwShopBuyPrice; TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; TItemApply aApplies[ITEM_APPLY_MAX_NUM]; long alValues[ITEM_VALUES_MAX_NUM]; long alSockets[ITEM_SOCKET_MAX_NUM]; DWORD dwRefinedVnum; WORD wRefineSet; BYTE bAlterToMagicItemPct; BYTE bSpecular; BYTE bGainSocketPct; BYTE bMaskType; BYTE bMaskSubType; } TClientItemTable; ItemData.cpp BYTE CItemData::GetMaskType() const { return m_ItemTable.bMaskType; } BYTE CItemData::GetMaskSubType() const { return m_ItemTable.bMaskSubType; } PythonItemModule.cpp PyObject * itemGetMaskType(PyObject * poSelf, PyObject * poArgs) { CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); if (!pItemData) return Py_BuildException("no selected item data"); return Py_BuildValue("i", pItemData->GetMaskType()); } PyObject * itemGetMaskSubType(PyObject * poSelf, PyObject * poArgs) { CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); if (!pItemData) return Py_BuildException("no selected item data"); return Py_BuildValue("i", pItemData->GetMaskSubType()); } Here are the newest item proto text files. http://www.speedyshare.com/G4W3M/ItemProto.rar Best Regards Ken
×