Jump to content

Distraught

Honorable Member
  • Posts

    194
  • Joined

  • Last visited

  • Days Won

    23
  • Feedback

    0%

Posts posted by Distraught

  1. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hey again :D

     

    Yesterday I was looking into mss32.dll and just found out this is the library being responsible for loading asi, mix, m3d, etc.. files. So I made a library that will hook the Miles Sound System so that it won't load unwanted files, only what is needed.

     

    Download: https://distraught.hu/DistraughtProtector/

    VirusTotal: 

    This is the hidden content, please

     

    There are 3 files in the zip:

    • .lib -> put it in your extern/lib folder
    • .h -> put it in your extern/include folder
    • .dll -> put it in your client

     

    Open UserInterface/UserInterface.cpp and find the WinMain function.

    Add this to the beginning of the function:

    DistraughtProtector::Initialize();
    
    DistraughtProtector::SetFileBlockedCallback(&HackerDetected);
    
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssmp3.asi", 125952);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssvoice.asi", 197120);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssa3d.m3d", 83456);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssds3d.m3d", 70656);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssdx7.m3d", 80896);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\msseax.m3d", 103424);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssrsx.m3d", 354816);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\msssoft.m3d", 67072);
    DistraughtProtector::AddAllowedMilesProviderLibrary("miles\\mssdsp.flt", 93696);

    You have to specify the files that are enabled to load by the Miles Sound System (path, file size in bytes).

     

     

    And add this before that function:

    static void _stdcall HackerDetected(const char* blockedFile)
    {
    	MessageBox(NULL, blockedFile, ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP);
    }

    This is a callback where you get notified if the user would load a file that he/she shouldn't :D

    You don't have to specify a callback, in that case remove DistraughtProtector::SetFileBlockedCallback(&HackerDetected); from WinMain and the client just simply won't load the dangerous files. 

     

    Here's an image what it should look like:

    image_howto.jpg

     

     

    After that just add

    DistraughtProtector::Destroy();

    to the end of WinMain (surely before the return!).

     

    Hope you like it! If you have ideas what new features should I add to the library, let me know in the comments! :)

    • Metin2 Dev 35
    • Dislove 1
    • Good 6
    • Love 2
    • Love 19
  2. No one defined what they mean by interacting real-time. Interacting real time can also mean like sending messages what could be achieved. What I was talking about still makes sense as I told them their possibilities, just really have your time understanding it. This construction could matter tho. You ought to understand what I am saying instead of just trying to get it personal because your message was nothing but trying to be bitchy about anything.

  3. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hey guys,

     

    I just programmed this feature for my server but I thought it can be really useful for everyone so now I release it.

    This stuff is about how you can load images, etc. in the game without directly packing it into the client but uploading them to a web-server. In this tutorial we will make it work for images, but you can extend it to any type of file you want.

    There are not much requirements we only use up to C++11 features and you have to have libcurl library.

     

    Open up EterLib/ResourceManager.h and add add the following to the end of the class (don't forget to include <future> and <utility>):

    private:
    	std::list<std::future<CResource*>>		ongoingDownloads;
    public:
    	void AddDownload(std::future<CResource*>&& f)
    	{
    		ongoingDownloads.emplace_back(std::forward<std::future<CResource*>>(f));
    	}

    Go to EterLib/ResourceManager.cpp and find the CResourceManager::Update function, add the following to the end of it:

    	for (auto it = ongoingDownloads.begin(); it != ongoingDownloads.end();)
    	{
    		if (it->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
    		{
    			it->get()->LoadDownloadedData();
    			it = ongoingDownloads.erase(it);
    		}
    		else
    		{
    			++it;
    		}
    	}

    Next, open EterLib/Resource.h, find the constructor and modify it like:

    CResource(const char* c_szFileName, bool _loadFromNetwork = false);

    After add the following to the end of the class:

    protected:
    	bool loadFromNetwork;
    private:
    	std::vector<BYTE> downloadedData;
    public:
    	void LoadDownloadedData();

     

    Then go to EterLib/Resource.cpp, find the constructor and also modify it like:

    CResource::CResource(const char* c_szFileName, bool _loadFromNetwork) 
    	: me_state(STATE_EMPTY)
    	, loadFromNetwork(_loadFromNetwork)
    {
    	SetFileName(c_szFileName);
    }

    In the same file, add this to the beginning right after the includes:

    #include <curl/curl.h>
    #include "ResourceManager.h"
      
    #define ASSET_SERVER "http://assets.my-website.com/"
      
    static size_t CurlWriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
    {
    	if (nullptr != userp)
    	{
    		std::vector<BYTE>& vec = *((std::vector<BYTE>*)userp);
    		vec.reserve(vec.size() + (size * nmemb));
    		for (size_t i = 0; i < size * nmemb; ++i)
    		{
    			vec.push_back(((BYTE*)contents)[i]);
    		}
    	}
    	return size * nmemb;
    }
    
    void CResource::LoadDownloadedData()
    {
    	if (downloadedData.empty())
    		return;
    
    	Clear();
    
    	if (OnLoad(downloadedData.size(), downloadedData.data()))
    	{
    		me_state = STATE_EXIST;
    	}
    	else
    	{
    		Tracef("CResource::Load Error %s\n", GetFileName());
    		me_state = STATE_ERROR;
    	}
    
    	downloadedData.clear();
    }

     

    Now, - still in the same file - find CResource::Load function and modify it like this:

    void CResource::Load()
    {
    	if (me_state != STATE_EMPTY)
    		return;
    
    	std::string fileName = GetFileName();
    
    	if (loadFromNetwork && downloadedData.empty())
    	{
    		CResourceManager::instance().AddDownload(std::move(std::async(std::launch::async | std::launch::deferred, [this, fileName]()
    			{
    				std::string url = ASSET_SERVER;
    				url += fileName;
    
    				CURL* curl = curl_easy_init();
    				if (curl)
    				{
    					curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    					curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
    					curl_easy_setopt(curl, CURLOPT_WRITEDATA, &downloadedData);
    					curl_easy_perform(curl);
    					curl_easy_cleanup(curl);
    				}
    
    				return this;
    			})));
    
    		fileName = "d:/ymir work/ui/placeholder.tga";
    	}
    
    	DWORD		dwStart = ELTimer_GetMSec();
    	CMappedFile	file;
    	LPCVOID		fileData;
    
    	//Tracenf("Load %s", c_szFileName);
    
    	if (CEterPackManager::Instance().Get(file, fileName.c_str(), &fileData))
    	{
    		m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart;
    		//Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond);
    
    		if (OnLoad(file.Size(), fileData))
    		{
    			me_state = STATE_EXIST;
    		}
    		else
    		{
    			Tracef("CResource::Load Error %s\n", fileName.c_str());
    			me_state = STATE_ERROR;
    			return;
    		}
    	}
    	else
    	{
    		if (OnLoad(0, NULL))
    			me_state = STATE_EXIST;
    		else
    		{
    			Tracef("CResource::Load file not exist %s\n", fileName.c_str());
    			me_state = STATE_ERROR;
    		}
    	}
    }

     

    Still in Resource.cpp, find the CResource::Reload function and modify like:

    void CResource::Reload()
    {
    	Tracef("CResource::Reload %s\n", GetFileName());
    
    	if (loadFromNetwork)
    	{
    		if (downloadedData.empty())
    		{
    			std::string fileName = GetFileName();
    			CResourceManager::instance().AddDownload(std::move(std::async(std::launch::async | std::launch::deferred, [this, fileName]()
    				{
    					std::string url = ASSET_SERVER;
    					url += "/";
    					url += fileName;
    
    					CURL* curl = curl_easy_init();
    					if (curl)
    					{
    						curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    						curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
    						curl_easy_setopt(curl, CURLOPT_WRITEDATA, &downloadedData);
    						curl_easy_perform(curl);
    						curl_easy_cleanup(curl);
    					}
    
    					return this;
    				})));
    		}
    	}
    	else
    	{
    		Clear();
    
    		CMappedFile	file;
    		LPCVOID		fileData;
    
    		if (CEterPackManager::Instance().Get(file, GetFileName(), &fileData))
    		{
    			if (OnLoad(file.Size(), fileData))
    			{
    				me_state = STATE_EXIST;
    			}
    			else
    			{
    				me_state = STATE_ERROR;
    				return;
    			}
    		}
    		else
    		{
    			if (OnLoad(0, NULL))
    				me_state = STATE_EXIST;
    			else
    			{
    				me_state = STATE_ERROR;
    			}
    		}
    	}
    }

     

    Open EterLib/GrpImage.h and modify the constructor:

    CGraphicImage(const char* c_szFileName, DWORD dwFilter = D3DX_FILTER_LINEAR, bool loadFromNetwork = false);

    In EterLib/GrpImage.cpp also modify it:

    CGraphicImage::CGraphicImage(const char * c_szFileName, DWORD dwFilter, bool loadFromNetwork) 
    	: CResource(c_szFileName, loadFromNetwork)
    	, m_dwFilter(dwFilter)
    {
    	m_rect.bottom = m_rect.right = m_rect.top = m_rect.left = 0;
    }

     

    Finally open ScriptLib/Resource.cpp and add this somewhere the beginning:

    CResource* NewOnlineImage(const char* c_szFileName)
    {
    	return new CGraphicImage(c_szFileName, D3DX_FILTER_LINEAR, true);
    }

    Go down where you see m_resManager.RegisterResourceNewFunctionPointer("jpg", NewImage); and add after:

    m_resManager.RegisterResourceNewFunctionPointer("oimg", NewOnlineImage);

     

    We're done! Now if you use *.oimg extension anywhere it will load them from what you define as ASSET_SERVER in EterLib/Resource.cpp (http://assets.my-website.com/filename.oimg). You have to rename the image you upload from the original extension to oimg!

     

    Put a placeholder image at "d:\ymir work\ui\placeholder.tga" that it will load while waiting for bigger images.

     

    GIF in action (normal size image, the pic in the right bottom corner):

    online-asset-normal-load.gif

     

    GIF of loading a big (10MB image) that takes more time:

    online-asset-big-load.gif

     

    Hope you like it!

    • Metin2 Dev 7
    • Good 5
    • Love 2
    • Love 19
  4. On 1/8/2020 at 5:16 PM, UdvAtt108 said:

     

    I would like to correct you.

     

    ++it is more efficient because it++ need to return a copy of the object then increment itself.

     

     

    And you really think the compiler won't optimize it anyway?

    • Lmao 1
  5. Theoretically en bloc it gives some performance gain. For example converting meshes to 16bit indices even tho sounds strange because modern cpus work faster with their native word size but the less cache miss because of the size optimization can turn the balance to the other way around.

    • Love 2
  6. 56 minutes ago, HITRON said:

    Good idea, Thanks for the tool.

     

    I don't know how that sounds to others but to me sounds weird -> 

     

    Last night I was kinda playing with granny a bit and this tool was born.

     

    haha that was intentional :P 

    • Metin2 Dev 1
    • Lmao 2
    • Good 1
  7. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hey guys,

     

    Last night I was kinda playing with granny a bit and this tool was born.

    I hope it will be useful for most of you!

     

    Optimize, change textures, convert to fbx or 3ds, etc...

     

    Downloadhttps://distraught.hu/download/m2dev/GR2Tool_by_Distraught.exe

    Usage: Just drag and drop a gr2 file on the exe and choose what you would like the program to do.

     

    Spoiler

    080801gr2-tool-by-distraught-preview.jpg

     

    P.S.: Don't be surprised if the new gr2 file becomes bigger than it was, it is because this tool saves them without compression for better performance.

    • Metin2 Dev 268
    • kekw 5
    • Eyes 7
    • Flame 1
    • Dislove 6
    • Angry 4
    • Not Good 4
    • Sad 4
    • Cry 1
    • Smile Tear 2
    • Think 8
    • Confused 7
    • Scream 7
    • Lmao 3
    • Good 125
    • muscle 3
    • Love 23
    • Love 211
  8. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hey guys,

    I needed to be able to scroll on the ui with the mouse wheel and I thought it will be useful for others too so here's what to do.

     

    EterPythonLib

    PythonWindow.h

    Add

     

    virtual BOOL	OnMouseWheel(int nLen);

     

    after like

     

    virtual BOOL	OnMouseMiddleButtonUp();

     

    In PythonWindow.cpp add the following function:

     

    BOOL CWindow::OnMouseWheel(int nLen)
    {
      long lValue;
      return PyCallClassMemberFunc(m_poHandler, "OnMouseWheel", Py_BuildValue("(i)", nLen), &lValue) && 0 != lValue;
    }

     

    In PythonWindowManager.h add

     

    bool		RunMouseWheel(int nLen);

     

    after like

     

    void		RunMouseMiddleButtonUp(long x, long y);

     

    In PythonWindowManager.cpp add the definition somewhere:

     

    bool CWindowManager::RunMouseWheel(int nLen)
    {
      CWindow* pWin = GetPointWindow();
      while (pWin)
      {
        if (pWin->OnMouseWheel(nLen))
          return true;
        pWin = pWin->GetParent();
      }
      return false;
    }

     

    UserInterface

    In PythonApplicationEvent.cpp override the following function:

     

    void CPythonApplication::OnMouseWheel(int nLen)
    {
    	UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
    	if (!rkWndMgr.RunMouseWheel(nLen))
    	{
    		CCameraManager& rkCmrMgr = CCameraManager::Instance();
    		if (CCamera* pkCmrCur = rkCmrMgr.GetCurrentCamera())
    			pkCmrCur->Wheel(nLen);
    	}
    }

     

    Then root/ui.py and find ScrollBar class and add this function to it:

     

    def OnMouseWheel(self, nLen):
    		if nLen > 0:
    			self.OnUp()
    			return True
    		elif nLen < 0:
    			self.OnDown()
    			return True
    		return False

     

    But you can use OnMouseWheel everywhere to listen to scrolling.

     

    Good luck!

    • Metin2 Dev 96
    • kekw 1
    • Eyes 1
    • Angry 1
    • Good 25
    • Love 2
    • Love 82
  9. 22 minutes ago, Sonitex said:

    I think what @Finnael is saying makes sense. In order to achieve synchronisation of characters' movement and information you would need to send PacketAround() through P2P so it reaches other servers. Also having one master server would solve issues like spawning regens on each server or something similar (I just guessed). 

    I type the same for the third time now. Packet around will not send anything to the peers because other cores just really don't give a shit what happened real-time with your character. Who sees you (and this is why it sends to them) is connected to the same core as you are.

     

    3 minutes ago, Finnael said:

    Yes the game can work like this because all the cores are inside one machine. When one core requires the data the other core has it gets it instantly. But in this case the cores will be in different continents.

     

    Yes exactly. 

    WHAT YOU THINK HOW THE FUCK SENDS ONE CORE THE DATA TO ALL ANOTHER? THE SAME WAY AS IF THEY WERE NOT ON THE SAME MACHINE

    • Confused 1
  10. Read again. The server only has to know eg. the position of others if they are on the same map with you (sorta kinda). What do you think, why do you divide cores by maps? They are each a running server instance.

    When you start your server, you begin with the db because that application is going to receive a packet from each of the cores when they start running and distributes to the others.

    If you look into the sources, you will find out that a lot of communication acts are not even sent to all the peers just what needs to be known on other channels too (like shouts).

    It is completely irrelevant if those server instances are on the same machine or not if they get the address of the same db app.

  11. 91752355_115573150093552_290170447239053

     

    Dear Community,

     

    We are a soon-to-be-opened, so that still under development server in Hungary which we are looking for new enthusiastic, active and teamwork compatible members for our development team.

    We prefer the Dali approach, therefore we are not seeking (self-claimed) i-know-everything guys but we eagerly wish to meet talented developers with virtue at their fields.

     

     

    So what positions are free to apply?

    Game designers, game economy designers, UI designers, 2D and 3D artists are always welcome.

     

    What skills should a game designer really have?

    • creativity
    • playing experience with a lot of games (mostly MMORPGs)
    • understanding different types of gamers, their needs and the way they work (Bartle taxonomy)
    • ability to think outside the box and then sync those ideas to fit in the game
    • minimal knowledge for Excel as we have all our data and game settings in xlsx files that game designers edit

     

    What skills should a game economy designer really have?

    • being good at numbers
    • ability to oversee the whole game's balances
    • experience at writing drops, setting values to items and monsters, besides forecasting the impact of new stuffs on the game and its economy 
    • defining and maintaining the values of currencies (soft and hard) and preventing inflations

     

    What skills should a UI designer really have?

    • Photoshop skills
    • basic knowledge of UI/UX guidelines
    • a hell of creativity
    • competency to work with 2D and 3D artists to make game-ready design assets

     

    What skills should a 2D artist really have?

    • having the talent to draw graphics for the game (loading screens, concept arts)
    • deftness to draw with digitalizing boards
    • also a really really really lot of creativity

     

    What skills should a 3D artist really have?

    • knowledge for using 3DSMax (it's good if you can work with other programs too)
    • being able to work by concept arts and by-heart also
    • rigging and animating skills

     

    You can apply or ask anything by messaging me here.

     

    But now lets see something of the project itself too :)

     

    93290851_123092406008293_414982394429308

    ingame voice chat in parties

     

     

    flying mounts

     

    103511916_147499220234278_62059013367702104206228_147499256900941_45730545013201

    achievements

     

     

    improved customizability

     

    And for sure a lot of else that we didn't want to expose yet on our social media sites, like board game, puzzle event, reworked guild system, powerup card system, etc...

     

    The server is going to open in Hungary first and after 3 months of the opening we would like to open our turkish server too.

     

    Facebookhttps://www.facebook.com/landofheroes.hu

    Discord: https://discord.landofheroes.eu

  12. Rendering 250 fps when your monitor can only show 60? By the way if you run the application NOT in fullscreen mode, the window manager will sync them anyway. Only in fullscreen mode will you have the opportunity to do it on your own.

    Oh and I haven't talked about the input delay it can cause. Microsoft suggests rendering and updating on 60 fps and only handling the input more times.

  13. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hey guys,

     

    It was really a long ago I did any activity on a forum so I decided to release a small but usefull class.

    This can be used to place functions you want to run on every frame for a period of time with a progress on a "timeline". This can be used for example to roll the yang up or down when changing it (a normal way and not creating threads or wtf others doing) or anything else when you animating something in code.

    So add this 2 files (download link at the end of this post) to your project and go to PythonApplication.cpp and find the Process function.

    Add this line after like OnUIUpdate();:

    
    Timeline::GetInstance()->DoEvents();
    
    

     

    You can add functions like (it's an example for the mentioned yang stuff):

    
                auto currentGold = rkPlayer.GetStatus(POINT_GOLD);
                auto goldChange = PointChange.value - currentGold;
                Timeline::GetInstance()->AddFunction(0.5f, 
                    [currentGold, goldChange](float p)
                    {
                        CPythonPlayer& rkPlayer = CPythonPlayer::Instance();
                        rkPlayer.SetStatus(POINT_GOLD, currentGold + (goldChange * p));
                    },
                    [currentGold, goldChange]()
                    {
                        CPythonPlayer& rkPlayer = CPythonPlayer::Instance();
                        rkPlayer.SetStatus(POINT_GOLD, currentGold + goldChange);
                    }
                );
    
    

    Download: https://distraught.hu/download/m2dev/Timeline.rar

     

    Good luck!

     

     

    -----------------------

    Oh and if you can't compile it because the compiler does not find ModernSingleton then here it is:

    
    template<typename T>
    struct ModernSingleton
    {
        static T* GetInstance()
        {
            static T _instance;
            return &_instance;
        }
    };
    
    

    (just add it to like singleton.h)

    • Metin2 Dev 4
    • Angry 1
    • Good 2
    • Love 6
×
×
  • 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.