Introduction

Metin2 Vote Verification System

Easy, Free & Reliable Voting Rewards for Your Metin2 Private Server

What is the Vote Verification System?

Our Vote Verification System is a modern and innovative solution designed specifically for Metin2 Private Servers. It provides an engaging way for players to vote for their favorite servers while receiving in-game benefits.

The system is both easy to implement and highly reliable, making it an excellent choice for server owners looking to increase player engagement and server visibility.

Our goal is to create a win-win situation for both players and server owners. Players get rewarded for their loyalty with in-game benefits, while servers benefit from increased visibility and higher player engagement.

Vote4Buff

Vote4Buff System (Recommended)

Complete In-Game Voting & Reward System with Custom UI

What is Vote4Buff?

Vote4Buff is our premium all-in-one voting solution that includes a beautiful in-game UI, WebSocket communication, and complete server integration. Players can vote, select from multiple bonus pools, and receive instant rewards without ever leaving the game!

System Architecture

The Vote4Buff system consists of three main components:

Client Side
  • Python UI system (uivote4buff.py)
  • Custom UI assets & graphics
  • C++ WebSocket integration
  • 11 language support
Server Side
  • C++ API integration
  • Bonus pool management
  • Item reward system
  • Real-time affect tracking
Our Platform
  • Vote verification API
  • Account-based tracking
  • Anti-cheat protection
  • Real-time vote status

Key Features

Multiple Bonus Pools: Up to 3 configurable bonus pools players can choose from
Item Rewards: Automatically give items upon successful vote
Real-Time UI: Live countdown timers and affect tracking in-game
WebSocket Communication: Instant verification without page refreshes
Multi-Language: Supports 11 languages (EN, DE, ES, PL, TR, RO, IT, PT, HU, GR, CZ)
Customizable Rewards: Configure bonuses, duration, and pricing

Perfect for: Server owners who want a professional, ready-to-use solution without spending weeks on custom development. Simply configure the bonus pools, integrate the files, and you're ready to go!

Download

Download Vote4Buff Files

Get all the files you need for client and server integration

Requirements

Vote4Buff is designed for martysama0134 v5.8 source base. If you're using a different source, some modifications may be required.

Package Contents

Client Files
  • Python UI files (uivote4buff.py)
  • Game file modifications
  • UI graphics & assets
  • 11 language locale files
  • C++ WebSocket implementation
  • UI script files

Includes libcurl.dll (32-bit included, 64-bit available)

Server Files
  • char.h configuration
  • Affect system modifications
  • Chat command integration
  • API communication layer
  • Bonus management system

All necessary C++ source modifications included

Login Required

Please login to download Vote4Buff files.

Configuration

Configuration Guide

Configure bonus pools, item rewards, and API settings

All Vote4Buff configuration is done in the char.h file on your server. Below are detailed examples of each configuration option.

Step 1: API Credentials

First, you'll need to configure your Server ID and API Token (found in your dashboard):

C++
// 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 !!!

Step 2: Configure Bonus Pools

You can define up to 3 bonus pools that players can choose from. Each pool can contain multiple bonuses:

C++
// 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
    },
    { // 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
    },
};
Available APPLY Types

Common bonus types: 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, and many more!

Step 3: Item Rewards (Optional)

Configure items that players receive automatically upon voting:

C++
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
};

Step 4: Bonus Change Settings

Control cooldown and pricing when players want to switch between bonus pools:

C++
// 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)

Note: After players vote, they can choose a bonus pool for FREE. The cooldown and price only apply when they want to switch pools later without voting again.

Installation

Installation Guide

Step-by-step instructions for integrating Vote4Buff

Before You Begin

Make sure you have backups of your client and server files! File naming convention: Files with __ prefix need modifications, files without prefix can be copied directly.

Server Installation

1
Configure char.h

Open Source/Server/__char.h from the downloaded package.

  • Locate class CBuffOnAttributes; and add the configuration code above it (see Configuration section)
  • Set your s_VOTE4BUFF_SERVER_ID and s_VOTE4BUFF_API_TOKEN
  • Configure your bonus pools and item rewards
  • Locate bool DragonSoul_RefineWindow_CanRefine(); and add the public method declarations
2
Apply Server Modifications

Integrate the server-side files from the package:

  • __affect.h - Modify your existing affect.h with the provided changes
  • __chat_affect.cpp - Add Vote4Buff affect handling
  • __cmd_general.cpp - Add command processing
  • __desc_client.cpp - Client descriptor modifications

Note: Files with __ prefix indicate you need to merge the changes into your existing files.

