Cum Funcționează
API-ul Vote Rewards de la metin2.gg permite serverului tău Metin2 să detecteze automat când jucătorii votează și să acorde recompense în joc. Fluxul este simplu: jucătorii votează pe metin2.gg cu numele personajului lor, iar serverul tău interoghează API-ul nostru pentru a verifica și revendica acele voturi.
Există două moduri de integrare — alege-l pe cel potrivit configurării tale:
Polling (Recomandat)
Serverul tău apelează periodic API-ul nostru pentru a verifica voturile noi. Cel mai simplu de implementat — funcționează cu orice configurare de server Metin2. Adaugă doar o cerere HTTP la codul serverului tău de joc.
Webhooks (Avansat)
metin2.gg trimite o notificare serverului tău în momentul în care un jucător votează. În timp real, dar necesită un endpoint HTTPS accesibil public de partea ta.
Autentificare
Toate cererile API necesită o cheie API trimisă prin headerul X-API-Key. Cheile au formatul mg_live_... și sunt generate din panoul serverului tău.
X-API-Key: mg_live_5bef...1a70Cheia ta API este legată de un singur server și este afișată o singură dată la generare. Dacă o pierzi, generează una nouă din panou (cheia veche este invalidată imediat).
Cum să obții cheia API
- 1Mergi la Panoul Meu → Serverele Mele. Dă click pe numele serverului tău pentru a deschide pagina de administrare.
- 2Pe pagina de administrare, verifică proprietatea (înregistrare DNS TXT sau meta tag) dacă nu ai făcut-o deja.
- 3Adaugă un backlink către metin2.gg pe site-ul serverului tău pentru a debloca statutul de Partener.
- 4Pe pagina de administrare a serverului tău, dă click pe butonul "Setări API". Apoi dă click pe "Generează Cheie API" și copiaz-o — este afișată o singură dată.
Verifică Statusul Votului
Verifică dacă un anumit jucător are un vot nerevendicat. Dacă există un vot în așteptare, acesta este revendicat automat (marcat ca utilizat), astfel încât același vot nu poate fi revendicat de două ori.
GET /api/v1/vote/check?player_id=PlayerName HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HEREParametri de Interogare
| Parameter | Type | Required | Description |
|---|---|---|---|
| player_id | string | Yes | Numele personajului pe care jucătorul l-a folosit la vot. Insensibil la majuscule/minuscule. |
Răspuns
Jucătorul are un vot nerevendicat (acum revendicat)
{
"voted": true,
"player_id": "PlayerName",
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"voted_at": "2026-03-02T14:30:00Z"
}Niciun vot în așteptare pentru acest jucător
{
"voted": false
}Listează Voturile Nerevendicate
Obține toate voturile nerevendicate pentru serverul tău. Util pentru procesare în lot — de exemplu, un cron job care rulează la fiecare 5 minute și acordă recompense pentru toate voturile în așteptare simultan.
GET /api/v1/vote/unclaimed?limit=50 HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HEREParametri de Interogare
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Numărul maxim de voturi returnate (1–100, implicit 50). |
Răspuns
{
"votes": [
{
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"player_id": "PlayerName",
"voted_at": "2026-03-02T14:30:00Z"
},
{
"vote_id": "660e8400-e29b-41d4-a716-446655440001",
"player_id": "AnotherPlayer",
"voted_at": "2026-03-02T14:32:00Z"
}
],
"total": 2
}Revendică Voturi în Lot
Marchează mai multe voturi ca revendicate într-o singură cerere. Folosește aceasta după procesarea voturilor de la endpointul unclaimed.
POST /api/v1/vote/claim HTTP/1.1
Host: metin2.gg
Content-Type: application/json
X-API-Key: mg_live_YOUR_KEY_HERE
{
"vote_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
]
}Corpul Cererii (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
| vote_ids | string[] | Yes | Array de UUID-uri de voturi pentru revendicare. Maximum 100 pe cerere. |
Răspuns
{
"claimed": 2,
"failed": 0
}Webhooks
În loc de polling, poți primi notificări push în timp real când un jucător votează. Configurează URL-ul webhook-ului în panoul serverului sub Setări API.
Payload Webhook
POST https://your-server.com/api/vote-webhook HTTP/1.1
Content-Type: application/json
X-Metin2GG-Signature: a1b2c3d4e5f6...
{
"event": "vote.created",
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"server_id": "your-server-uuid",
"player_id": "PlayerName",
"voted_at": "2026-03-02T14:30:00Z",
"timestamp": "2026-03-02T14:30:01Z"
}Verificarea Semnăturii
Fiecare cerere webhook include un header X-Metin2GG-Signature care conține un digest hex HMAC-SHA256 al corpului brut al cererii, semnat cu secretul tău API. Verifică întotdeauna această semnătură înainte de a avea încredere în payload.
import hmac
import hashlib
def verify_webhook(request_body: bytes, signature: str, secret: str) -> bool:
"""Verify the X-Metin2GG-Signature header."""
expected = hmac.new(
secret.encode("utf-8"),
request_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature)
# Usage in your webhook handler:
# body = request.body (raw bytes)
# sig = request.headers["X-Metin2GG-Signature"]
# if not verify_webhook(body, sig, "your_api_secret"):
# return HttpResponse(status=403)<?php
function verifyWebhook(string $body, string $signature, string $secret): bool {
$expected = hash_hmac('sha256', $body, $secret);
return hash_equals($expected, $signature);
}
// Usage in your webhook handler:
// $body = file_get_contents('php://input');
// $sig = $_SERVER['HTTP_X_METIN2GG_SIGNATURE'] ?? '';
// if (!verifyWebhook($body, $sig, 'your_api_secret')) {
// http_response_code(403);
// exit('Invalid signature');
// }Integrare Metin2: Comandă Python
Pune acest script în sistemul de comenzi Python al serverului tău de joc. Când un jucător tastează /reward în joc, verifică metin2.gg pentru un vot în așteptare și acordă recompensa.
# vote_reward.py — Drop into your game server's command scripts
# Works with Python 2.7+ (common in Metin2 servers)
import json
import os
METIN2GG_API_KEY = "mg_live_YOUR_KEY_HERE"
METIN2GG_API_URL = "https://metin2.gg/api/v1/vote/check"
def check_vote(player_name):
"""Check if player has a pending vote and auto-claim it."""
url = "%s?player_id=%s" % (METIN2GG_API_URL, player_name)
# Method 1: Use urllib2 (Python 2) or urllib.request (Python 3)
try:
try:
import urllib2
req = urllib2.Request(url)
req.add_header("X-API-Key", METIN2GG_API_KEY)
resp = urllib2.urlopen(req, timeout=5)
data = json.loads(resp.read())
except ImportError:
import urllib.request
req = urllib.request.Request(url)
req.add_header("X-API-Key", METIN2GG_API_KEY)
resp = urllib.request.urlopen(req, timeout=5)
data = json.loads(resp.read().decode("utf-8"))
return data.get("voted", False)
except Exception:
pass
# Method 2: Fallback to curl (works even with broken SSL)
try:
cmd = 'curl -s -H "X-API-Key: %s" "%s"' % (METIN2GG_API_KEY, url)
raw = os.popen(cmd).read()
data = json.loads(raw)
return data.get("voted", False)
except Exception:
return None
# Example usage in your game command handler:
# def cmd_reward(player):
# result = check_vote(player.GetName())
# if result is True:
# player.GiveItem(50011, 10) # Example: 10x Dragon God Coins
# player.ChatInfoMessage("Vote reward claimed!")
# elif result is False:
# player.ChatInfoMessage("No pending vote. Vote at metin2.gg!")
# else:
# player.ChatInfoMessage("Could not reach metin2.gg. Try again.")Integrare Metin2: Fișier Quest (Lua)
Acest fișier quest creează o interacțiune NPC unde jucătorii pot verifica statusul votului. Apelează o comandă server-side care declanșează verificarea votului Python.
quest vote_reward begin
state start begin
when login or letter begin
send_letter("Vote Reward")
end
when button or info begin
say_title("Vote Reward")
say("")
say("Vote for our server on metin2.gg")
say("and claim your reward here!")
say("")
local s = select("Check My Vote", "How to Vote", "Close")
if s == 1 then
-- Triggers the Python command that checks the API
cmdchat("checkvote "..pc.get_name())
elseif s == 2 then
say_title("How to Vote")
say("")
say("1. Open metin2.gg in your browser")
say("2. Find our server page")
say("3. Enter your character name")
say("4. Click the Vote button")
say("5. Come back here to claim your reward!")
say("")
end
end
end
endIntegrare Metin2: Panou Web PHP
Dacă serverul tău are un panou web (bazat pe PHP), folosește acest snippet pentru a verifica și revendica voturi din panou. Funcționează cu orice mediu PHP 7+ cu cURL.
<?php
/**
* check_vote.php — Vote check for PHP-based web panels
* Requires PHP 7.0+ with cURL extension
*/
$apiKey = "mg_live_YOUR_KEY_HERE";
$playerName = $_GET["player"] ?? "";
if (empty($playerName)) {
echo json_encode(["error" => "Missing player name"]);
exit;
}
// Check vote status
$ch = curl_init(
"https://metin2.gg/api/v1/vote/check?player_id=" . urlencode($playerName)
);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
echo json_encode(["error" => "API returned HTTP $httpCode"]);
exit;
}
$data = json_decode($response, true);
if ($data["voted"] ?? false) {
// Player has voted — grant reward via your game DB
// Example: INSERT INTO player.reward_queue (player, item_vnum, count) ...
echo json_encode([
"success" => true,
"message" => "Vote reward granted!",
"vote_id" => $data["vote_id"],
]);
} else {
echo json_encode([
"success" => false,
"message" => "No pending vote found.",
]);
}Limite de Rată și Coduri de Eroare
API-ul impune limite de rată pentru a asigura utilizarea echitabilă. Limitele actuale:
- 60 requests per minute per API key
- 1,000 requests per hour per API key
| Status | Descriere |
|---|---|
| 200 OK | Cerere reușită. |
| 400 Bad Request | Parametri lipsă sau invalizi. Verifică formatul player_id sau vote_ids. |
| 401 Unauthorized | Cheie API lipsă sau invalidă. Asigură-te că incluzi headerul X-API-Key. |
| 403 Forbidden | Accesul API este dezactivat — de obicei pentru că backlink-ul a fost eliminat. Adaugă backlink-ul din nou și verifică. |
| 404 Not Found | Endpointul nu există. Verifică din nou calea URL. |
| 429 Too Many Requests | Limita de rată depășită. Așteaptă și reîncearcă după valoarea headerului Retry-After (în secunde). |
| 500 Internal Server Error | Ceva a mers prost de partea noastră. Reîncearcă după câteva secunde. |
Strategia de Reîncercare
On 429 errors, read the Retry-After header (value in seconds) and wait before retrying. For 500 errors, retry with exponential backoff (1s, 2s, 4s).
Întrebări Frecvente Depanare
Primesc 401 Unauthorized la fiecare cerere
Asigură-te că trimiți cheia API în headerul X-API-Key (nu ca parametru de interogare sau în corp). Cheia trebuie să înceapă cu mg_live_.
API-ul spune voted: false dar jucătorul susține că a votat
Jucătorul poate a votat fără a introduce numele personajului, sau a folosit un alt nume. Verifică URL-ul linkului de vot — trebuie să includă ?player_id=NUMELE_EXACT. Numele sunt insensibile la majuscule.
Primesc 403 Forbidden
Accesul tău API este suspendat, probabil pentru că backlink-ul către metin2.gg a fost eliminat de pe site-ul tău. Adaugă-l din nou și dă click pe 'Verifică Acum' în panou pentru re-verificare.
Pot testa API-ul fără voturi reale?
Momentan nu există mod sandbox. Votează pe propria ta listare de server cu un nume de test pentru a verifica integrarea end-to-end.
Scriptul meu Python nu se poate conecta (timeout sau eroare SSL)
Majoritatea serverelor Metin2 rulează Python 2.7 care are certificate SSL depășite. Folosește alternativa os.popen('curl ...') prezentată în exemplul Python, sau actualizează pachetul CA Python al serverului.
Cât de des ar trebui să fac polling la API?
Pentru endpointul /check (per jucător): apelează-l când jucătorul își solicită recompensa (ex. comanda /reward). Pentru /unclaimed (lot): la fiecare 3–5 minute prin cron este ideal. Nu face polling mai des de o dată pe minut.
Pot mai multe servere să partajeze o cheie API?
Nu. Fiecare cheie API este legată de o listare de server. Dacă rulezi mai multe servere, generează o cheie separată pentru fiecare din paginile respective ale panoului.
Ce se întâmplă dacă endpointul meu webhook este indisponibil?
metin2.gg reîncearcă livrările webhook eșuate de până la 5 ori cu backoff exponențial. Dacă toate încercările eșuează, votul rămâne nerevendicat și poate fi preluat prin endpointurile de polling.
Gata de Integrare?
Adaugă serverul tău pe metin2.gg, generează o cheie API și începe să recompensezi votanții în câteva minute.