Jump to content

Intel

Premium
  • Posts

    200
  • Joined

  • Last visited

  • Days Won

    4
  • Feedback

    0%

Everything posted by Intel

  1. There's no need to fix it on the sources: Just go to ymir work/pc/assassin/bow Open attack.msa Copy Group ComboInputData and Group AttackingData Paste in the same msa, same directory in pc2. Enjoy
  2. I myself would prefer gcc (btw clang supports c++20 as well: [Hidden Content] obviously depending on what feature you'd need, but I'd argue you'd not miss anything useful for metin. For me in particolar it's for constexpr std::string_view/std::array, std::map.contains() ) but if there wouldn't have been any issues with c++20, you should not have much problem. Obviously testing is always required, you'd never know!
  3. No problem. I know the jail can be frustrating (especially when trying to update stuff, because you gotta do it all over again), but you'd need to re-compile the libs anyway at some point so, it's basically almost the same. There's always the other option: remove -m32 and.. well, pray to make everything working compiled at 64bit lol
  4. Use a jail, way easier (imo). Steps: Create a virtual machine with the same freebsd version you wish to install the jail for (the VM 32bit of course) create a file in /etc/ jail.jailname.conf in the file write: exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.clean; mount.devfs; path = "/usr/jails/jailname"; compilejail { host.hostname = "jailname"; } BE CAREFUL AT THE EOL: create a new folder in usr/jails called jailname tar all your system from your virtual machine and then untar the zip file into usr/jails/jailname (set up your sources inside already) in /etc/rc.conf add: jail_enable="YES" jail_list="jailname" then on the console type: service jail start jailname If it doesn't start a reboot may be needed (or just service jail restart?) Then type jls: Usually the id should be 1, therefore: jexec 1 and you are into the jail
  5. The server is literally telling you the problem:
  6. Fair to say the he might not have been the best server owner in Italy but, ffs, jemalloc is called by the lua lib, not the sources. I can guarantee that dungeons have core issues with the kill functions. We had to log EVERYTHING on UE because some ::KillDungeon or ::KillUnique would make the core crash sometimes:
  7. So, I said "it's not something Metin2 related." which, it's half true, half false. I still stand by the fact that the fly it's a bug and there are better ways to legalize it (for example: Riven, a LoL character, used animation cancels, derived by bugs, to maximize her damage. Riot at some point decided to fix her, and keep her gameplay the same. The real fix to this nasty fly bug, should be to actually make the fly an actual character state controlled by the server, but that's a whole other discussion). So, after reading some Microsoft docs and trying to find anything meaningful, I stumbled across the holy grail, stackoverlow. At the end of the answer, it was pointed out "That is, are people really going to be dragging the window WHILE playing, unlikely.", rightly so, I'd say. It doesn't surprise me that no game, and I mean, not a single goddamn game, does not freeze if you move around the window. I mean, why a developer would take time even thinking about that, it doesn't make sense. But this is Metin2, and this bug, it's somehow a core mechanic that, if removed, you can expect your players at your house with trucks and pitchforks. The answer on the stackoverflow discussione stated: Your application is most likely "freezing" because it has a WinMain loop similar to this: while (true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { TickGame(); } } and guess effing what, there's a very similar looking function in the client One solution would be to handle the Windows messages about the moving/clicking on the toolbar: WM_ENTERSIZEMOVE WM_EXITSIZEMOVE WM_MOVE WM_MOVE, if the hWnd is available, otherwise it crashes while opening the client, can call directly the main rendering function of the client, while ENTERSIZEMOVE and EXITSIZEMOVE needs to handle a special timer, which will call the rendering function when Windows sends the TIMER message. In pseudocode: if (event_is_resize_start) { Start_Win32Timer(); } if (event_is_resize_end) { Kill_Win32Timer(); } WindowsMessages { //[...] WM_TIMER: render(); } The only "issue" will be a small delay when clicking the titlebar, but the character will still keep performing whatever action it was doing, instead of standing still in position (keeping the enemy "flyed bugged down"). Normally, one shouldn't be able to do that, therefore we could really not care about the smoothness of it.
  8. Yeah, no, I know about that (I edited the post later). The real fix is to actually nuke the fly to the moon, but players just got accustomed to that bug, so, here we are.
  9. Legit every game (new or old, DirectX9/10/11/12/Vulkan) I've tried freezes (the only exception was Forza Horizon but they use UWP). And rightly so, what's the point to even fix it? Obviously, only on Metin (because of the stupid fly). What's the server's name btw? (in DM if you want to)
  10. OH, that is a totally whole different problem LOL well, in that case, on exchange.cpp, on: bool CHARACTER::ExchangeStart(LPCHARACTER victim) there should be something like: //PREVENT_TRADE_WINDOW if( IsOpenSafebox() || GetShopOwner() || IsInteractingWithNpc()) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("If the Trade Window is open, you cannot trade with others." ) ); return false; } if( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->IsInteractingWithNpc() || victim->GetOfflineShopGuest() || victim->GetAuctionGuest()) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("The other player is already trading." ) ); return false; } //END_PREVENT_TRADE_WINDOW InteractingWithNpc is just a function on my files that checks stuff: bool CHARACTER::IsInteractingWithNpc() const { if(IsCubeOpen()) return true; if(IsRouletteOpen()) return true; if(IsAcceOpen()) return true; return false; } You might need maybe some other checks, and some don't exist (like GetOfflineShopGuest) I forgot, on: bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) there should be: if(item->IsExchanging()) return false; this check should be also on: bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell, int nArgument) bool CHARACTER::DropItem(TItemPos Cell, WORD wCount) bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, WORD wCount, bool bSaveTime) Yes and no, I don't know how you edit the item_proto in your server, but if you have like a converter txt->item_proto client then yeah, you edit the txt, you upload it (and that's the server part), and for the visual stuff you dump the item_proto client side and change it in the locale folder of the client (and then pack the locale folder with the new item_proto)
  11. I don't understand this, if it's like you asked on Discord, as I've already said, you cannot do this. Again, there's a reason why there are some checks in place (like, you can't warp if you just traded). You mean they get teleported back? It's caused by this peace of code (change the numbers accordingly, do some tests) if(((false == ch->IsRiding() && fDist > 60) || fDist > 125) && OXEVENT_MAP_INDEX != ch->GetMapIndex()) { /*const PIXEL_POSITION & warpPos = ch->GetWarpPosition(); if(warpPos.x == 0 && warpPos.y == 0) LogManager::instance().HackLog("Teleport", ch);*/ // It may be imprecise sys_log(0, "MOVE: %s trying to move too far (dist: %.1fm) Riding(%d)", ch->GetName(), fDist, ch->IsRiding()); ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ()); ch->Stop(); return; } Also, if the mount, in your mob_proto, has a folder (in the folder column), you need to add the msa files of that mount (from your client) copied into share/data/monster/mount_folder. EX: You've changed the item on the database, but you also need the item_proto of your client
  12. You don't "install" c+11, you say to the compiler what version of C++ you intend to compile the files with. Depending on your gcc version (the compiler), the default might very well be a version prior c++11 who doesn't have for range loops ( for(auto x : container) ). Usually you define the version in the CXXFLAGS (declared in the Makefile), using -std=c++11 but that might involve some modifications on the sources. I gave you an alternative without needing an updated version of C++ anyway
  13. Sure, one way would be to edit: m_hWnd = CreateWindow( c_szClassName, c_szName, ws, 0, 0, 0, 0, NULL, NULL, ms_hInstance, NULL); with: m_hWnd = CreateWindow( c_szClassName, c_szName, WS_POPUPWINDOW, 0, 0, 0, 0, NULL, NULL, ms_hInstance, NULL); but then you wouldn't be able to move the window. There are no other options, it's not something Metin2 related. Example with League of Legends: [Hidden Content]
  14. [Hidden Content] You need c++11. If you are still using C++03/C++98 you can't use: for (auto lpItem : setItems) Instead: std::set<LPITEMS>::iterator itr; for (itr = setItems.begin(); itr != setItems.end(); itr++) and wherever lpItem in the loop is used, in this case needs to be replaced with *itr
  15. Updated project: Now it opens at the center of the screen Set some defines for a window flag, open at the center and the testing of the application Better testing of the progress bar (with define, now only the change of the configuration type is needed) Changed optimization settings (it fucks with the linking, didn't notice since VisualStudio sets this option by default)
  16. Ok we got it privately, basically the simple solution (keeping the original GetAtlasInfo) would be: void CPythonMiniMap::RegisterAtlasMark(BYTE byType, DWORD dwVnum, const char * c_szName, long lx, long ly) aAtlasMarkInfo.m_strText = c_szName; here, instead of copying the name, taken from the server: void CPythonMiniMap::RegisterAtlasMark(BYTE byType, DWORD dwVnum, const char * c_szName, long lx, long ly) { TAtlasMarkInfo aAtlasMarkInfo; aAtlasMarkInfo.m_fX = float(lx); aAtlasMarkInfo.m_fY = float(ly); const CPythonNonPlayer::TMobTable* c_pMobTable = CPythonNonPlayer::Instance().GetTable(c_dwVnum); if(c_pMobTable != nullptr) //if exists in mob_proto, change accordingly aAtlasMarkInfo.m_strText = c_pMobTable->szLocaleName;; else //otherwise, use the name from server aAtlasMarkInfo.m_strText = c_szName; aAtlasMarkInfo.m_dwID = dwVnum; aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f; aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f; switch(byType) { case CActorInstance::TYPE_NPC: aAtlasMarkInfo.m_byType = TYPE_NPC; m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo); break; case CActorInstance::TYPE_WARP: aAtlasMarkInfo.m_byType = TYPE_WARP; { int iPos = aAtlasMarkInfo.m_strText.find(" "); if (iPos >= 0) aAtlasMarkInfo.m_strText[iPos]=0; } m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo); break; } } and that's it, the name will be in the m_AtlasNPCInfoVector or m_AtlasWarpInfoVector so that in bool CPythonMiniMap::GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID) rReturnString = rAtlasMarkInfo.m_strText; this string would be either the name from mob_proto or the server one, depending on what was saved during the RegisterAtlasMark function. Obviously in this case, the packet should send the vnum as well
  17. Maybe I am not understanding quite correctly what you are trying to accomplish, but that system already gives the solution to show the name of NPCs/Monsters from the client (you'd need to update the mapName_point.txt file with the coordinates but ye). Anyway, if you have the vnum (from Penger's topic itself): const CPythonNonPlayer::TMobTable* c_pMobTable = CPythonNonPlayer::Instance().GetTable(c_dwVnum); if(c_pMobTable != nullptr) auto name = c_pMobTable->szLocaleName;
  18. If anyone had bought the VegaS' client optimization, they know that the loading of the motion files, depending on the loading vector's size, can take a bit of time, especially if you have 3642 files to load (totally random number ) N.B. I won't display even a single byte of the VegaS system's code. I would be happy to assist you if you are a customer of his and have purchased his client optimization (I will confirm with him, but I won't offer support for leaked stuff). Alrright, so, at first I thought to simply create a new "HWND" and work on that one, but, since it would run on the same instance as the client, it wouldn't be just as smooth. So just initialize a different instance and load the window on that instance? Sure, but, also no, too much of an hassle. A simpler solution would be to start a new app with the client who would receive the progress of the loading and show a progress bar or something, just to inform the player that the client is actually opening. Technically the project can be used for just anything else, like a separate menu integrated into the client or something, although the framework I used is not intended to fully work with DX8, so there might be some glitches considering what you wanna do with it. Now, let's dive into it, because it's not just a plug-and-play thing. Let's start by saying the app is made using a framework called ImGui: [Hidden Content] What's need to be done? Let's start with the name and the size (in this case 1280x800) of the main Application. You can find it on LoadingWindowHandler.cpp: m_HWND = ::CreateWindow(m_WCEX.lpszClassName, _T("Dear ImGui DirectX8 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, m_WCEX.hInstance, NULL); If you've had any experience on Win32 APIs, do not do this: SetWindowLong(hWnd, GWL_STYLE, 0); It breaks the text. If there is a fix, I haven't found one, yet. Second thing, ImGui stores the position and the size of the child windows inside a .ini file, called imgui.ini For example, in my case, I have: [Window][MainWindow] Pos=98,165 Size=1266,750 Collapsed=0 (declared in imgui.cpp line 4556) and then: [Window][TopWindow] Pos=0,0 Size=1265,762 Collapsed=0 Which is the window where we're gonna render the background, text and progressbar. Obviously, depending on your image size, these settings should be changed. We can also edit the size of the "TopWindow" actually running the application and resize it there. To do that, we can just de-comment: #define TEST_PROGRESS_BAR in LoadingWindowHandler.h After that, we need to change the Configuration Type: then we can open the application and move the window: Or resize it: Once closed, the application will have changed the settings in the ini file: [Window][MainWindow] Pos=98,165 Size=1266,750 Collapsed=0 [Window][TopWindow] Pos=-78,-120 Size=967,524 Collapsed=0 This way you can resize/move the window according to your background image. It is also possible to change the name of the ini file in imgui.cpp IniFilename = "imgui.ini"; To change the background image you want to edit the directory and name here: std::string filepath = cwd.string() + "\\movie\\splash.bmp"; From Microsoft docs the formats supported are: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga. How are the positions of the ProgressBar, Text and background handled? Well, let's start from the background: ImGui::SetCursorPosY(0); auto size = ImGui::GetContentRegionAvail(); ImGui::Image((void*)SplashImage, ImVec2(size.x, size.y)); ImGui::SetCursorPosY(0); is like saying "go to the Y coord 0", then the rest is to "resize" the background image to the Area of the "TopWindow". The style of the ProgressBar is in LoadingWindowDesigner.cpp: #include "LoadingWindowDesigner.h" #include <ImGui/imgui.h> namespace LoadingWindowDesigner { void RenderUI(float progress, std::string loading_text) { auto window_size = ImGui::GetWindowSize(); ImGui::SetCursorPosY(window_size.y - 30); ImGui::Text(loading_text.c_str()); ImGui::ProgressBar(progress, ImVec2(window_size.x - 15.0f, 5.0f), ""); } } Again, with SetCursorPosY we are saying to go specific Y coords, in this case at the bottom of the window minus 30 pixels, that's where it's gonna write the text, then we draw the ProgressBar. The numbers inside ImVec2 are the dimensions of the ProgressBar. There's a third parameter where you could set an overlay text to the ProgressBar. If you wanna change the Font, well: [Hidden Content]/blob/master/docs/FAQ.md#q-how-can-i-load-a-different-font-than-the-default If you wanna change the color of the moving bar, you can go to imgui_widgets.cpp and change this line: RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_ButtonHovered), 0.0f, fraction, style.FrameRounding); The background instead is on this line: RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); The colors specified are the ones with the index: ImGuiCol_ButtonHovered and ImGuiCol_FrameBg. All this stuff can be seen by downloading the framework from the github repository and launching a project from the examples folder. The ImGui Demo window will show every possible option that you can then check on the source code (even the colors, that I found playing around with the demo window). One thing you'd notice from the window, is that there are some weird borders, and we can delete those (in my example, they actually fit pretty well with the background, so I left them. To do that just de-comment the other define: //#define LOADING_WINDOW_NOBORDERS P.S. There might be a few pixel modification on the ini file to do afterwards on the "TopWindow", noticeable when opening the client, because of the removal of the borders (if you did). Usually the correction is around 8px, which is the default padding of the framework, if I am not mistaken. You could also adjust the padding). So, we chose a background image, set the window size accordingly, positioned the text and rendered the progressbar as we wanted. And for now, we are done with the library (remember to change the configuration type to .lib and comment: #define TEST_PROGRESS_BAR Now compile the library both in Debug and Release mode, and add them to the lib folder of the client. After that open LinkerLibraries.h and add: #ifdef _DEBUG #pragma comment(lib, "LoadingWindowLib_d.lib") #else #pragma comment(lib, "LoadingWindowLib.lib") #endif then in StdAfx.h we add: #include "LoadingWindowMain.h" Then add on your include folder: LoadingWindowDesigner.h LoadingWindowHandler.h LoadingWindowMain.h You also need to add the ImGui folder (only the header files): Now if you have linking/compile errors, that's because your DirectX folder or your include directory, on the Project Settings, are different. To fix it you need to change the path in "Additional Include Properties" in the lib project so that your #include <directxheader> directive is the same as in the client. After confirming that everything works, how to use it: auto LoadingWindow = std::thread(LoadingWindow::InitializeLibrary); LoadingWindow.detach(); CPythonApplication *app = new CPythonApplication(); app->Initialize(hInstance); This will start a new thread running the library. How to change the progress percentage and the text? Let's say you have a number of executions: static auto EXECUTION_TIMES = 100000; float progress_adder = (1.0f - progress)/static_cast<float>(EXECUTION_TIMES); the "number" we are gonna add to the progress bar is gonna be his total (1.0f) minus the actual progress in that moment (if 0, you could just do 1.0f/static_cast<float>(EXECUTION_TIMES). Then on the loop of your loading stuff function you can change the text before the loop, or inside (if you wanna show something for every execution) and the actual progress: LoadingWindow::UpdateProgressText("Executing tasks..."); for (auto i = 0; i < EXECUTION_TIMES; ++i) { progress += progress_adder; // call a function here LoadingWindow::UpdateProgress(progress); } Always remember that the progress is a float and the "percentage" goes from 0.0f to 1.0f Now, in theory, the library should close itself when it gets to 1.0: if (m_Progress >= 1.0f) m_Done = true; but, at least in my case, it's also possible that it ends with a number such as 0.9999628 or something like that, so we can just call the CleanUpLibrary method to just close it when we want it. And that's it. Result: [Hidden Content] N.B. Despite working, if you intend to use this framework for other stuff, like some external menus to open from the client or w/e you have in mind, the DX8 version is super glitchy when there are two windows open: [Hidden Content]/issues/5379 and if you think you can use a different DirectX version, I am sorry to disappoint you: As you can see, when trying to load the texture, it's calling the "AddRef()" method: bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) { ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx9"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. bd->pd3dDevice = device; bd->pd3dDevice->AddRef(); //<----------- return true; } but, the client calls the DX8 APIs, not DX9, ergo no DirectX different than 8.1 Can you use a different framework? Sure, you may always use a similar approach with another similar GUI App, like the CefWebBrowser, but on a different thread, because the webbrowser runs on the same instance of the client: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #ifdef _DEBUG _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF ); //_CrtSetBreakAlloc( 110247 ); #endif LocaleService_LoadConfig("locale.cfg"); SetDefaultCodePage(LocaleService_GetCodePage()); CefWebBrowser_Startup(hInstance); //<------------- Credits: ocornuti, the owner of ImGui's repository KsaNL for providing a base for ImGui on DX8 Ikarus for dealing with my mental illness during this mini-project Project Download: Mega (or Metin2 Download)
  19. Yes, in my files, in my locale_string I have "%d seconds to logout."; "translation"; so you gotta check the text with original source files and then check the text in locale_string (they have to match, obviously)
  20. Should be: EVENTFUNC(timed_event) in cmd_general.cpp [...] else { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d seconds to logout."), info->left_second); //<--------------------- --info->left_second; } return PASSES_PER_SEC(1); } ACMD(do_cmd) [...]
  21. I am curious as well to know where that POINT is used in original sources..
  22. No, I am high. But, kiddings aside, as I've already stated: and they've changed the text as well, I guess. Now, whether removing the if clause is valid or not, it's not up to my knowledge. Considering that it did not affect a single thing (again, 7+ years), I am almost 101% confident it's w/e (otherwise I am more than happy to be proven wrong).
  23. it's been like this for 7+ years (so whoever commented it, they deemed the if clause useless as well)
  24. Just comment that: void CInstanceBase::PushTCPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) { //if (__IsMainInstance()) //{ // TraceError("CInstanceBase::PushTCPState Cannot Push TCPState on a main instance"); // return; //} [...] }
×
×
  • 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.