3
Recompile Game Core

Compile your game server with the new modifications.

make clean && make

Client Installation

4
Python UI Files

From the Client/root/ folder:

  • Copy uivote4buff.py to your client's root/ folder
  • Modify the following files as indicated:
    • __constInfo.py
    • __game.py
    • __interfaceModule.py
    • __uiAffectShower.py
5
UI Graphics & Scripts
  • Copy Client/ui/game/vote4buff/ folder to your pack's ui/game/ directory
  • Copy Client/uiscript/vote4buffwindow.py to your uiscript folder
6
Language Files

Add locale strings for your supported languages from Client/locale/:

  • Append __locale_game.txt content to your locale_game.txt
  • Append __locale_interface.txt content to your locale_interface.txt

Available languages: EN, DE, ES, PL, TR, RO, IT, PT, HU, GR, CZ

7
C++ Client Modifications

From Source/Client/UserInterface/:

  • Copy M2WebSocket.cpp and M2WebSocket.h to your UserInterface folder
  • Apply modifications from files with __ prefix to your existing files
  • Ensure libcurl.dll is in your client directory (32-bit included, download 64-bit if needed)
8
Add UI Button (Optional)

Vote4Buff doesn't add a default button. You need to call ToggleVote4Buff() from somewhere in your UI. For example:

  • Add a button to your SystemDialog
  • Bind it to a hotkey
  • Add it to your QuickSlot menu

Or use the included Vote4BuffButton class which creates a draggable icon button

9
Recompile Client

Rebuild your client executable with the new modifications.

10
Testing

Test the integration:

  1. Login to your server
  2. Open the Vote4Buff window
  3. Vote on our platform: https://metin2-toplist.net/vote/en/YOUR_SERVER_ID-server-name/YOUR_ACCOUNT_ID
  4. Return to game and verify your vote
  5. Select a bonus pool and check if affects are applied
  6. Verify item rewards were received
Installation Complete!

Your players can now vote and receive rewards automatically. The Vote4Buff UI will show them when they can vote, let them choose bonus pools, and display countdown timers for active affects.

Benefits

Advantages for Server Admins

Free Promotion

Most new players discover servers through toplists, making it an essential marketing tool

Simple Configuration

Detailed documentation and step-by-step guides make setup a breeze

Zero Coding Required

Straightforward REST API integration process

Optimized Performance

Client-side vote verification ensures minimal server load

Highly Reliable

Battle-tested system with built-in fraud prevention

Vote Verification

Ensure players really voted for your server before rewards

Advantages for Players

Receive in-game rewards for voting
Easy-to-use voting interface
Clear vote cooldown timer display
Guaranteed reward delivery system
Process

How Does the System Work?

The system features a clean and intuitive flow that players can easily understand. Best of all, vote checking happens via our API, ensuring you can verify legitimate votes!

1. Player Clicks Vote Button — From your website or in-game interface
2. Redirect to Vote Page — Player is redirected to your server's voting page on our toplist
3. Player Votes — Player completes CAPTCHA and submits vote
4. API Verification — Your server queries our API to verify the vote
5. Reward Player — Your server grants the in-game reward
Quick Start

Getting Started - Quick Start Guide

Choose your integration method based on your needs:

RECOMMENDED
Vote4Buff System

Complete all-in-one solution with custom UI, WebSocket communication, and automatic reward system.

  • Full in-game UI
  • Multiple bonus pools
  • Automatic item rewards
  • Real-time countdown timers
  • 11 languages support
Start with Vote4Buff
Custom API Integration

Build your own implementation using our REST API for maximum flexibility and control.

  • Full customization
  • Your own UI design
  • Custom reward logic
  • IP or Account-based
Use Basic API

General Setup Steps

1
Register Your Server

Create an account and add your server to our toplist at https://metin2-toplist.net/servers/create

2
Get Your API Credentials

Find your unique Server ID and API Token in your server dashboard. These are required for authentication.

3
Choose Your Integration Method

Download Vote4Buff for a ready-to-use solution, or integrate our API for custom implementation.

4
Test & Deploy

Test the voting system thoroughly, then deploy to your live server.

Reference

API Endpoint (For Custom Implementations)

Note

If you're using the Vote4Buff System (recommended), this API is already integrated! This section is for server owners who want to build custom implementations.

GET https://metin2-toplist.net/api/check-vote

Required Parameters

Parameter Type Required Description
api_token string Yes Your server's unique API token
ip string Optional* Player's IP address (IPv4 or IPv6)
account_id string Optional* Player's account ID/username for more accurate tracking
*Either ip or account_id (or both) must be provided

