// Country pricing + local currency display function pooliva_language_catalog(): array { // ISO-style language catalog for global auto-language. Labels are English admin labels; UI strings can be AI-translated and cached. return [ 'af'=>'Afrikaans','sq'=>'Albanian','am'=>'Amharic','ar'=>'Arabic','hy'=>'Armenian','az'=>'Azerbaijani','eu'=>'Basque','be'=>'Belarusian','bn'=>'Bengali','bs'=>'Bosnian','bg'=>'Bulgarian','my'=>'Burmese','ca'=>'Catalan','ceb'=>'Cebuano','zh'=>'Chinese','zh-CN'=>'Chinese Simplified','zh-TW'=>'Chinese Traditional','co'=>'Corsican','hr'=>'Croatian','cs'=>'Czech','da'=>'Danish','nl'=>'Dutch','en'=>'English','eo'=>'Esperanto','et'=>'Estonian','fi'=>'Finnish','fr'=>'French','fy'=>'Frisian','gl'=>'Galician','ka'=>'Georgian','de'=>'German','el'=>'Greek','gu'=>'Gujarati','ht'=>'Haitian Creole','ha'=>'Hausa','haw'=>'Hawaiian','he'=>'Hebrew','hi'=>'Hindi','hmn'=>'Hmong','hu'=>'Hungarian','is'=>'Icelandic','ig'=>'Igbo','id'=>'Indonesian','ga'=>'Irish','it'=>'Italian','ja'=>'Japanese','jv'=>'Javanese','kn'=>'Kannada','kk'=>'Kazakh','km'=>'Khmer','rw'=>'Kinyarwanda','ko'=>'Korean','ku'=>'Kurdish','ky'=>'Kyrgyz','lo'=>'Lao','la'=>'Latin','lv'=>'Latvian','lt'=>'Lithuanian','lb'=>'Luxembourgish','mk'=>'Macedonian','mg'=>'Malagasy','ms'=>'Malay','ml'=>'Malayalam','mt'=>'Maltese','mi'=>'Maori','mr'=>'Marathi','mn'=>'Mongolian','ne'=>'Nepali','no'=>'Norwegian','ny'=>'Nyanja','or'=>'Odia','ps'=>'Pashto','fa'=>'Persian','pl'=>'Polish','pt'=>'Portuguese','pa'=>'Punjabi','ro'=>'Romanian','ru'=>'Russian','sm'=>'Samoan','gd'=>'Scots Gaelic','sr'=>'Serbian','st'=>'Sesotho','sn'=>'Shona','sd'=>'Sindhi','si'=>'Sinhala','sk'=>'Slovak','sl'=>'Slovenian','so'=>'Somali','es'=>'Spanish','su'=>'Sundanese','sw'=>'Swahili','sv'=>'Swedish','tl'=>'Tagalog','tg'=>'Tajik','ta'=>'Tamil','tt'=>'Tatar','te'=>'Telugu','th'=>'Thai','tr'=>'Turkish','tk'=>'Turkmen','uk'=>'Ukrainian','ur'=>'Urdu','ug'=>'Uyghur','uz'=>'Uzbek','vi'=>'Vietnamese','cy'=>'Welsh','xh'=>'Xhosa','yi'=>'Yiddish','yo'=>'Yoruba','zu'=>'Zulu' ]; } function pooliva_language_is_rtl(string $lang): bool { $base = strtolower(explode('-', $lang)[0]); return in_array($base, ['ar','fa','he','ur','ps','sd','ug','ku'], true); } function pooliva_country_language_map(): array { // Covers virtually all ISO-3166 countries with a practical default language for auto-language. return [ 'US'=>'en','CA'=>'en','GB'=>'en','AU'=>'en','NZ'=>'en','IE'=>'en','ZA'=>'en','NG'=>'en','KE'=>'sw','TZ'=>'sw','UG'=>'en','GH'=>'en','PH'=>'en','IN'=>'hi','PK'=>'ur','BD'=>'bn','LK'=>'si','NP'=>'ne', 'SA'=>'ar','AE'=>'ar','QA'=>'ar','KW'=>'ar','BH'=>'ar','OM'=>'ar','YE'=>'ar','JO'=>'ar','LB'=>'ar','SY'=>'ar','IQ'=>'ar','EG'=>'ar','SD'=>'ar','LY'=>'ar','TN'=>'ar','DZ'=>'ar','MA'=>'ar','PS'=>'ar', 'BR'=>'pt','PT'=>'pt','AO'=>'pt','MZ'=>'pt','CV'=>'pt','GW'=>'pt','ST'=>'pt','TL'=>'pt', 'ES'=>'es','MX'=>'es','AR'=>'es','CO'=>'es','PE'=>'es','CL'=>'es','VE'=>'es','EC'=>'es','BO'=>'es','PY'=>'es','UY'=>'es','CR'=>'es','PA'=>'es','GT'=>'es','HN'=>'es','SV'=>'es','NI'=>'es','DO'=>'es','CU'=>'es','PR'=>'es', 'FR'=>'fr','BE'=>'fr','CH'=>'de','LU'=>'fr','MC'=>'fr','CI'=>'fr','SN'=>'fr','CM'=>'fr','ML'=>'fr','NE'=>'fr','BF'=>'fr','BJ'=>'fr','TG'=>'fr','GA'=>'fr','CG'=>'fr','CD'=>'fr','RW'=>'rw','BI'=>'fr','DJ'=>'fr','KM'=>'fr','MG'=>'mg', 'DE'=>'de','AT'=>'de','NL'=>'nl','SE'=>'sv','NO'=>'no','DK'=>'da','FI'=>'fi','IS'=>'is','IT'=>'it','SM'=>'it','VA'=>'it','GR'=>'el','CY'=>'el','MT'=>'mt','PL'=>'pl','CZ'=>'cs','SK'=>'sk','HU'=>'hu','RO'=>'ro','MD'=>'ro','BG'=>'bg','HR'=>'hr','SI'=>'sl','RS'=>'sr','BA'=>'bs','ME'=>'sr','MK'=>'mk','AL'=>'sq','XK'=>'sq','TR'=>'tr','RU'=>'ru','UA'=>'uk','BY'=>'be','EE'=>'et','LV'=>'lv','LT'=>'lt','GE'=>'ka','AM'=>'hy','AZ'=>'az','KZ'=>'kk','KG'=>'ky','TJ'=>'tg','TM'=>'tk','UZ'=>'uz', 'CN'=>'zh-CN','TW'=>'zh-TW','HK'=>'zh-TW','MO'=>'zh-TW','JP'=>'ja','KR'=>'ko','KP'=>'ko','VN'=>'vi','TH'=>'th','ID'=>'id','MY'=>'ms','SG'=>'en','KH'=>'km','LA'=>'lo','MM'=>'my','MN'=>'mn','BN'=>'ms', 'IR'=>'fa','AF'=>'fa','IL'=>'he','ET'=>'am','SO'=>'so','ER'=>'ti','ZW'=>'sn','ZM'=>'en','MW'=>'ny','MZ'=>'pt','BW'=>'en','NA'=>'en','LS'=>'st','SZ'=>'en','MG'=>'mg','MU'=>'en','SC'=>'en', 'JM'=>'en','HT'=>'ht','BZ'=>'en','GY'=>'en','SR'=>'nl','TT'=>'en','BB'=>'en','BS'=>'en','AG'=>'en','DM'=>'en','GD'=>'en','KN'=>'en','LC'=>'en','VC'=>'en','AW'=>'nl','CW'=>'nl' ]; } function pooliva_country_currency_map(): array { // Currency/language defaults for the most important ad/payment countries. Missing countries safely fall back to USD + country language. $m = [ 'US'=>['USD','$',1.00,'en'], 'CA'=>['CAD','C$',1.36,'en'], 'GB'=>['GBP','£',0.79,'en'], 'AU'=>['AUD','A$',1.52,'en'], 'NZ'=>['NZD','NZ$',1.64,'en'], 'SA'=>['SAR','ر.س',3.75,'ar'], 'AE'=>['AED','د.إ',3.67,'ar'], 'QA'=>['QAR','ر.ق',3.64,'ar'], 'KW'=>['KWD','د.ك',0.31,'ar'], 'BH'=>['BHD','BD',0.38,'ar'], 'OM'=>['OMR','OMR',0.38,'ar'], 'EG'=>['EGP','E£',48.00,'ar'], 'MA'=>['MAD','DH',10.00,'ar'], 'BR'=>['BRL','R$',5.15,'pt'], 'MX'=>['MXN','$',17.00,'es'], 'AR'=>['ARS','$',900.00,'es'], 'CO'=>['COP','$',3900.00,'es'], 'CL'=>['CLP','$',920.00,'es'], 'PE'=>['PEN','S/',3.75,'es'], 'TR'=>['TRY','₺',32.50,'tr'], 'IN'=>['INR','₹',83.00,'hi'], 'ID'=>['IDR','Rp',16000,'id'], 'PH'=>['PHP','₱',56.00,'en'], 'TH'=>['THB','฿',36.00,'th'], 'MY'=>['MYR','RM',4.70,'ms'], 'SG'=>['SGD','S$',1.35,'en'], 'JP'=>['JPY','¥',155.00,'ja'], 'KR'=>['KRW','₩',1360.00,'ko'], 'CN'=>['CNY','¥',7.20,'zh-CN'], 'TW'=>['TWD','NT$',32.00,'zh-TW'], 'HK'=>['HKD','HK$',7.80,'zh-TW'], 'FR'=>['EUR','€',0.92,'fr'], 'DE'=>['EUR','€',0.92,'de'], 'ES'=>['EUR','€',0.92,'es'], 'IT'=>['EUR','€',0.92,'it'], 'NL'=>['EUR','€',0.92,'nl'], 'BE'=>['EUR','€',0.92,'fr'], 'AT'=>['EUR','€',0.92,'de'], 'IE'=>['EUR','€',0.92,'en'], 'PT'=>['EUR','€',0.92,'pt'], 'GR'=>['EUR','€',0.92,'el'], 'FI'=>['EUR','€',0.92,'fi'], 'SE'=>['SEK','kr',10.60,'sv'], 'NO'=>['NOK','kr',10.70,'no'], 'DK'=>['DKK','kr',6.90,'da'], 'PL'=>['PLN','zł',4.00,'pl'], 'CZ'=>['CZK','Kč',23.00,'cs'], 'RO'=>['RON','lei',4.60,'ro'], 'HU'=>['HUF','Ft',360.00,'hu'], 'BG'=>['BGN','лв',1.80,'bg'], 'RU'=>['RUB','₽',92.00,'ru'], 'UA'=>['UAH','₴',39.00,'uk'], 'ZA'=>['ZAR','R',18.50,'en'], 'NG'=>['NGN','₦',1500.00,'en'], 'KE'=>['KES','KSh',130.00,'sw'] ]; $langMap = pooliva_country_language_map(); foreach ($langMap as $cc=>$lang) if (!isset($m[$cc])) $m[$cc]=['USD','$',1.00,$lang]; return $m; } function pooliva_geo_profile(?string $cc=null): array { $cc = strtoupper($cc ?: country_code()); $map = pooliva_country_currency_map(); $d = $map[$cc] ?? ['USD','$',1.00,(pooliva_country_language_map()[$cc] ?? 'en')]; return ['country_code'=>$cc,'currency_code'=>$d[0],'currency_symbol'=>$d[1],'fx_rate'=>(float)$d[2],'language'=>$d[3]]; } function pooliva_country_price_row(string $cc): ?array { global $pdo; try { $st=$pdo->prepare('SELECT * FROM country_pricing WHERE country_code=? AND is_active=1 LIMIT 1'); $st->execute([strtoupper($cc)]); $r=$st->fetch(); return $r ?: null; } catch(Throwable $e){ return null; } } function pooliva_pricing_for_country(?string $cc=null): array { $geo = pooliva_geo_profile($cc); $row = pooliva_country_price_row($geo['country_code']); $credits = (float)($row['pack_credits'] ?? setting_value('min_credit_pack','20')); $bonus = (float)($row['bonus_credits'] ?? setting_value('default_bonus_credits','0')); $usd = (float)($row['pack_price_usd'] ?? ((float)setting_value('credit_price','0.50') * $credits)); $prevUsd = (float)($row['previous_price_usd'] ?? 0); if ($prevUsd <= $usd) $prevUsd = round($usd * 1.9, 2); $rate = (float)($row['fx_rate_override'] ?? 0); if ($rate <= 0) $rate = (float)$geo['fx_rate']; $symbol = $row['currency_symbol'] ?? $geo['currency_symbol']; $code = $row['currency_code'] ?? $geo['currency_code']; $local = $usd * $rate; $prevLocal = $prevUsd * $rate; $totalCredits = $credits + $bonus; $badge = trim((string)($row['badge_text'] ?? setting_value('default_pack_badge','MOST POPULAR'))); $savingsPct = ($prevUsd > 0) ? max(0, min(95, round((1 - ($usd / $prevUsd)) * 100))) : 0; return [ 'country_code'=>$geo['country_code'], 'language'=>$geo['language'], 'credits'=>$credits, 'bonus_credits'=>$bonus, 'total_credits'=>$totalCredits, 'pay_usd'=>round($usd,2), 'paypal_amount_usd'=>round($usd,2), 'previous_price_usd'=>round($prevUsd,2), 'local_amount'=>round($local,2), 'previous_local_amount'=>round($prevLocal,2), 'currency_code'=>$code, 'currency_symbol'=>$symbol, 'badge_text'=>$badge, 'savings_percent'=>$savingsPct, 'matches'=>$totalCredits, 'featured'=> (int)($row['is_featured'] ?? 1), // Local currency is DISPLAY ONLY. PayPal/order amount remains exactly the USD value below. 'display_text'=>trim($symbol.' '.number_format($local, ($local>=1000?0:2))).' ≈ $'.number_format($usd,2).' USD', 'previous_display_text'=>trim($symbol.' '.number_format($prevLocal, ($prevLocal>=1000?0:2))).' ≈ $'.number_format($prevUsd,2).' USD', 'small_paypal_text'=>'PayPal checkout amount: $'.number_format($usd,2).' USD', 'paypal_notice'=>'You will pay exactly $'.number_format($usd,2).' USD in PayPal. Local currency is only an estimated display using FX rate '.number_format($rate,4).'.', 'fx_rate_used'=>round($rate,6), 'local_display_only'=>true ]; } function pooliva_language_for_country(?string $cc=null): string { $geo = pooliva_geo_profile($cc); $force = setting_value('force_language','auto'); if ($force && $force !== 'auto') return $force; if (setting_value('auto_language_enabled','1') !== '1') return 'en'; // Browser language gets priority when the visitor's device clearly asks for it. $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''; if ($accept) { $first = strtolower(trim(explode(',', $accept)[0])); $first = str_replace('_','-', $first); $catalog = pooliva_language_catalog(); if (isset($catalog[$first])) return $first; $base = explode('-', $first)[0]; if (isset($catalog[$base])) return $base; } return $geo['language'] ?: 'en'; } function pooliva_base_translation_en(): array { return [ 'enter_title'=>'Enter Pooliva','enter_desc'=>'Write your player name first. No signup. Your game profile stays linked to this device/IP.','name_placeholder'=>'Your player name','terms'=>'I agree to the name rules, privacy policy, and fair play terms.','start'=>'Start Playing','optional_photo'=>'Profile photo is optional after you enter.','tag'=>'🎱 First match free • instant device profile','hero_title'=>'Instant Pool Battles','hero_desc'=>'Enter in seconds, beat global players, build streaks, and push your country up the City Wars board.','play_free'=>'Play Free Match','play_next'=>'Play Next Match','buy'=>'Buy Credits','edit_profile'=>'Edit Name / Photo','city_theme'=>'🏙️ City Table Theme','leaderboard'=>'Global Leaderboard','city_wars'=>'🌍 City Wars' ]; } function pooliva_static_translations(): array { return [ 'en'=>pooliva_base_translation_en(), 'ar'=>['enter_title'=>'ادخل Pooliva','enter_desc'=>'اكتب اسم اللاعب أولاً. بدون تسجيل. ملفك يبقى مربوط بجهازك.','name_placeholder'=>'اسم اللاعب','terms'=>'أوافق على شروط الاسم والخصوصية واللعب العادل.','start'=>'ابدأ اللعب','optional_photo'=>'صورة البروفايل اختيارية بعد الدخول.','tag'=>'🎱 أول مباراة مجانية • ملف فوري للجهاز','hero_title'=>'تحديات بلياردو فورية','hero_desc'=>'ادخل خلال ثواني، اهزم لاعبين عالميين، ارفع الستريك وادفع بلدك في ترتيب City Wars.','play_free'=>'العب مباراة مجانية','play_next'=>'العب المباراة التالية','buy'=>'شراء كريدت','edit_profile'=>'تعديل الاسم / الصورة','city_theme'=>'🏙️ ثيم طاولة المدينة','leaderboard'=>'الترتيب العالمي','city_wars'=>'🌍 حروب المدن'], 'es'=>['enter_title'=>'Entra a Pooliva','enter_desc'=>'Escribe tu nombre primero. Sin registro. Tu perfil queda ligado a este dispositivo.','name_placeholder'=>'Tu nombre','terms'=>'Acepto las reglas del nombre, privacidad y juego limpio.','start'=>'Empezar','optional_photo'=>'La foto de perfil es opcional después.','tag'=>'🎱 Primera partida gratis • perfil instantáneo','hero_title'=>'Batallas de pool instantáneas','hero_desc'=>'Entra en segundos, vence jugadores globales y sube tu país en City Wars.','play_free'=>'Jugar gratis','play_next'=>'Siguiente partida','buy'=>'Comprar créditos','edit_profile'=>'Editar nombre / foto','city_theme'=>'🏙️ Tema de mesa','leaderboard'=>'Ranking global','city_wars'=>'🌍 City Wars'], 'pt'=>['enter_title'=>'Entre no Pooliva','enter_desc'=>'Digite seu nome primeiro. Sem cadastro. Seu perfil fica ligado a este dispositivo.','name_placeholder'=>'Seu nome','terms'=>'Aceito as regras de nome, privacidade e jogo justo.','start'=>'Começar','optional_photo'=>'Foto de perfil é opcional depois.','tag'=>'🎱 Primeira partida grátis • perfil instantâneo','hero_title'=>'Batalhas instantâneas de sinuca','hero_desc'=>'Entre em segundos, vença jogadores globais e leve seu país ao topo.','play_free'=>'Jogar grátis','play_next'=>'Próxima partida','buy'=>'Comprar créditos','edit_profile'=>'Editar nome / foto','city_theme'=>'🏙️ Tema da mesa','leaderboard'=>'Ranking global','city_wars'=>'🌍 City Wars'] ]; } function pooliva_ai_translate_bundle(string $lang): ?array { if (setting_value('ai_translation_enabled','0') !== '1') return null; $key = trim(setting_value('openai_api_key','')); if (!$key || strtolower($key)==='null') return null; $catalog = pooliva_language_catalog(); $target = $catalog[$lang] ?? $lang; $base = pooliva_base_translation_en(); $model = setting_value('translation_model','gpt-4o-mini'); $note = setting_value('translation_quality_note','short, natural mobile pool game UI text. Keep Pooliva, City Wars, Credits as brand/game terms when natural. Return JSON only.'); $payload = json_encode([ 'model'=>$model, 'messages'=>[ ['role'=>'system','content'=>'You translate short mobile game UI strings. Return only valid compact JSON object with the same keys. No markdown.'], ['role'=>'user','content'=>'Translate this Pooliva game UI into '.$target.' ('.$lang.'). '.$note.' JSON: '.json_encode($base, JSON_UNESCAPED_UNICODE)] ], 'temperature'=>0.2 ], JSON_UNESCAPED_UNICODE); try { $ch = curl_init('https://api.openai.com/v1/chat/completions'); curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.$key],CURLOPT_POSTFIELDS=>$payload,CURLOPT_TIMEOUT=>18]); $res = curl_exec($ch); $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (!$res || $code < 200 || $code >= 300) return null; $j=json_decode($res,true); $txt=$j['choices'][0]['message']['content'] ?? ''; $arr=json_decode($txt,true); if (!is_array($arr)) return null; return array_intersect_key($arr, $base) + $base; } catch(Throwable $e){ return null; } } function pooliva_translations(string $lang): array { global $pdo; $lang = str_replace('_','-', trim($lang ?: 'en')); $static = pooliva_static_translations(); $base = pooliva_base_translation_en(); $out = $static[$lang] ?? $static[explode('-', $lang)[0] ?? 'en'] ?? $base; try { $st=$pdo->prepare('SELECT text_key,text_value FROM translations WHERE lang_code=?'); $st->execute([$lang]); $rows=$st->fetchAll(); if (!$rows && !isset($static[$lang]) && setting_value('ai_translation_enabled','0')==='1') { $ai = pooliva_ai_translate_bundle($lang); if ($ai) { $ins=$pdo->prepare('INSERT INTO translations(lang_code,text_key,text_value,source) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE text_value=VALUES(text_value),source=VALUES(source),updated_at=NOW()'); foreach($ai as $k=>$v){ $ins->execute([$lang,$k,$v,'ai-cache']); } $out = $ai; } } else { foreach($rows as $r){ $out[$r['text_key']]=$r['text_value']; } } } catch(Throwable $e) {} return $out + $base; } Terms of Use - Pooliva.net
Privacy

