Odkryj najlepsze prywatne serwery Metin2. Głosuj na ulubione, poznawaj nowe społeczności i znajdź swoją następną przygodę w grze.
Łatwe, darmowe i niezawodne nagrody za głosowanie dla prywatnego serwera Metin2
Nasz system weryfikacji głosów to nowoczesne i innowacyjne rozwiązanie stworzone specjalnie dla prywatnych serwerów Metin2. Zapewnia angażujący sposób, by gracze głosowali na ulubione serwery i otrzymywali korzyści w grze.
System jest zarówno łatwy do wdrożenia, jak i bardzo niezawodny, co czyni go idealnym wyborem dla właścicieli serwerów, którzy chcą zwiększyć zaangażowanie graczy i widoczność serwera.
Naszym celem jest stworzenie sytuacji korzystnej dla wszystkich: gracze otrzymują nagrody za lojalność, a serwery zyskują większą widoczność i aktywność.
Kompletny system głosowania i nagród z dedykowanym interfejsem w grze
Vote4Buff to nasze premium, kompletne rozwiązanie do głosowania, obejmujące atrakcyjny interfejs w grze, komunikację WebSocket i pełną integrację z serwerem. Gracze mogą głosować, wybierać spośród wielu zestawów bonusów i natychmiast otrzymywać nagrody bez opuszczania gry!
System Vote4Buff składa się z trzech kluczowych komponentów:
Idealne dla: właścicieli serwerów, którzy chcą profesjonalnego, gotowego rozwiązania bez tygodni własnego developmentu. Wystarczy skonfigurować zestawy bonusów, wdrożyć pliki i gotowe!
Uzyskaj wszystkie potrzebne pliki do integracji po stronie klienta i serwera
Vote4Buff został przygotowany dla bazy źródłowej martysama0134 v5.8. Jeśli korzystasz z innego źródła, mogą być potrzebne dodatkowe modyfikacje.
Zawiera libcurl.dll (wersja 32-bit w zestawie, 64-bit dostępna)
W zestawie znajdują się wszystkie niezbędne modyfikacje źródeł C++
Prosimy zaloguj się, aby pobrać pliki Vote4Buff.
Skonfiguruj zestawy bonusów, nagrody przedmiotowe i ustawienia API
Cała konfiguracja Vote4Buff odbywa się w pliku char.h na Twoim serwerze. Poniżej znajdziesz szczegółowe przykłady dla każdej opcji.
Najpierw ustaw ID serwera i token API (znajdziesz je w panelu serwera):
// API SETTINGS from Metin2 Server List
static const std::string s_VOTE4BUFF_SERVER_ID = "YOUR_SERVER_ID"; // From dashboard
static const std::string s_VOTE4BUFF_API_TOKEN = "YOUR_API_TOKEN"; // From dashboard
static const int s_VOTE4BUFF_DURATION = 86400; // seconds (1 day) DO NOT MODIFY THIS !!!
Możesz zdefiniować maksymalnie 3 zestawy bonusów, z których gracze mogą wybierać. Każdy zestaw może zawierać wiele bonusów:
// Bonuses must be set with its APPLY_ declaration.
// You can add as many bonuses as you want per slot.
static std::vector<std::vector<std::pair<int, int>>> s_VOTE4BUFF_BONUSES =
{
{ // Bonus Pool 1: PvP Focused
{ APPLY_ATTBONUS_HUMAN, 5 }, // +5% vs Players
{ APPLY_DEF_GRADE_BONUS, 50 }, // +50 Defense
// Add more bonuses if wanted
},
{ // Bonus Pool 2: PvE Focused
{ APPLY_ATTBONUS_MONSTER, 5 }, // +5% vs Monsters
{ APPLY_ATTBONUS_INSECT, 5 }, // +5% vs Insects
{ APPLY_HP_REGEN, 10 }, // +10 HP Regen
},
{ // Bonus Pool 3: Farm Focused
{ APPLY_ITEM_DROP_BONUS, 10 }, // +10% Drop Rate
{ APPLY_EXP_DOUBLE_BONUS, 10 }, // +10% EXP
{ APPLY_GOLD_FIND, 15 }, // +15% Gold
},
};
Popularne typy bonusów: APPLY_ATTBONUS_HUMAN, APPLY_ATTBONUS_MONSTER, APPLY_DEF_GRADE_BONUS, APPLY_ITEM_DROP_BONUS, APPLY_EXP_DOUBLE_BONUS, APPLY_GOLD_FIND, APPLY_MAX_HP, APPLY_MAX_SP, APPLY_HP_REGEN, APPLY_SP_REGEN, APPLY_CRITICAL_PCT, APPLY_PENETRATE_PCT i wiele innych!
Skonfiguruj przedmioty, które gracze otrzymują automatycznie po weryfikacji głosu:
static std::vector<std::pair<DWORD, int>> s_VOTE4BUFF_ITEM_REWARDS =
{
// Leave empty if you don't want to give any items as rewards
// Format: { vnum, count }
{ 27007, 5 }, // 5x Red Potion (XXL)
{ 50084, 1 }, // 1x Gold Bar
{ 71027, 10 }, // 10x Dragon Coin
};
Kontroluj czas odnowienia i koszt, gdy gracze chcą zmienić zestaw bonusów:
// Cooldown when changing bonus (does not apply when choosing right after voting)
static const int s_VOTE4BUFF_CHANGE_BONUS_COOLDOWN = 300; // seconds (5 minutes)
// Price when changing bonus (does not apply when choosing right after voting)
static const int s_VOTE4BUFF_CHANGE_BONUS_PRICE = 15000; // yang (0 = free)
Uwaga: Po oddaniu głosu gracze mogą wybrać zestaw bonusów za darmo. Czas odnowienia i opłata obowiązują tylko przy zmianie zestawu bez ponownego głosowania.
Krok po kroku, jak zintegrować Vote4Buff
Wykonaj kopie zapasowe plików klienta i serwera! Pliki z prefixem __ wymagają scalenia, pozostałe można kopiować bez zmian.
Otwórz plik Source/Server/__char.h z pobranej paczki.
class CBuffOnAttributes; i dodaj nad nim kod konfiguracji (zobacz sekcję Konfiguracja)s_VOTE4BUFF_SERVER_ID oraz s_VOTE4BUFF_API_TOKENbool DragonSoul_RefineWindow_CanRefine(); i dodaj deklaracje metod publicznychZintegruj pliki serwerowe z paczki:
__affect.h - Scal zmiany z własnym plikiem affect.h__chat_affect.cpp - Dodaj obsługę efektu Vote4Buff__cmd_general.cpp - Rozszerz obsługę komend__desc_client.cpp - Zmodyfikuj deskryptor klientaUwaga: Pliki z prefixem __ wymagają ręcznego połączenia ze swoimi plikami.
Skompiluj serwer gry z wprowadzonymi zmianami.
make clean && make
Z katalogu Client/root/:
uivote4buff.py do katalogu root/ klienta
__constInfo.py__game.py__interfaceModule.py__uiAffectShower.pyClient/ui/game/vote4buff/ do swojego katalogu ui/game/
Client/uiscript/vote4buffwindow.py do folderu uiscript
Dodaj lokalizacje dla obsługiwanych języków z katalogu Client/locale/:
__locale_game.txt do swojego locale_game.txt
__locale_interface.txt do locale_interface.txt
Obsługiwane języki: EN, DE, ES, PL, TR, RO, IT, PT, HU, GR, CZ
Z katalogu Source/Client/UserInterface/:
M2WebSocket.cpp oraz M2WebSocket.h do katalogu UserInterface
__ w swoich plikach
libcurl.dll znajduje się w katalogu klienta (wersja 32-bit w zestawie, 64-bit do pobrania)
Vote4Buff nie dodaje domyślnego przycisku. Musisz wywołać ToggleVote4Buff() w swojej UI, na przykład:
Możesz użyć klasy Vote4BuffButton, która tworzy przesuwalny przycisk z ikoną
Przebuduj plik wykonywalny klienta z nowymi zmianami.
Przetestuj integrację:
Twoi gracze mogą teraz głosować i automatycznie otrzymywać nagrody. Interfejs Vote4Buff pokazuje, kiedy mogą głosować, pozwala wybrać bonus i wyświetla liczniki dla aktywnych efektów.
Większość nowych graczy znajduje serwery poprzez toplisty, co czyni je kluczowym narzędziem marketingowym
Szczegółowa dokumentacja i instrukcje krok po kroku czynią konfigurację banalną
Łatwy proces integracji REST API
Weryfikacja głosu po stronie klienta minimalizuje obciążenie serwera
Sprawdzony system z wbudowanymi zabezpieczeniami przeciw oszustwom
Upewnij się, że gracze faktycznie zagłosowali, zanim otrzymają nagrody
System posiada prosty i intuicyjny przebieg, który gracze łatwo rozumieją. Co najważniejsze, weryfikacja głosu odbywa się przez nasze API, więc masz pewność, że nagradzasz prawdziwe głosy!
Na Twojej stronie lub w interfejsie gry
Gracz trafia na stronę głosowania Twojego serwera w topliscie
Gracz wykonuje CAPTCHA i wysyła głos
Twój serwer sprawdza głos przez nasze API
Twój serwer przyznaje nagrodę w grze
Wybierz metodę integracji odpowiednią dla Twoich potrzeb:
Gotowe rozwiązanie z interfejsem w grze, komunikacją WebSocket i automatycznymi nagrodami.
Zbuduj własną implementację przy użyciu naszego REST API, aby mieć pełną kontrolę.
Utwórz konto i dodaj swój serwer do naszej toplisty pod https://metin2-toplist.net/servers/create
Znajdź unikalne ID serwera i token API w panelu serwera. Są wymagane do autoryzacji.
Pobierz Vote4Buff dla gotowego rozwiązania lub skorzystaj z API, aby zbudować własne.
Dokładnie przetestuj system głosowania, następnie wdroż go na serwerze produkcyjnym.
Jeśli korzystasz z systemu Vote4Buff (zalecane), ten endpoint jest już zintegrowany! Ta sekcja przeznaczona jest dla właścicieli serwerów, którzy chcą zbudować własne rozwiązanie.
https://metin2-toplist.net/api/check-vote
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
api_token |
string | Tak | Unikalny token API Twojego serwera |
ip |
string | Opcjonalnie* | Adres IP gracza (IPv4 lub IPv6) |
account_id |
string | Opcjonalnie* | ID/nazwa konta gracza dla dokładniejszego śledzenia |
Najlepsze rezultaty uzyskasz korzystając z parametru <code>account_id</code>, aby dokładnie identyfikować graczy. Metoda <code>ip</code> może być mniej wiarygodna, jeśli używają VPN lub grają z różnych miejsc.
Kieruj graczy na głosowanie za pomocą następującego adresu:
https://metin2-toplist.net/vote.{lang}/{server_id}-{server_slug}/{account_id}
Przykłady:
https://metin2-toplist.net/vote.en/123-awesome-server/PlayerName
https://metin2-toplist.net/vote.de/123-awesome-server/PlayerName
https://metin2-toplist.net/vote.tr/123-awesome-server/PlayerName
Obsługiwane języki: en, de, es, pl, tr, ro, it, pt, hu, gr, cz
API zwraca odpowiedź JSON o następującej strukturze:
{
"success": true,
"voted": true,
"last_vote": "2025-11-11T14:30:00Z",
"next_vote_in": 0,
"message": "Vote verified successfully"
}
{
"success": true,
"voted": false,
"message": "No recent vote found"
}
{
"success": false,
"message": "Invalid API token"
}
| Pole | Typ | Opis |
|---|---|---|
success |
boolean | Czy żądanie API zakończyło się powodzeniem |
voted |
boolean | Czy znaleziono ważny głos (tylko gdy success=true) |
last_vote |
string | Znacznik czasu ISO 8601 ostatniego głosu (tylko gdy voted=true) |
next_vote_in |
integer | Liczba sekund do następnego dozwolonego głosu (tylko gdy voted=true) |
message |
string | Opisowy komunikat wyjaśniający wynik |
<?php
function checkVote($apiToken, $playerIP) {
$url = "https://metin2-toplist.net/api/check-vote";
$params = http_build_query([
'api_token' => $apiToken,
'ip' => $playerIP
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
return ['success' => false, 'message' => 'API request failed'];
}
return json_decode($response, true);
}
// Usage Example
$apiToken = 'YOUR_API_TOKEN_HERE';
$playerIP = $_SERVER['REMOTE_ADDR']; // Or get from your game server
$result = checkVote($apiToken, $playerIP);
if ($result['success'] && $result['voted']) {
// Player has voted! Give reward
echo "Vote verified! Rewarding player...";
giveReward($playerName); // Your reward function
} else {
echo "No valid vote found. Please vote first!";
}
?>
import requests
import json
def check_vote(api_token, player_ip):
"""
Check if a player has voted for the server
"""
url = "https://metin2-toplist.net/api/check-vote"
params = {
'api_token': api_token,
'ip': player_ip
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {'success': False, 'message': f'API request failed: {str(e)}'}
# Usage Example
api_token = 'YOUR_API_TOKEN_HERE'
player_ip = '123.456.789.012'
result = check_vote(api_token, player_ip)
if result.get('success') and result.get('voted'):
print("Vote verified! Rewarding player...")
# Give reward to player
else:
print("No valid vote found. Please vote first!")
#include <curl/curl.h>
#include <string>
#include <sstream>
// Callback function for cURL
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
bool CheckVote(const std::string& apiToken, const std::string& playerIP) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
std::ostringstream url;
url << "https://metin2-toplist.net/api/check-vote"
<< "?api_token=" << apiToken
<< "&ip=" << playerIP;
curl_easy_setopt(curl, CURLOPT_URL, url.str().c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res == CURLE_OK) {
// Parse JSON response (you'll need a JSON library like nlohmann/json)
// Check if readBuffer contains "\"voted\":true"
return readBuffer.find("\"voted\":true") != std::string::npos;
}
}
return false;
}
// Usage in your game server
void OnPlayerRequestReward(const std::string& playerName, const std::string& playerIP) {
std::string apiToken = "YOUR_API_TOKEN_HERE";
if(CheckVote(apiToken, playerIP)) {
// Give reward to player
GiveItemToPlayer(playerName, REWARD_ITEM_VNUM, REWARD_COUNT);
SendNotice("Vote verified! You received your reward!");
} else {
SendNotice("No valid vote found. Please vote first!");
}
}
async function checkVote(apiToken, playerIP) {
const url = new URL('https://metin2-toplist.net/api/check-vote');
url.searchParams.append('api_token', apiToken);
url.searchParams.append('ip', playerIP);
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('API request failed:', error);
return { success: false, message: error.message };
}
}
const apiToken = 'YOUR_API_TOKEN_HERE';
const playerIP = '123.456.789.012';
checkVote(apiToken, playerIP).then(result => {
if (result.success && result.voted) {
console.log('Vote verified! Rewarding player...');
// Give reward to player
} else {
console.log('No valid vote found. Please vote first!');
}
});
Przechowuj token API w bezpiecznym miejscu i nigdy nie udostępniaj go w kodzie po stronie klienta. Wszystkie żądania API wykonuj z backendu serwera.
Dodaj na stronie lub w grze przycisk, który przekieruje graczy na stronę głosowania pod adresem https://metin2-toplist.net/servers/YOUR-SERVER-SLUG.
Gdy gracz prosi o nagrodę (na stronie lub w grze), wykonaj poniższe kroki:
voted to true, przyznaj nagrodęDobre praktyki przy przyznawaniu nagród:
Rozwiązanie: Sprawdź, czy używasz poprawnego tokena API z panelu serwera. Upewnij się, że nie ma dodatkowych spacji ani znaków.
Możliwe przyczyny:
Rozwiązanie: Upewnij się, że serwer może wykonywać zapytania HTTPS. Sprawdź ustawienia firewalla i zaimplementuj ponawianie z backoffem wykładniczym.
Rozwiązanie: Prowadź lokalny rejestr nagrodzonych głosów. Zapisuj znacznik czasu i wydaj nagrodę tylko raz.
Rozwiązanie: Upewnij się, że przesyłasz pełny adres IPv6. Nasze API obsługuje zarówno IPv4, jak i IPv6.
Przetestuj integrację na koncie testowym przed wdrożeniem na produkcję. Upewnij się, że obsługujesz wszystkie przypadki brzegowe i błędy.