For best results, use <code>account_id</code> for accurate player tracking. The <code>ip</code> method can be less reliable if players use VPNs or play from different locations.

Vote URL Format

Direct players to vote using this URL structure:

https://metin2-toplist.net/vote.{lang}/{server_id}-{server_slug}/{account_id}

Examples:
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

Supported languages: en, de, es, pl, tr, ro, it, pt, hu, gr, cz

Response Format

The API returns a JSON response with the following structure:

Success Response
{
    "success": true,
    "voted": true,
    "last_vote": "2025-11-11T14:30:00Z",
    "next_vote_in": 0,
    "message": "Vote verified successfully"
}
No Vote Found Response
{
    "success": true,
    "voted": false,
    "message": "No recent vote found"
}
Error Response
{
    "success": false,
    "message": "Invalid API token"
}

Response Fields

Field Type Description
success boolean Whether the API request was successful
voted boolean Whether a valid vote was found (only present if success=true)
last_vote string ISO 8601 timestamp of the last vote (only if voted=true)
next_vote_in integer Seconds until next vote is allowed (only if voted=true)
message string Human-readable message describing the result
Examples

Code Examples

PHP Example

PHP cURL Implementation
<?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);
}

$result = checkVote('YOUR_API_TOKEN', $_SERVER['REMOTE_ADDR']);
if ($result['success'] && $result['voted']) {
    echo "Vote verified! Rewarding player...";
}
?>

Python Example

Python Requests Implementation
import requests

def check_vote(api_token, player_ip):
    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)}'}

result = check_vote('YOUR_API_TOKEN', '123.456.789.012')
if result.get('success') and result.get('voted'):
    print("Vote verified! Rewarding player...")

C++ Example (for Game Servers)

C++ libcurl Implementation
#include <curl/curl.h>
#include <string>
#include <sstream>

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 = curl_easy_init();
    if (!curl) return false;

    std::string readBuffer;
    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);

    CURLcode res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    return (res == CURLE_OK) && (readBuffer.find("\"voted\":true") != std::string::npos);
}

void OnPlayerRequestReward(const std::string& playerName, const std::string& playerIP) {
    if (CheckVote("YOUR_API_TOKEN", playerIP)) {
        GiveItemToPlayer(playerName, REWARD_ITEM_VNUM, REWARD_COUNT);
        SendNotice("Vote verified! You received your reward!");
    } else {
        SendNotice("No valid vote found. Please vote first!");
    }
}

JavaScript/Node.js Example

