GİRİŞ & PROBLEM
Merhaba, bir üyenin ricası ile clientlerin (.exe) görev çubuğunda üst üste binmesini engelleyip, tüm clientlerin ayrı ayrı açılmasıyla alakalı bir düzenleme yaptım, belki ihtiyacı olan vardır diye paylaşıyorum.
NELERİ DEĞİŞTİRDİK ?
Açılan her .exe için farklı bir ID oluşturarak işletim sisteminin bunları aynı uygulama olarak görmemesini sağlayacağız, bu benzersiz oluşturulan ID'ler sayesinde her .exe farklı olacak ve üst üste binmeyecek.
NASIL YAPILIR ?
Sadece tek bir dosyada değişiklik yapacağız, Client src/UserInterface içinden "UserInterface.cpp" dosyası açılır.
Merhaba, bir üyenin ricası ile clientlerin (.exe) görev çubuğunda üst üste binmesini engelleyip, tüm clientlerin ayrı ayrı açılmasıyla alakalı bir düzenleme yaptım, belki ihtiyacı olan vardır diye paylaşıyorum.
NELERİ DEĞİŞTİRDİK ?
Açılan her .exe için farklı bir ID oluşturarak işletim sisteminin bunları aynı uygulama olarak görmemesini sağlayacağız, bu benzersiz oluşturulan ID'ler sayesinde her .exe farklı olacak ve üst üste binmeyecek.
NASIL YAPILIR ?
Sadece tek bir dosyada değişiklik yapacağız, Client src/UserInterface içinden "UserInterface.cpp" dosyası açılır.
Kod:
// In cludeların en sonuna eklenir; // UNIQUE_CLIENT_ID #include <shobjidl.h> #include <sstream> // END_OF_UNIQUE_CLIENT_ID
Kod:
// BULUNUR; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) // ÜSTÜNE EKLENİR; (Dikkat, fonksiyonun dışına!) // UNIQUE_CLIENT_ID std::wstring GenerateAppUserModelID() { std::wstringstream ss; ss << L"Metin2_" << GetCurrentProcessId(); return ss.str(); } // END_OF_UNIQUE_CLIENT_ID // BULUNUR; #ifdef _DEBUG _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF ); #endif // ALTINA EKLENİR; // UNIQUE_CLIENT_ID std::wstring appUserModelID = GenerateAppUserModelID(); SetCurrentProcessExplicitAppUserModelID (appUserModelID.c_str()); // END_OF_UNIQUE_CLIENT_ID
C++ ile Metin2 Clientlerin (.exe) Üst Üste Binmesini Engelleme Yöntemleri
Metin2 özel sunucularında client tarafında geliştirme yaparken, birden fazla clientin aynı anda çalıştırılması istenmeyen durumlara neden olabilir. Özellikle PVP sistemlerinde ya da turnuvalarda, bir oyuncunun birden fazla hesap ile aynı anda oyunda olup hileli yollarla avantaj elde etmesi gibi senaryolar söz konusu olabilir. Bu durumda, client dosyasının birden fazla kez çalıştırılmasını engellemek büyük önem taşır. Bu yazıda, C++ dilinde yazılmış bir Metin2 clientinin birden fazla kez çalıştırılmasını nasıl önleyebileceğimizi ele alacağız.
Neden Birden Fazla Client Çalıştırılması Sorun Olur?
Metin2 özel sunucularında, client dosyası (.exe) doğrudan kullanıcıya verilir. Eğer bu client birden fazla kez çalıştırılırsa, aynı kullanıcı birden fazla karakter ile oyuna girebilir. Bu durum özellikle PVP sistemlerinde ciddi dengesizliklere yol açabilir. Ayrıca, bazı hile programları da birden fazla client üzerinden çalışarak avantaj sağlayabilir. Bu nedenle clientin sadece bir kez çalıştırılmasını sağlamak, hem adil oyun hem de güvenlik açısından kritik bir konudur.
Mutex Kullanımı ile Clientin Tek Seferliğine Çalıştırılması
Windows ortamında bir uygulamanın birden fazla kez çalıştırılmasını engellemenin en yaygın yolu mutex adı verilen sistem nesnesini kullanmaktır. Mutex, aynı anda sadece bir işlemin erişimine izin veren bir tür kilittir. C++ ile yazılmış bir client içinde bir mutex oluşturulduğunda, program başlatıldığında bu mutex kontrol edilir. Eğer aynı adda bir mutex daha önce oluşturulmuşsa, ikinci kez çalışan clientin çalışması engellenir.
Örnek Kod Yapısı:
Kod:
HANDLE hMutex = CreateMutex(NULL, TRUE, L'Metin2ClientInstance');[BR][/BR][BR][/BR]if (GetLastError() == ERROR_ALREADY_EXISTS) {[BR][/BR] MessageBox(NULL, L'Client zaten çalışıyor!', L'Hata', MB_OK);[BR][/BR] return 0;[BR][/BR]}
Yukarıdaki örnekte, Metin2ClientInstance adında bir mutex oluşturuluyor. Eğer bu mutex daha önce oluşturulmuşsa, yani başka bir instance çalışıyor ise, GetLastError() fonksiyonu ERROR_ALREADY_EXISTS döndürür ve yeni çalışan client başlatılmaz. Bu sayede clientin sadece bir kez çalışması sağlanmış olur.
Diğer Alternatifler
Mutex dışında, aynı işi yapabilecek başka yöntemler de mevcuttur. Örneğin, client başlatılırken belirli bir portun açık olup olmadığına bakılabilir. Eğer port doluysa, başka bir clientin çalıştığı anlaşılır. Ancak bu yöntem, clientin internete bağlı olması gerektiği için her zaman uygun değildir. Mutex yöntemi, sistem seviyesinde işlem yaptığı için daha güvenlidir ve her platformda çalışabilir.
Not: Mutex adı benzersiz olmalıdır. Aksi takdirde farklı uygulamalar arasında çakışma olabilir. Mutex adı olarak, clientin adı ya da GUID gibi benzersiz değerler kullanılabilir.
Metin2 Client Kaynak Kodlarında Uygulama
Metin2 client kaynak kodları genellikle Python tabanlı arayüzlerle (uiscript) ve C++ motoruyla birleşerek çalışır. Ancak gerçek engine kısmı C++ ile yazılmıştır. Bu nedenle mutex kontrolü, clientin başlatıldığı ana C++ dosyasında yapılmalıdır. Örneğin, Main.cpp veya Entry Point olarak tanımlanan yerde bu kontrol yapılmalıdır. Böylece client başlatılmadan önce, başka bir instance çalışıp çalışmadığı kontrol edilir.
Sonuç
Clientin birden fazla kez çalıştırılmasının önüne geçmek, Metin2 özel sunucularında güvenliği artırmak ve oyun içi dengeyi korumak için önemli bir adımdır. C++ ile geliştirilmiş clientlerde mutex kullanımı, bu iş için oldukça etkili ve kolay bir çözümdür. Doğru uygulandığında, clientin aynı anda sadece bir kez çalıştırılmasını garantileyebilir. Bu tür küçük ama etkili geliştirmeler, hem kullanıcı deneyimini artırır hem de sunucu sahiplerinin karşılaştığı potansiyel sorunları azaltır.
Preventing Multiple Instances of Metin2 Clients (.exe) with C++
When developing on the client side for Metin2 private servers, running multiple clients simultaneously can lead to unwanted scenarios. Particularly in PVP systems or tournaments, a player might gain unfair advantages by logging into the game with multiple accounts at the same time. In such cases, preventing the client file from being executed more than once becomes crucial. In this article, we will examine how to prevent multiple instances of a Metin2 client written in C++.
Why Running Multiple Clients Is Problematic?
In Metin2 private servers, the client file (.exe) is directly provided to the user. If this client is run multiple times, the same user may enter the game with multiple characters. This situation can cause serious imbalances, especially in PVP systems. Additionally, some cheat programs can exploit multiple client instances to gain unfair advantages. Therefore, ensuring that the client runs only once is critical for both fair gameplay and security.
Using Mutex to Ensure Single Client Execution
The most common way to prevent a Windows application from running multiple times is by using a system object called mutex. A mutex is a type of lock that allows only one process access at a time. When a mutex is created within a C++ client application, it is checked upon startup. If a mutex with the same name already exists, the second instance of the client is prevented from launching.
Sample Code Structure:
Kod:
HANDLE hMutex = CreateMutex(NULL, TRUE, L'Metin2ClientInstance');[BR][/BR][BR][/BR]if (GetLastError() == ERROR_ALREADY_EXISTS) {[BR][/BR] MessageBox(NULL, L'Client is already running!', L'Error', MB_OK);[BR][/BR] return 0;[BR][/BR]}
In the above example, a mutex named Metin2ClientInstance is created. If this mutex already exists, meaning another instance is running, the GetLastError() function returns ERROR_ALREADY_EXISTS, and the new client instance is not started. This ensures the client runs only once.
Alternative Methods
Besides mutex, other methods can also achieve the same result. For example, during startup, the client could check if a specific port is open. If the port is occupied, it indicates another client instance is active. However, this approach requires the client to be connected to the internet, which may not always be suitable. The mutex method is more reliable since it operates at the system level and works across all platforms.
Note: The mutex name must be unique. Otherwise, conflicts between different applications may occur. Unique values such as the client's name or a GUID can be used for the mutex name.
Implementation in Metin2 Client Source Code
Metin2 client source codes typically combine Python-based interfaces (uiscript) with a C++ engine. However, the actual engine part is written in C++. Therefore, the mutex check should be placed where the client starts up—typically in the main C++ file such as Main.cpp or the entry point. This ensures that before the client launches, any other running instance is detected and blocked.
Conclusion
Preventing a client from running multiple times is an important step towards enhancing security and maintaining balance in Metin2 private servers. Using mutex in C++-based clients is a highly effective and straightforward solution for this purpose. When implemented correctly, it guarantees that the client runs only once. Such small but impactful improvements enhance the user experience and reduce potential issues faced by server owners.