Terms of Use

Effective date: 2026-05-23 • Version: 1.0

These Terms of Use govern access to Pooliva.net, an online skill-based pool game operated by REDLIVE LTD in the United Kingdom.

1. Acceptance before play

No visitor may enter or play unless they first write a player name and actively agree to these Terms of Use and the Privacy Policy. By clicking Start Playing, you confirm that you accept the name rules, privacy policy, fair-play rules, and payment terms.

2. Account model

The service can create a device-based guest profile without email registration. Your profile may be linked to your device, browser, cookies/local storage, IP-derived country, fingerprint signals, game activity, credits, leaderboard activity, and security logs.

3. Credits and payments

Credits are digital access units used to enter games, features, or other in-game experiences. Unless clearly stated otherwise, credits have no cash value, are not a bank balance, are not withdrawable, and cannot be exchanged for money.

4. No refunds

All purchases are final and non-refundable once credits or digital access are delivered, except where a refund is required by applicable law. This no-refund rule is necessary because credits provide immediate digital access and can be consumed instantly.

5. Fair play

You must not cheat, manipulate game results, exploit bugs, abuse free matches, farm credits, use automation, attack the server, abuse VPN/proxy systems, impersonate staff, upload harmful files, or interfere with other players.

6. Names, chat, voice and uploads

Player names, profile images, chat messages and voice taunts must not contain illegal, abusive, hateful, sexually exploitative, threatening, misleading, or infringing content. We may remove content, rename players, restrict features, shadow-ban, suspend, or block devices/IPs at our discretion.

7. Game integrity and security

We may use anti-cheat tools, rate limits, fingerprinting, VPN/proxy checks, security logs, replay validation, and manual review to protect the game. Suspicious players may be restricted from rewards, leaderboards, matchmaking, credits, or access.

8. Availability

The service is provided on an “as is” and “as available” basis. We do not guarantee uninterrupted availability, perfect matchmaking, bug-free gameplay, exact physics behavior, or permanent access to any feature.

9. Intellectual property

All software, branding, design, graphics, gameplay systems, database structure, text, logos, and platform content belong to REDLIVE LTD or its licensors. You may not copy, resell, scrape, reverse engineer, or reproduce the service without written permission.

10. Limitation of liability

To the maximum extent permitted by law, REDLIVE LTD is not liable for indirect losses, loss of profits, loss of data, account restrictions, leaderboard changes, payment-provider decisions, downtime, or third-party service failures.

11. Changes

We may update these terms. Continued use after updates means you accept the updated terms.

Back to game