Node.js Fetch Implementation
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 ${response.status}`);
        return await response.json();
    } catch (error) {
        return { success: false, message: error.message };
    }
}

checkVote('YOUR_API_TOKEN', '123.456.789.012').then(result => {
    if (result.success && result.voted) {
        console.log('Vote verified! Rewarding player...');
    }
});
Guide

Integration Guide

Security Best Practice

Always store your API token securely and never expose it in client-side code. API calls should always be made from your server backend.

Step 1: Create Vote Button/Command

Add a vote button on your website or an in-game command that directs players to your server's vote page at https://metin2-toplist.net/servers/YOUR-SERVER-SLUG.

Step 2: Implement Vote Checking

When a player requests their reward (via website or in-game command), check if they've voted:

  1. Get the player's IP address
  2. Make an API request to our check-vote endpoint
  3. Parse the JSON response
  4. If voted is true, grant the reward
  5. Store that you've given this reward to prevent duplicate claims

Step 3: Handle Rewards

Best practices for reward handling:

  • Track Given Rewards: Store in your database which votes you've already rewarded to prevent duplicate claims
  • Vote Cooldown: Respect the 24-hour cooldown between votes
  • Error Handling: Always handle API errors gracefully and inform players
  • Logging: Log all vote verifications for debugging and analytics

Example Workflow

Player: Types /vote command in-game
↓
Server: Opens browser to vote page
↓
Player: Votes on the toplist
↓
Player: Types /claim command or clicks "Claim Reward"
↓
Server: Calls API with player's IP
↓
API: Returns voted=true
↓
Server: Gives reward to player
Help

Troubleshooting

"Invalid API token" error

Solution: Double-check that you're using the correct API token from your server dashboard. Make sure there are no extra spaces or characters.

Vote not detected after player voted

Possible causes:

  • Player is using a VPN/Proxy (IP addresses don't match)
  • Vote hasn't been processed yet (wait 30 seconds and try again)
  • Wrong IP address being sent to API
  • Player voted for a different server
API timeout or connection errors

Solution: Ensure your server can make outbound HTTPS requests. Check your firewall settings. Implement retry logic with exponential backoff.

Players claiming rewards multiple times

Solution: Implement local tracking of rewarded votes. Store the vote timestamp and ensure you only reward each vote once.

IPv6 addresses not working

Solution: Ensure you're sending the full IPv6 address. Our API supports both IPv4 and IPv6.

Server Listing API

Public Server Listing API (v1)

List, submit, and claim Metin2 servers programmatically. Perfect for other toplists, server management tools, or custom integrations.

Base URL

https://metin2-toplist.net/api/v1

Rate Limits

EndpointMethodLimitAuth
/api/v1/serversGET60/min—
/api/v1/servers/{slug}GET60/min—
/api/v1/serversPOST3/hour—
/api/v1/servers/claimPOST10/hour✅

List Servers

Retrieve a paginated list of active, launched servers. Supports filtering by category and language.

ParameterTypeDefaultDescription
categorystring—Filter by category: oldschool, newschool, fun, pvp, pvm, pve
languagestring—Filter by language code: EN, DE, TR, etc.
sortstringvotesSort order: votes, newest, name
pageinteger1Page number
per_pageinteger25Results per page (max 50)
Example Request
curl -H "Accept: application/json" \
  "https://metin2-toplist.net/api/v1/servers?category=pvp&language=EN&per_page=10"

Submit a New Server

Submit a new server listing via the API. The server enters a moderation queue and must be approved before it appears publicly.

Moderation Queue

All API-submitted servers start as inactive and require manual approval. This prevents spam and ensures listing quality.

FieldTypeRequiredDescription
namestring✅Server name (max 255 chars, must be unique)
descriptionstring✅Server description (min 20, max 5000 chars)
website_urlstring—Server website URL
discord_urlstring—Discord invite URL
languagesarray✅Language codes, e.g. ["EN", "DE"] (min 1, max 5)
categorystring—One of: oldschool, newschool, fun, pvp, pvm, pve
launch_datestring—Future launch date (YYYY-MM-DD)
owner_emailstring—Contact email (optional, not shown publicly)
Submit Example
curl -X POST "https://metin2-toplist.net/api/v1/servers" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "name": "Dragon Kingdom",
    "description": "A classic PvP experience with custom dungeons and weekly events.",
    "languages": ["EN", "DE"],
    "category": "pvp",
    "website_url": "https://dragon-kingdom.com",
    "discord_url": "https://discord.gg/example"
  }'
Example Response
{
  "success": true,
  "message": "Server submitted successfully!",
  "data": {
    "id": 42,
    "slug": "dragon-kingdom",
    "status": "pending_review"
  },
  "claim_token": "a1b2c3d4...80 characters",
  "note": "Save this token! Use it to claim your listing."
}

Claim Token System

When you submit a server, you receive a unique 80-character claim token. This token lets you link the listing to your account later.

The claim token is shown only once in the API response. Save it immediately — we store only the hash.

1
Submit

POST your server to /api/v1/servers and save the claim_token from the response.

2
Register

Create an account and paste the token in the optional "Claim Token" field.

3
Manage

Your server is now linked to your account with full dashboard access.

Error Codes

CodeMeaning
200Success
201Server created (pending review)
401Authentication required (claim endpoint)
404Server not found / invalid claim token
409Server already claimed
410Claim token expired
422Validation error / spam rejected
429Rate limit exceeded

Integration Examples

PHP
$response = file_get_contents('https://metin2-toplist.net/api/v1/servers?per_page=10');
$data = json_decode($response, true);

foreach ($data['data'] as $server) {
    echo $server['name'] . ' — ' . $server['vote_count'] . ' votes' . PHP_EOL;
}
JavaScript
const res = await fetch('https://metin2-toplist.net/api/v1/servers?category=pvp');
const { data, meta } = await res.json();

data.forEach(server => {
  console.log(`${server.name}: ${server.vote_count} votes`);
});
Python
import requests

resp = requests.get('https://metin2-toplist.net/api/v1/servers', params={
    'language': 'DE',
    'sort': 'newest',
    'per_page': 20
})
servers = resp.json()['data']

for s in servers:
    print(f"{s['name']} — {s['vote_count']} votes")
Help

Support & Resources

Email Support

Get help via email

Contact Support
Discord Community

Join our community

Join Discord
Pro Tip

Test your integration thoroughly with a test account before deploying to production. Make sure to handle all edge cases and error scenarios.

Scroll to top