| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client2/web31/web/slots/includes/ |
Upload File : |
<?php
/**
* Reel Royale – Administrations-Helfer.
* Einstellungen (slot_settings), RTP-Faktoren je Spiel sowie Spieler-Operationen.
*/
/** Alle Einstellungen als key=>value (gecached pro Request). */
function admin_settings(): array {
static $cache = null;
if ($cache !== null) {
return $cache;
}
$cache = [];
try {
foreach (db()->query('SELECT skey, sval FROM slot_settings') as $row) {
$cache[$row['skey']] = $row['sval'];
}
} catch (Throwable $e) {
$cache = [];
}
return $cache;
}
function admin_set_setting(string $key, string $value): void {
$stmt = db()->prepare('INSERT INTO slot_settings (skey, sval, updated_at) VALUES (?,?,NOW()) ON DUPLICATE KEY UPDATE sval=VALUES(sval), updated_at=NOW()');
$stmt->execute([$key, $value]);
}
/** Erlaubter Bereich des RTP-Faktors (0.50 = sehr knausrig … 5.00 = extrem großzügig). */
function admin_clamp_factor(float $f): float {
return max(0.50, min(5.00, $f));
}
/** Effektiver Auszahlungsfaktor eines Spiels = global × spielspezifisch. */
function game_rtp_factor(string $gameId): float {
$s = admin_settings();
$global = isset($s['rtp_factor:global']) ? (float)$s['rtp_factor:global'] : 1.0;
$game = isset($s['rtp_factor:' . $gameId]) ? (float)$s['rtp_factor:' . $gameId] : 1.0;
return admin_clamp_factor($global) * admin_clamp_factor($game);
}
/** Erlaubter Bereich der Freispiel-Häufigkeit (1.0 = Standard … 8.0 = sehr häufig). */
function admin_clamp_fs_factor(float $f): float {
return max(1.00, min(8.00, $f));
}
/** Effektiver Freispiel-Häufigkeitsfaktor = global × spielspezifisch. */
function game_fs_factor(string $gameId): float {
$s = admin_settings();
$global = isset($s['fs_factor:global']) ? (float)$s['fs_factor:global'] : 1.0;
$game = isset($s['fs_factor:' . $gameId]) ? (float)$s['fs_factor:' . $gameId] : 1.0;
return admin_clamp_fs_factor($global) * admin_clamp_fs_factor($game);
}
/** Erlaubter Bereich des spielerindividuellen Glücksfaktors (bis 10×). */
function admin_clamp_player_factor(float $f): float {
return max(0.20, min(10.00, $f));
}
/** Ist das Verdopplungsspiel (Gamble) aktiv? (Standard: an) */
function gamble_enabled(): bool {
$s = admin_settings();
return !isset($s['gamble_enabled']) || $s['gamble_enabled'] === '1';
}
/** Gewinnchance im Verdopplungsspiel (50% × Spielerfaktor, gedeckelt). */
function gamble_win_chance(array $user): float {
$base = 0.5 * player_rtp_factor($user);
return max(0.05, min(0.95, $base));
}
/** Gewinnfaktor eines einzelnen Spielers (Standard 1.00). */
function player_rtp_factor(array $user): float {
return admin_clamp_player_factor((float)($user['rtp_factor'] ?? 1.0));
}
// ---------------- Spieler-Operationen ----------------
function admin_all_players(): array {
$stmt = db()->query('SELECT id, username, balance, free_spins, banned, rtp_factor, total_wagered, total_won, last_seen_at, created_at FROM users ORDER BY id ASC');
return $stmt->fetchAll();
}
function admin_get_player(int $id): ?array {
$stmt = db()->prepare('SELECT id, username, balance, free_spins, banned FROM users WHERE id = ? LIMIT 1');
$stmt->execute([$id]);
$row = $stmt->fetch();
return $row ?: null;
}
function admin_set_balance(int $id, float $amount): void {
$amount = max(0, round($amount, 2));
db()->prepare('UPDATE users SET balance = ? WHERE id = ?')->execute([$amount, $id]);
}
function admin_adjust_balance(int $id, float $delta): void {
db()->prepare('UPDATE users SET balance = GREATEST(0, balance + ?) WHERE id = ?')->execute([round($delta, 2), $id]);
}
function admin_set_free_spins(int $id, int $count): void {
$count = max(0, $count);
db()->prepare('UPDATE users SET free_spins = ?, free_spin_special_symbol = NULL WHERE id = ?')->execute([$count, $id]);
}
function admin_set_banned(int $id, bool $banned): void {
db()->prepare('UPDATE users SET banned = ? WHERE id = ?')->execute([$banned ? 1 : 0, $id]);
}
function admin_set_player_factor(int $id, float $factor): void {
$factor = admin_clamp_player_factor($factor);
db()->prepare('UPDATE users SET rtp_factor = ? WHERE id = ?')->execute([$factor, $id]);
}
// ---------------- Symbol-Austausch je Spiel ----------------
/** Overrides eines Spiels: code => ['icon'=>?, 'img'=>?]. */
function game_symbol_overrides(string $gameId): array {
$s = admin_settings();
$raw = $s['symbols:' . $gameId] ?? '';
if ($raw === '') return [];
$d = json_decode($raw, true);
return is_array($d) ? $d : [];
}
/** Frischer DB-Lesezugriff (umgeht den Request-Cache) – für Schreiboperationen. */
function _symbol_overrides_fresh(string $gameId): array {
$stmt = db()->prepare('SELECT sval FROM slot_settings WHERE skey = ? LIMIT 1');
$stmt->execute(['symbols:' . $gameId]);
$raw = (string)$stmt->fetchColumn();
$d = $raw !== '' ? json_decode($raw, true) : [];
return is_array($d) ? $d : [];
}
function admin_set_symbol_override(string $gameId, string $code, array $data): void {
$all = _symbol_overrides_fresh($gameId);
$all[$code] = array_merge($all[$code] ?? [], $data);
admin_set_setting('symbols:' . $gameId, json_encode($all, JSON_UNESCAPED_UNICODE));
}
function admin_reset_symbol_override(string $gameId, string $code): void {
$all = _symbol_overrides_fresh($gameId);
unset($all[$code]);
admin_set_setting('symbols:' . $gameId, json_encode($all, JSON_UNESCAPED_UNICODE));
}
/** Speichert ein hochgeladenes Symbol-Bild und liefert den relativen Pfad. */
function admin_save_symbol_image(string $gameId, string $code, array $file): string {
if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
throw new RuntimeException('Es wurde keine Datei hochgeladen.');
}
if (($file['size'] ?? 0) > 3 * 1024 * 1024) {
throw new RuntimeException('Datei zu groß (max. 3 MB).');
}
$info = @getimagesize($file['tmp_name']);
if (!$info) {
throw new RuntimeException('Keine gültige Bilddatei.');
}
$extMap = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', 'image/gif' => 'gif'];
$ext = $extMap[$info['mime']] ?? null;
if (!$ext) {
throw new RuntimeException('Format nicht unterstützt (JPG, PNG, WebP, GIF).');
}
$gameId = preg_replace('/[^a-z_]/', '', $gameId);
$code = preg_replace('/[^A-Za-z0-9_]/', '', $code);
if ($gameId === '' || $code === '') {
throw new RuntimeException('Ungültiges Spiel/Symbol.');
}
$dir = __DIR__ . '/../assets/img/symbols/' . $gameId;
if (!is_dir($dir) && !@mkdir($dir, 0775, true) && !is_dir($dir)) {
throw new RuntimeException('Zielordner konnte nicht erstellt werden.');
}
if (!is_writable($dir)) {
throw new RuntimeException('Zielordner ist nicht beschreibbar (Rechte prüfen).');
}
// alte Varianten entfernen, neue speichern
foreach ($extMap as $e) {
$old = $dir . '/' . $code . '.' . $e;
if (is_file($old)) @unlink($old);
}
$dest = $dir . '/' . $code . '.' . $ext;
if (!move_uploaded_file($file['tmp_name'], $dest)) {
throw new RuntimeException('Datei konnte nicht gespeichert werden.');
}
@chmod($dest, 0644);
return 'assets/img/symbols/' . $gameId . '/' . $code . '.' . $ext . '?v=' . time();
}