Jump to content

blaxis

Active+ Member
  • Posts

    222
  • Joined

  • Last visited

  • Feedback

    0%

Everything posted by blaxis

  1. Hi all. From the source code, I attach a different object to an NPC or another object as ATTACH_DATA, but the connected object appears in the default position. For example; Let's say I tie a sword to an NPC's waist. However, the sword is displayed stationary and sideways. In this case, is there any way I can rotate this sword clockwise? (This was just an example, all I want to do is rotate these connected objects clockwise..) I would be glad if you could help me, good work.
  2. I'm having the same problem right now. What is the solution to this? I removed the quests.
  3. Hello, is there a tool that can automatically translate locale_game and locale_interface texts when adding a new system when there is a multi-language system? I searched but couldn't find it. There are 16 different languages..
  4. Can someone show me an example usage? How should we adapt it to other windows? For example, the task list.(in character window -> quest) Not working. As you show, the sliding process does not occur, there is visual distortion.
  5. The answer to this question is already written in the content of the topic. I recommend you read it carefully.
  6. Yes, they can be used too. However, the point I am talking about here covers all pack files, not just root. The root file does not continue the game after any editing and it gives an error and closes. But this is not the case for other pack files, the game continues even if intervention is made. Here I just presented a small idea to prevent this. Anyone can customize it as they wish and use it as a small add-on. Or he may not use it.
  7. I didn't claim that it was a great idea, those who want can convert it to SHA256 type and use it. It's just an idea. It's better than "nothing at all".
  8. Hello, I have been hearing about the existence of such an event from time to time. I thought of creating such a solution. I haven't had any problems so far in my tests. To briefly talk about the incident; Some pack files can be opened and edited while the game is open. This may pose a problem in some exceptional cases. Most of the time, changes made due to cache may not be reflected in the game unless the client is reset, but I still thought it wouldn't hurt to prevent this situation. In addition; Nowadays, foxfs etc. methods are used, so you can also consider this as additional security for your game. The codes are completely open to development and customization, you can progress them in any direction you want. I should point out that this method will work more efficiently with autopatcher. So, you also have a job to do here, the codes I share here are the first stage of this system. The necessary adjustments you will make to the autopatcher depending on these codes will be the second stage. To give an example from the working logic; As soon as the pack file named x is edited, the game will close completely, and when it is opened again, autopatcher (if there is a file integrity feature, etc.) will download the original instead of this edited pack file and allow you to log in from the original file. Likewise, if there is any intervention in the pack files again, these operations will be repeated automatically. (This is the idea I suggested, anyone can use it however they want.) Now let's get to the point.. Here's a short video showing it before editing: [Hidden Content] After video: [Hidden Content] [Hidden Content] For those who are curious; The codes run only once when the client is opened and only keep track of the pack files as long as the game (client) is open. In other words, it does not work repeatedly in situations such as teleportation or casting a character.
  9. I am the person who prepared the mentioned .dll files. Yes, it is not a very healthy method, but it is still an alternative for those who want to use it. The codes within the DLL are dynamic, meaning it implements as much MSAA as the GPU supports. If it doesn't support it, it won't apply. Device creation etc. It is applied depending on the transactions. It has no other duty.
  10. If you do this with a wrapper yes you will run into these problems. Because the wrapper is applied to many elements, including ETC. However, when done from source code, none of these problems occur. Because the wrapper doesn't know which Render does what task and applies the effect anyway. It is automatically applied to all rendering operations such as textail rendering, interface rendering, character rendering.
  11. Hello. As you know, the LibJPEG library in Metin2 is only useful for taking screenshots. Other than that, it doesn't have any duties. Those who have Directx9 and want to take better quality screenshots with this method can follow this guide carefully. Those who use Directx8 can update the code I will give according to Directx8 and try it, I did not have the chance to try it. Make sure you are determined before following the steps here. Because as a result of these operations, you will no longer have the libjpeg library, and the screenshot files will reach larger sizes than the jpg file, depending on the quality. (between 3-8MB) The explanation will be a bit complicated, but if you follow each process in order, you will not have any problems. If you still have a problem, you can report it below. First, let's get rid of libjpeg: -> Enter the Client src/extern/lib folder and delete the .lib files whose file name starts with libjpeg... -> Enter the Client src/EterLib folder and delete the JpegFile.cpp & JpegFile.h files. Open the EterLib project in Visual Studio in the same way, select these two files and remove them. -> Open the client src/EterPythonLib/PythonGraphic.cpp file and remove the following include line and functions: #include "../eterLib/JpegFile.h" --------------------------------- void GenScreenShotTag(const char* src, DWORD crc32, char* leaf, size_t leafLen){ const char* p = src; const char* n = p; while (n = strchr(p, '\\')) p = n + 1; _snprintf(leaf, leafLen, "YMIR_METIN2:%s:0x%.8x", p, crc32); } bool CPythonGraphic::SaveJPEG(const char* pszFileName, LPBYTE pbyBuffer, UINT uWidth, UINT uHeight) { return jpeg_save(pbyBuffer, uWidth, uHeight, 100, pszFileName) != 0; } -> Where you delete these, you will see this function: bool CPythonGraphic::SaveScreenShot(const char* c_pszFileName) { -> Replace this function completely like this: bool CPythonGraphic::SaveScreenShot() { LPDIRECT3DSURFACE9 lpSurface = nullptr; D3DSURFACE_DESC stSurfaceDesc = {}; uint32_t uWidth = stSurfaceDesc.Width; uint32_t uHeight = stSurfaceDesc.Height; ms_lpd3dDevice->CreateOffscreenPlainSurface(uWidth, uHeight, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &lpSurface, NULL); if (SUCCEEDED(ms_lpd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &lpSurface))) { if (!CreateDirectory("screenshot", NULL) && ERROR_ALREADY_EXISTS != GetLastError()) //yoksa oluştur return false; SYSTEMTIME st; GetSystemTime(&st); char szFileName[MAX_PATH]; sprintf_s(szFileName, "screenshot/screenshot_%04d%02d%02d_%02d%02d%02d.bmp", // eşsiz st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); D3DXSaveSurfaceToFile(szFileName, D3DXIFF_BMP, lpSurface, NULL, NULL); } else TraceError("CPythonGraphic::SaveScreenShot() - ScreenShot Basarisiz!"); // yok et if (lpSurface) { lpSurface->Release(); lpSurface = nullptr; } return true; } -> Then remove the following from the PythonGraphic.h file: bool SaveJPEG(const char* pszFileName, LPBYTE pbyBuffer, UINT uWidth, UINT uHeight); -> In the same file there will be: bool SaveScreenShot(const char* szFileName); -> Update this to: bool SaveScreenShot(); -> Open PythonGraphicModule.cpp and delete this PyObject* grpSaveScreenShot(PyObject* poSelf, PyObject* poArgs) { struct tm* tmNow; time_t ct; ct = time(0); tmNow = localtime(&ct); char szPath[MAX_PATH + 256]; SHGetSpecialFolderPath(NULL, szPath, CSIDL_PERSONAL, TRUE); //GetTempPath(); strcat(szPath, "\\METIN2\\"); if (-1 == _access(szPath, 0)) if (!CreateDirectory(szPath, NULL)) { TraceError("Failed to create directory [%s]\n", szPath); return Py_BuildValue("(is)", FALSE, ""); } sprintf(szPath + strlen(szPath), "%02d%02d_%02d%02d%02d.jpg", tmNow->tm_mon + 1, tmNow->tm_mday, tmNow->tm_hour, tmNow->tm_min, tmNow->tm_sec); BOOL bResult = CPythonGraphic::Instance().SaveScreenShot(szPath); return Py_BuildValue("(is)", bResult, szPath); } -> and delete this: { "SaveScreenShot", grpSaveScreenShot, METH_VARARGS }, -> Find the following function in the same file PyObject* grpSaveScreenShotToPath(PyObject* poSelf, PyObject* poArgs) { -> Replace this function completely with the code I gave below. PyObject* grpSaveScreenShotToPath(PyObject* poSelf, PyObject* poArgs) { CPythonGraphic::Instance().SaveScreenShot(); return Py_BuildNone(); } -> We are done with the client src. Now open root/game.py and find this function: def SaveScreen(self): print "save screen" # SCREENSHOT_CWDSAVE if SCREENSHOT_CWDSAVE: if not os.path.exists(os.getcwd()+os.sep+"screenshot"): os.mkdir(os.getcwd()+os.sep+"screenshot") (succeeded, name) = grp.SaveScreenShotToPath(os.getcwd()+os.sep+"screenshot"+os.sep) elif SCREENSHOT_DIR: (succeeded, name) = grp.SaveScreenShot(SCREENSHOT_DIR) else: (succeeded, name) = grp.SaveScreenShot() # END_OF_SCREENSHOT_CWDSAVE if succeeded: pass """ chat.AppendChat(chat.CHAT_TYPE_INFO, name + localeInfo.SCREENSHOT_SAVE1) chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SCREENSHOT_SAVE2) """ else: chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SCREENSHOT_SAVE_FAILURE) -> ..and update it like this: def SaveScreen(self): grp.SaveScreenShotToPath() You can also search and delete the variables in the original Python code above from root. I'm sorry for my bad english.
  12. Hello. Can you tell me how to solve this problem? I applied the changes you gave via visual studio and compiled it(32bit). When I tested the resulting dll file, the guild icons in the game became completely invisible. I also uploaded your lib files to the server, but it's still the same. When I select the guild icon, no .tga or anything like that is created on the server side and it does not appear in the game. I'm using bsd 13.0 - 32bit
  13. I have used and tried many wrappers like dgvodo. ReShade, GShade,dgVodo etc. None of them satisfied me. I am more in favor of solving this issue by the source. Additionally, dgvodoo increases memory usage excessively. A single client consumes between 550-650mb. Using such large memory just to enable MSAA is pointless. I've been trying for weeks and this is where I'm at now(Metin2 client source codes only )
  14. I know this. This is not a fix and it is dangerous to use it this way. Unfortunately, DirectX codes are not as simple as you think.
  15. Hello. K I'm having a little problem with inventory. As you can see from the picture, when I drag the bonus replacement item to a weapon or armor in the first slot of the inventory, it does not detect the bottom slot. It only detects the upper slot. And this situation happens only once. If I drag it to the upper slot first, then the lower slot is also detected. The same goes for stones. Actually, the thing is this; This problem occurs if the item in the K inventory and the item in the normal inventory are in the first slot on both sides.
  16. Hello, when I drag an item from the inventory to the market and try to sell it, it only shows me the name "Moon Essence" and shows it as 0 yang. It does this on all items. However, when I click the "Sell" button in the Market and select items from the inventory, it displays properly. There is no problem in the source codes, when I look at the ch1 logs, the SELL operation looks completely normal. There is such a display problem only in the game. I would really appreciate if you could help, thank you. uiShop.py(But there is no problem here): def SellAttachedItem(self): if shop.IsPrivateShop(): mouseModule.mouseController.DeattachObject() return attachedSlotType = mouseModule.mouseController.GetAttachedType() attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() attachedCount = mouseModule.mouseController.GetAttachedItemCount() if localeInfo.IsBRAZIL() == 0: attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() if app.ENABLE_SPECIAL_STORAGE: if player.SLOT_TYPE_INVENTORY == attachedSlotType or player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType or player.SLOT_TYPE_UPGRADE_INVENTORY == attachedSlotType or player.SLOT_TYPE_BOOK_INVENTORY == attachedSlotType or player.SLOT_TYPE_STONE_INVENTORY == attachedSlotType or player.SLOT_TYPE_FLOWER_INVENTORY == attachedSlotType or player.SLOT_TYPE_ATTR_INVENTORY == attachedSlotType or player.SLOT_TYPE_CHEST_INVENTORY == attachedSlotType: item.SelectItem(attachedItemIndex) 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 itemtype = player.SlotTypeToInvenType(attachedSlotType) if player.IsValuableItem(itemtype, attachedSlotPos): itemPrice = item.GetISellItemPrice() if item.Is1GoldItem(): itemPrice = attachedCount / itemPrice / 5 else: itemPrice = itemPrice * max(1, attachedCount) / 5 itemName = item.GetItemName() questionDialog = uiCommon.QuestionDialog() questionDialog.SetText(localeInfo.DO_YOU_SELL_ITEM(itemName, attachedCount, itemPrice)) questionDialog.SetAcceptEvent(lambda arg1=attachedSlotPos, arg2=attachedCount, arg3 = itemtype: self.OnSellItem(arg1, arg2, arg3)) questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) questionDialog.Open() self.questionDialog = questionDialog else: self.OnSellItem(attachedSlotPos, attachedCount, itemtype) else: snd.PlaySound("sound/ui/loginfail.wav") else: if player.SLOT_TYPE_INVENTORY == attachedSlotType or player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType: if localeInfo.IsBRAZIL(): itemIndex = player.GetItemIndex(attachedSlotPos) item.SelectItem(itemIndex) else: item.SelectItem(attachedItemIndex) 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 itemtype = player.INVENTORY if localeInfo.IsBRAZIL() == 0: if player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType: itemtype = player.DRAGON_SOUL_INVENTORY if player.IsValuableItem(itemtype, attachedSlotPos): itemPrice = item.GetISellItemPrice() if item.Is1GoldItem(): itemPrice = attachedCount / itemPrice / 5 else: itemPrice = itemPrice * max(1, attachedCount) / 5 itemName = item.GetItemName() questionDialog = uiCommon.QuestionDialog() questionDialog.SetText(localeInfo.DO_YOU_SELL_ITEM(itemName, attachedCount, itemPrice)) questionDialog.SetAcceptEvent(lambda arg1=attachedSlotPos, arg2=attachedCount, arg3 = itemtype: self.OnSellItem(arg1, arg2, arg3)) questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) questionDialog.Open() self.questionDialog = questionDialog constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) else: self.OnSellItem(attachedSlotPos, attachedCount, itemtype) else: snd.PlaySound("sound/ui/loginfail.wav") mouseModule.mouseController.DeattachObject()
  17. thank you for sharing. There are many memory problems in Metin2 that are waiting to be fixed and cause unnecessary CPU increase. Do you have a post about these?
  18. There is no problem with Directx. I fixed all the problems and it works fine. Also, I don't understand why no one wants to help with how to apply effects like MSAA. I don't think there is such information worth hiding.
  19. How can I do this? Thank you. But I guess these don't apply MSAA. And unfortunately it didn't fix the ReShade issue
  20. Hello everyone. When I use horse skills, I get kicked out of the game and get an error like this. What is the reason of this? SKILL_HACK: name=Test, job=2, group=1, motion=113
  21. The symbol of the riding skill(130) does not appear. Anyone have any ideas about this? def __RefreshSkillPage(self, name, slotCount): global SHOW_LIMIT_SUPPORT_SKILL_LIST #global BLOCK_SUPPORT_SKILL_LIST skillPage=self.skillPageDict[name] startSlotIndex=skillPage.GetStartIndex() if "ACTIVE"==name: if self.PAGE_HORSE==self.curSelectedSkillGroup: startSlotIndex+=slotCount getSkillType=skill.GetSkillType getSkillIndex=player.GetSkillIndex getSkillGrade=player.GetSkillGrade getSkillLevel=player.GetSkillLevel getSkillLevelUpPoint=skill.GetSkillLevelUpPoint getSkillMaxLevel=skill.GetSkillMaxLevel for i in xrange(slotCount+1): slotIndex=i + startSlotIndex skillIndex=getSkillIndex(slotIndex) for j in xrange(self.SKILL_GRADE_SLOT_COUNT): skillPage.ClearSlot(self.__GetRealSkillSlot(j, i)) if 0==skillIndex: continue # if skillIndex in BLOCK_SUPPORT_SKILL_LIST: # continue skillGrade=getSkillGrade(slotIndex) skillLevel=getSkillLevel(slotIndex) skillType=getSkillType(skillIndex) if player.SKILL_INDEX_RIDING==skillIndex: if 1==skillGrade: skillLevel+=19 elif 2==skillGrade: skillLevel+=29 elif 3==skillGrade: skillLevel+=39 elif 4==skillGrade: skillLevel=50 skillPage.SetSkillSlotNew(slotIndex, skillIndex, max(skillLevel-1, 0), skillLevel) skillPage.SetSlotCount(slotIndex, skillLevel) elif skill.SKILL_TYPE_ACTIVE==skillType: for j in xrange(self.SKILL_GRADE_SLOT_COUNT): realSlotIndex = self.__GetRealSkillSlot(j, slotIndex) if (skillGrade >= self.SKILL_GRADE_SLOT_COUNT) and j == (self.SKILL_GRADE_SLOT_COUNT-1): skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, skillGrade, skillLevel) skillPage.SetCoverButton(realSlotIndex) skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) else: skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, j, skillLevel) skillPage.SetCoverButton(realSlotIndex) if (not self.__CanUseSkillNow()) or (skillGrade != j): skillPage.SetSlotCount(realSlotIndex, 0) skillPage.DisableCoverButton(realSlotIndex) else: skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) if player.IsSkillActive(slotIndex): skillPage.ActivateSlot(self.__GetRealSkillSlot(skillGrade, slotIndex)) else: if not SHOW_LIMIT_SUPPORT_SKILL_LIST or skillIndex in SHOW_LIMIT_SUPPORT_SKILL_LIST: realSlotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) skillPage.SetSkillSlot(realSlotIndex, skillIndex, skillLevel) skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) if skill.CanUseSkill(skillIndex): skillPage.SetCoverButton(realSlotIndex) skillPage.RefreshSlot()
×
×
  • 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.