Initial commit

ZnoteX / Commit #5

Commit Initial commit

Alex Alex committed 01/10/2026 09:20 main Full upload
481 files +128,311 -0
A layouts/default/views/killers.php +121-0 View file
@@ -0,0 +1,121 @@
1+<?php
2+/**
3+ * Kill statistics.
4+ *
5+ * Prepared by killers.php:
6+ * $killersMode 'modern' (TFS 1.x / 0.2 / OTHire), 'legacy' (TFS 0.3), or 'unsupported'
7+ * $killers biggest murderers [modern]
8+ * $victims biggest victims [modern]
9+ * $latests 20 most recent kills [modern]
10+ * $deaths 30 most recent deaths [legacy]
11+ *
12+ * Each of the four is false when there is nothing to show.
13+ */
14+?>
15+
16+<div class="znx-acct">
17+
18+<?php if ($killersMode === 'modern'): ?>
19+
20+ <div class="znx-acct-head"><?= t('killers.biggest_murders') ?></div>
21+ <?php if ($killers): ?>
22+ <div class="znx-acct-table-wrap">
23+ <table id="killersTable" class="znx-acct-table">
24+ <tr class="yellow">
25+ <th><?= t('common.name') ?></th>
26+ <th><?= t('killers.kills') ?></th>
27+ </tr>
28+ <?php foreach ($killers as $killer): ?>
29+ <tr>
30+ <td width="70%">
31+ <a href="characterprofile.php?name=<?= urlencode($killer['killed_by']) ?>"><?= htmlspecialchars($killer['killed_by'], ENT_QUOTES, 'UTF-8') ?></a>
32+ </td>
33+ <td width="30%"><?= (int)$killer['kills'] ?></td>
34+ </tr>
35+ <?php endforeach; ?>
36+ </table>
37+ </div>
38+ <?php else: ?>
39+ <div class="znx-empty-box"><?= t('killers.no_kills') ?></div>
40+ <?php endif; ?>
41+
42+ <div class="znx-acct-head"><?= t('killers.biggest_victims') ?></div>
43+ <?php if ($victims): ?>
44+ <div class="znx-acct-table-wrap">
45+ <table id="victimsTable" class="znx-acct-table">
46+ <tr class="yellow">
47+ <th><?= t('common.name') ?></th>
48+ <th><?= t('killers.deaths') ?></th>
49+ </tr>
50+ <?php foreach ($victims as $victim): ?>
51+ <tr>
52+ <td width="70%">
53+ <a href="characterprofile.php?name=<?= urlencode($victim['name']) ?>"><?= htmlspecialchars($victim['name'], ENT_QUOTES, 'UTF-8') ?></a>
54+ </td>
55+ <td width="30%"><?= (int)$victim['Deaths'] ?></td>
56+ </tr>
57+ <?php endforeach; ?>
58+ </table>
59+ </div>
60+ <?php else: ?>
61+ <div class="znx-empty-box"><?= t('killers.no_kills') ?></div>
62+ <?php endif; ?>
63+
64+ <div class="znx-acct-head"><?= t('killers.latest_kills') ?></div>
65+ <?php if ($latests): ?>
66+ <div class="znx-acct-table-wrap">
67+ <table id="killersTable" class="znx-acct-table">
68+ <tr class="yellow">
69+ <th><?= t('killers.killer') ?></th>
70+ <th><?= t('common.time') ?></th>
71+ <th><?= t('killers.victim') ?></th>
72+ </tr>
73+ <?php foreach ($latests as $last): ?>
74+ <tr>
75+ <td width="35%">
76+ <a href="characterprofile.php?name=<?= urlencode($last['killed_by']) ?>"><?= htmlspecialchars($last['killed_by'], ENT_QUOTES, 'UTF-8') ?></a>
77+ </td>
78+ <td width="30%"><?= htmlspecialchars(getClock($last['time'], true), ENT_QUOTES, 'UTF-8') ?></td>
79+ <td width="35%">
80+ <a href="characterprofile.php?name=<?= urlencode($last['victim']) ?>"><?= htmlspecialchars($last['victim'], ENT_QUOTES, 'UTF-8') ?></a>
81+ </td>
82+ </tr>
83+ <?php endforeach; ?>
84+ </table>
85+ </div>
86+ <?php else: ?>
87+ <div class="znx-empty-box"><?= t('killers.no_kills') ?></div>
88+ <?php endif; ?>
89+
90+<?php elseif ($killersMode === 'legacy'): ?>
91+
92+ <?php if ($deaths): ?>
93+ <div class="znx-acct-head"><?= t('killers.latest') ?></div>
94+ <div class="znx-acct-table-wrap">
95+ <table id="deathsTable" class="znx-acct-table">
96+ <tr class="yellow">
97+ <th><?= t('killers.killer') ?></th>
98+ <th><?= t('common.time') ?></th>
99+ <th><?= t('killers.victim') ?></th>
100+ </tr>
101+ <?php foreach ($deaths as $death): ?>
102+ <tr>
103+ <td>
104+ <a href="characterprofile.php?name=<?= urlencode($death['killed_by']) ?>"><?= htmlspecialchars($death['killed_by'], ENT_QUOTES, 'UTF-8') ?></a>
105+ </td>
106+ <td><?= htmlspecialchars(getClock($death['time'], true), ENT_QUOTES, 'UTF-8') ?></td>
107+ <td>
108+ <?= t('deaths.at_level', ['level' => (int)$death['level']]) ?>
109+ <a href="characterprofile.php?name=<?= urlencode($death['victim']) ?>"><?= htmlspecialchars($death['victim'], ENT_QUOTES, 'UTF-8') ?></a>
110+ </td>
111+ </tr>
112+ <?php endforeach; ?>
113+ </table>
114+ </div>
115+ <?php else: ?>
116+ <div class="znx-empty-box"><?= t('killers.no_deaths') ?></div>
117+ <?php endif; ?>
118+
119+<?php endif; ?>
120+
121+</div><!-- .znx-acct -->
A layouts/default/views/login_2fa.php +30-0 View file
@@ -0,0 +1,30 @@
1+<?php
2+?>
3+<h2><?= t('twofa.title') ?></h2>
4+<?php if (empty($errors) === false): ?>
5+ <?= output_errors($errors) ?>
6+<?php endif; ?>
7+<p>
8+ <?php if ($pendingStatus['totp_enabled']): ?>
9+ <?= t_default('twofa2.enter_app_code', 'Enter the code from your authenticator app, or a recovery code.') ?>
10+ <?php else: ?>
11+ <?= t_default('twofa2.enter_email_code', 'We emailed you a verification code. Enter it below, or use a recovery code.') ?>
12+ <?php endif; ?>
13+</p>
14+<form class="loginForm" method="post" action="login.php">
15+ <ul>
16+ <li>
17+ <input type="text" name="tfa2_code" autocomplete="one-time-code" autofocus>
18+ </li>
19+ <?php if ((int)znote2fa_v2_config()['trusted_device_days'] > 0): ?>
20+ <li>
21+ <label><input type="checkbox" name="tfa2_trust" value="1"> <?= t_default('twofa2.trust_device', 'Remember this device') ?></label>
22+ </li>
23+ <?php endif; ?>
24+ <input type="hidden" name="tfa2_email_sent" value="1">
25+ <?php Token::create(); ?>
26+ <li>
27+ <input type="submit" value="<?= t('widget.login.submit') ?>">
28+ </li>
29+ </ul>
30+</form>
A layouts/default/views/login_form.php +28-0 View file
@@ -0,0 +1,28 @@
1+<?php
2+?>
3+<?php if (empty($errors) === false): ?>
4+ <h2><?= t('login.failed_title') ?></h2>
5+ <?= output_errors($errors) ?>
6+<?php endif; ?>
7+<form class="loginForm" action="login.php" method="post">
8+ <ul>
9+ <li>
10+ <?= t('widget.login.username') ?><br>
11+ <input type="text" name="username" id="login_username">
12+ </li>
13+ <li>
14+ <?= t('widget.login.password') ?><br>
15+ <input type="password" name="password" id="login_password">
16+ </li>
17+ <?php if ($config['twoFactorAuthenticator']): ?>
18+ <li>
19+ <?= t('widget.login.token') ?><br>
20+ <input type="password" name="authcode">
21+ </li>
22+ <?php endif; ?>
23+ <?php Token::create(); ?>
24+ <li>
25+ <input type="submit" value="<?= t('widget.login.submit') ?>">
26+ </li>
27+ </ul>
28+</form>
A layouts/default/views/market.php +160-0 View file
@@ -0,0 +1,160 @@
1+<?php
2+if ($marketLoadError !== ''): ?>
3+
4+ <div class="znx-acct">
5+ <div class="znx-acct-head"><?= t('market.title') ?></div>
6+ <div class="znx-empty-box">
7+ <p><?= t('market.load_failed2') ?></p>
8+ <p><?= t('market.tried_file') ?> <?php echo $marketLoadError; ?></p>
9+ <p><?= t('market.fix_path') ?></p>
10+ <p><?= t('market.check_permissions') ?></p>
11+ </div>
12+ </div>
13+
14+<?php elseif ($marketMode === 'list'): ?>
15+
16+ <div class="znx-acct">
17+ <div class="znx-acct-head"><?= t('market.title') ?></div>
18+ <div class="znx-acct-info"><?= t('market.hint') ?> <a target="_BLANK" href="http://znote.eu/images/depotmarket.jpg"><?= t('market.depot_link_text') ?></a> <br><?= t('market.sell_instructions') ?></div>
19+ <form action="" class="znx-acct-toolbar market_item_search">
20+ <div class="znx-acct-toolbar__field">
21+ <label for="compareSearch"><?= t('market.search') ?></label>
22+ <input type="text" id="compareSearch" name="compare" class="znx-acct-select">
23+ </div>
24+ <div class="znx-acct-toolbar__submit"><button type="submit" class="znx-acct-btn"><?= t('common.search') ?></button></div>
25+ </form>
26+ <div class="znx-acct-head"><?= t('market.wts') ?></div>
27+ <div class="znx-acct-table-wrap">
28+ <table class="znx-acct-table">
29+ <tr class="yellow">
30+ <td><?= t('market.item_name') ?></td>
31+ <td><?= t('common.item') ?></td>
32+ <td><?= t('common.count') ?></td>
33+ <td><?= t('market.price_for_1') ?></td>
34+ <td><?= t('common.added') ?></td>
35+ <td><?= t('common.by') ?></td>
36+ <td><?= t('market.compare') ?></td>
37+ </tr>
38+ <?php foreach (($offers['wts'] ?: array()) as $o): ?>
39+ <tr>
40+ <td><?php echo (isset($items[$o['item_id']])) ? $items[$o['item_id']] : $o['item_id']; ?></td>
41+ <td><img src="<?php echo htmlspecialchars(znote_item_image_url((int)$o["item_id"]), ENT_QUOTES); ?>" alt="<?= t('market.item_image_alt') ?>"></td>
42+ <td><?php echo $o['amount']; ?></td>
43+ <td><?php echo number_format($o['price'], 0, "", " "); ?></td>
44+ <td><?php echo getClock($o['created'], true, true); ?></td>
45+ <td><?php echo ($o['anonymous'] == 1) ? t('market.anonymous') : "<a target='_BLANK' href='characterprofile.php?name=".$o['player_name']."'>".$o['player_name']."</a>"; ?></td>
46+ <td><a href="?compare=<?php echo $o['item_id']; ?>" class="znx-acct-edit-btn"><?= t('market.compare') ?></a></td>
47+ </tr>
48+ <?php endforeach; ?>
49+ </table>
50+ </div>
51+ <div class="znx-acct-head"><?= t('market.wtb') ?></div>
52+ <div class="znx-acct-table-wrap">
53+ <table class="znx-acct-table">
54+ <tr class="yellow">
55+ <td><?= t('market.item_name') ?></td>
56+ <td><?= t('common.item') ?></td>
57+ <td><?= t('common.count') ?></td>
58+ <td><?= t('market.price_for_1') ?></td>
59+ <td><?= t('common.added') ?></td>
60+ <td><?= t('common.by') ?></td>
61+ <td><?= t('market.compare') ?></td>
62+ </tr>
63+ <?php foreach (($offers['wtb'] ?: array()) as $o): ?>
64+ <tr>
65+ <td><?php echo (isset($items[$o['item_id']])) ? $items[$o['item_id']] : $o['item_id']; ?></td>
66+ <td><img src="<?php echo htmlspecialchars(znote_item_image_url((int)$o["item_id"]), ENT_QUOTES); ?>" alt="<?= t('market.item_image_alt') ?>"></td>
67+ <td><?php echo $o['amount']; ?></td>
68+ <td><?php echo number_format($o['price'], 0, "", " "); ?></td>
69+ <td><?php echo getClock($o['created'], true, true); ?></td>
70+ <td><?php echo ($o['anonymous'] == 1) ? t('market.anonymous') : "<a target='_BLANK' href='characterprofile.php?name=".$o['player_name']."'>".$o['player_name']."</a>"; ?></td>
71+ <td><a href="?compare=<?php echo $o['item_id']; ?>" class="znx-acct-edit-btn"><?= t('market.compare') ?></a></td>
72+ </tr>
73+ <?php endforeach; ?>
74+ </table>
75+ </div>
76+ </div>
77+
78+<?php else: ?>
79+
80+ <div class="znx-acct">
81+ <?php if (!is_string($compare)): ?>
82+ <div class="znx-acct-head"><?= t('market.comparing_item', ['name' => $itemname]) ?></div>
83+ <?php else: ?>
84+ <div class="znx-acct-head"><?= t('market.search_result', ['query' => stripslashes($compare)]) ?></div>
85+ <?php endif; ?>
86+ <div class="znx-jump-top"><a href="market.php" class="znx-acct-edit-btn"><?= t('market.go_back') ?></a></div>
87+ <div class="znx-acct-head"><?= t('market.active') ?></div>
88+ <div class="znx-acct-table-wrap">
89+ <table class="znx-acct-table">
90+ <tr class="yellow">
91+ <td><?= t('market.item_name') ?></td>
92+ <td><?= t('common.item') ?></td>
93+ <td><?= t('common.count') ?></td>
94+ <td><?= t('market.price_for_1') ?></td>
95+ <td><?= t('common.added') ?></td>
96+ <td><?= t('common.by') ?></td>
97+ </tr>
98+ <?php foreach ($activeSellOffers as $o): ?>
99+ <tr>
100+ <td><?php echo (isset($items[$o['item_id']])) ? $items[$o['item_id']] : $o['item_id']; ?></td>
101+ <td><img src="<?php echo htmlspecialchars(znote_item_image_url((int)$o["item_id"]), ENT_QUOTES); ?>" alt="<?= t('market.item_image_alt') ?>"></td>
102+ <td><?php echo $o['amount']; ?></td>
103+ <td><?php echo number_format($o['price'], 0, "", " "); ?></td>
104+ <td><?php echo getClock($o['created'], true, true); ?></td>
105+ <td><?php echo ($o['anonymous'] == 1) ? t('market.anonymous') : "<a target='_BLANK' href='characterprofile.php?name=".$o['player_name']."'>".$o['player_name']."</a>"; ?></td>
106+ </tr>
107+ <?php endforeach; ?>
108+ </table>
109+ </div>
110+
111+ <?php if ($buylist !== false): ?>
112+ <div class="znx-acct-head"><?= t('market.want_to_buy') ?></div>
113+ <div class="znx-acct-table-wrap">
114+ <table class="znx-acct-table">
115+ <tr class="yellow">
116+ <td><?= t('market.item_name') ?></td>
117+ <td><?= t('common.item') ?></td>
118+ <td><?= t('common.count') ?></td>
119+ <td><?= t('market.price_for_1') ?></td>
120+ <td><?= t('common.added') ?></td>
121+ <td><?= t('common.by') ?></td>
122+ </tr>
123+ <?php foreach ($buylist as $o): ?>
124+ <tr>
125+ <td><?php echo (isset($items[$o['item_id']])) ? $items[$o['item_id']] : $o['item_id']; ?></td>
126+ <td><img src="<?php echo htmlspecialchars(znote_item_image_url((int)$o["item_id"]), ENT_QUOTES); ?>" alt="<?= t('market.item_image_alt') ?>"></td>
127+ <td><?php echo $o['amount']; ?></td>
128+ <td><?php echo number_format($o['price'], 0, "", " "); ?></td>
129+ <td><?php echo getClock($o['created'], true, true); ?></td>
130+ <td><?php echo ($o['anonymous'] == 1) ? t('market.anonymous') : "<a target='_BLANK' href='characterprofile.php?name=".$o['player_name']."'>".$o['player_name']."</a>"; ?></td>
131+ </tr>
132+ <?php endforeach; ?>
133+ </table>
134+ </div>
135+ <?php endif; ?>
136+
137+ <div class="znx-acct-head"><?= t('market.old') ?></div>
138+ <div class="znx-acct-table-wrap">
139+ <table class="znx-acct-table">
140+ <tr class="yellow">
141+ <td><?= t('market.item_name') ?></td>
142+ <td><?= t('common.item') ?></td>
143+ <td><?= t('common.count') ?></td>
144+ <td><?= t('market.price_for_1') ?></td>
145+ <td><?= t('market.sold') ?></td>
146+ </tr>
147+ <?php foreach (($historyOffers ?: array()) as $o): ?>
148+ <tr>
149+ <td><?php echo (isset($items[$o['item_id']])) ? $items[$o['item_id']] : $o['item_id']; ?></td>
150+ <td><img src="<?php echo htmlspecialchars(znote_item_image_url((int)$o["item_id"]), ENT_QUOTES); ?>" alt="<?= t('market.item_image_alt') ?>"></td>
151+ <td><?php echo $o['amount']; ?></td>
152+ <td><?php echo number_format($o['price'], 0, "", " "); ?></td>
153+ <td><?php echo getClock($o['inserted'], true, true); ?></td>
154+ </tr>
155+ <?php endforeach; ?>
156+ </table>
157+ </div>
158+ </div>
159+
160+<?php endif; ?>
A layouts/default/views/monster_loot.php +100-0 View file
@@ -0,0 +1,100 @@
1+<?php
2+/**
3+ * Monster loot checker.
4+ *
5+ * Prepared by monster_loot.php:
6+ * $monsterLootError message when an XML file could not be read, else ''
7+ * $itemList [item id => item name]
8+ * $rarity [label => minimum percent], highest first
9+ * $monsterList name / state ('loot','empty','failed') / file / loot rows
10+ *
11+ * Nothing is read from disk here.
12+ */
13+
14+/** The rarity label for a drop chance. */
15+function znote_loot_rarity(float $chance, array $rarity): string {
16+ foreach ($rarity as $label => $percent) {
17+ if ($chance >= $percent) {
18+ return $label;
19+ }
20+ }
21+ return '';
22+}
23+
24+$lootParam = isset($_GET['lootrate']) ? '&lootrate' : '';
25+?>
26+<script>
27+ function toggleVisibility(obj) {
28+ var el = document.getElementById('d' + obj.id);
29+ var name = obj.innerHTML.substring(4);
30+
31+ if (el.style.display == 'none') {
32+ obj.innerHTML = '[ -]';
33+ el.style.display = 'block';
34+ } else {
35+ obj.innerHTML = '[+]';
36+ el.style.display = 'none';
37+ }
38+ obj.innerHTML += ' ' + name;
39+ }
40+</script>
41+
42+<div class="znx-acct">
43+
44+<div class="znx-acct-head"><?= t_default('loot.title', 'Monster Loot') ?></div>
45+
46+<div class="znx-pill-nav">
47+ <a href="monster_loot.php<?= $lootParam ? '?lootrate' : '' ?>"><?= t('loot.hide_none') ?></a>
48+ <a href="?hidefail<?= $lootParam ?>"><?= t('loot.hide_notfound') ?></a>
49+ <a href="?hideempty<?= $lootParam ?>"><?= t('loot.hide_empty') ?></a>
50+ <a href="?hideempty&amp;hidefail<?= $lootParam ?>"><?= t('loot.hide_all') ?></a>
51+ <a href="monster_loot.php"><?= t('loot.normal_rate') ?></a>
52+ <a href="?lootrate"><?= t('loot.server_rate') ?></a>
53+</div>
54+
55+<?php if ($monsterLootError !== ''): ?>
56+
57+ <div class="znx-empty-box"><?= htmlspecialchars($monsterLootError, ENT_QUOTES, 'UTF-8') ?></div>
58+
59+<?php else: ?>
60+
61+ <div class="znx-acct-info">
62+
63+ <?php $i = 0; foreach ($monsterList as $monster): $i++; ?>
64+
65+ <?php if ($monster['state'] === 'loot'): ?>
66+
67+ <a id="<?= $i ?>" href="javascript:void(0);" onclick="toggleVisibility(this)"
68+ style="text-decoration:none; font:bold 14px verdana; color:orange;">
69+ [+] <?= htmlspecialchars($monster['name'], ENT_QUOTES, 'UTF-8') ?>
70+ </a>
71+ <br>
72+ <div id="d<?= $i ?>" style="display:none;"><br>
73+ <?php foreach ($monster['loot'] as $drop): ?>
74+ <?= str_repeat('... ', $drop['level']) ?>
75+ <u><?= $drop['count'] ?: 1 ?></u>
76+ <span style="color:#7878FF; font-weight:bold;"><?= htmlspecialchars($itemList[$drop['id']] ?? '?', ENT_QUOTES, 'UTF-8') ?></span>
77+ - <span style="color:#C45; font-weight:bold;"><?= htmlspecialchars(znote_loot_rarity($drop['chance'], $rarity), ENT_QUOTES, 'UTF-8') ?></span>
78+ (<span style="color:#FF9A9A;"><?= $drop['chance'] ?>%</span>)<br>
79+ <?php endforeach; ?>
80+ <br>
81+ </div>
82+
83+ <?php elseif ($monster['state'] === 'empty' && !isset($_GET['hideempty'])): ?>
84+
85+ <span style="font:bold 14px verdana; color:red;">[x] <?= htmlspecialchars($monster['name'], ENT_QUOTES, 'UTF-8') ?></span><br>
86+
87+ <?php elseif ($monster['state'] === 'failed' && !isset($_GET['hidefail'])): ?>
88+
89+ <span><?= t('loot.failed') ?> <b><?= htmlspecialchars($monster['name'], ENT_QUOTES, 'UTF-8') ?></b>
90+ <i>(<?= htmlspecialchars($monster['file'], ENT_QUOTES, 'UTF-8') ?>)</i></span><br>
91+
92+ <?php endif; ?>
93+
94+ <?php endforeach; ?>
95+
96+ </div>
97+
98+<?php endif; ?>
99+
100+</div><!-- .znx-acct -->
A layouts/default/views/myaccount.php +69-0 View file
@@ -0,0 +1,69 @@
1+<div class="znx-acct">
2+
3+<div class="znx-acct-head"><?= t('acc.page_title') ?></div>
4+
5+<div class="znx-acct-info">
6+ <p><?= t('acc.welcome') ?> <strong><?php echo $user_data['name']; ?></strong><br>
7+ <?php
8+ if ($user_data['premdays'] != 0) echo t('acc.premium_days', ['days' => $user_data['premdays']]);
9+ else echo t('acc.free_account');
10+
11+ if ($config['mailserver']['myaccount_verify_email']):
12+ ?><br><?= t('login.email') ?>: <?php echo $user_data['email'];
13+ if ($user_znote_data['active_email'] == 1) {
14+ ?> (<?= t('acc.verified_short') ?>).<?php
15+ } else {
16+ ?><br><strong><?= t('acc.email_not_verified') ?> <a href="?authenticate"><?= t('acc.please_verify') ?></a>.</strong><?php
17+ }
18+ endif; ?>
19+ </p>
20+
21+ <?php if ($twofa2_status !== null || $legacy_twofa_status !== null): ?>
22+ <div class="znx-acct-2fa">
23+ <?php if ($twofa2_status !== null): ?>
24+ <span class="znx-acct-2fa__row"><?= t_default('twofa2.website_status', 'Website 2FA:') ?> <a href="twofa.php" class="znx-acct-badge <?= $twofa2_status['any_enabled'] ? 'is-on' : 'is-off' ?>"><?= $twofa2_status['any_enabled'] ? t_default('common.enabled', 'Enabled') : t_default('common.disabled', 'Disabled') ?></a></span>
25+ <?php endif; ?>
26+ <?php if ($legacy_twofa_status !== null): ?>
27+ <span class="znx-acct-2fa__row"><?= t_default('twofa2.legacy_status', 'Legacy game 2FA:') ?> <a href="twofa.php" class="znx-acct-badge <?= $legacy_twofa_status ? 'is-on' : 'is-off' ?>"><?= $legacy_twofa_status ? t_default('common.enabled', 'Enabled') : t_default('common.disabled', 'Disabled') ?></a></span>
28+ <?php endif; ?>
29+ </div>
30+ <?php endif; ?>
31+</div>
32+
33+<div class="znx-acct-head"><?= t('acc.char_list_count', ['count' => $char_count]) ?></div>
34+<?php if ($char_array): ?>
35+ <div class="znx-acct-table-wrap">
36+ <table id="myaccountTable" class="znx-acct-table">
37+ <tr class="yellow">
38+ <th><?= mb_strtoupper(t('common.name')) ?></th>
39+ <th><?= mb_strtoupper(t('common.level')) ?></th>
40+ <th><?= mb_strtoupper(t('common.vocation')) ?></th>
41+ <th><?= mb_strtoupper(t('common.town')) ?></th>
42+ <th><?= mb_strtoupper(t('char.last_login')) ?></th>
43+ <th><?= mb_strtoupper(t('common.status')) ?></th>
44+ <th><?= mb_strtoupper(t('acc.hide_col')) ?></th>
45+ <th></th>
46+ </tr>
47+ <?php foreach ($char_array as $value): ?>
48+ <tr>
49+ <td><a href="characterprofile.php?name=<?php echo $value['name']; ?>"><?php echo $value['name']; ?></a></td>
50+ <td><?php echo $value['level']; ?></td>
51+ <td><?php echo $value['vocation']; ?></td>
52+ <td><?php echo $value['town_id']; ?></td>
53+ <td><?php echo $value['lastlogin']; ?></td>
54+ <td><?php echo $value['online']; ?></td>
55+ <td><?php echo hide_char_to_name($value['hide_char']); ?></td>
56+ <td><a href="page.php?p=editcharacter&character=<?php echo urlencode($value['name']); ?>" class="znx-acct-edit-btn"><?= t_default('acc.edit_char', 'Edit') ?></a></td>
57+ </tr>
58+ <?php endforeach; ?>
59+ </table>
60+ </div>
61+ <?php else: ?>
62+ <div class="znx-empty-box"><?= t('acc.no_characters') ?></div>
63+ <?php endif; ?>
64+
65+</div><!-- .znx-acct -->
66+
67+<div id="myaccount">
68+ <h2 class="sr-only"><?= t_default('acc.plugins_heading', 'Account plugins') ?></h2>
69+</div>
A layouts/default/views/myaccount_edit_comment.php +18-0 View file
@@ -0,0 +1,18 @@
1+<h1><?= t('acc.change_comment_on') ?></h1>
2+<form action="" method="post">
3+ <ul>
4+ <li>
5+ <input name="action" type="hidden" value="update_comment">
6+ <input name ="selected_character" type="text" value="<?php echo $char_name; ?>" readonly="readonly">
7+ </li>
8+ <li>
9+ <font class="profile_font" name="profile_font_comment"><?= t('acc.comment') ?></font> <br>
10+ <textarea name="comment" cols="70" rows="10"><?php echo $comment_data['comment']; ?></textarea>
11+ </li>
12+ <?php
13+ /* Form file */
14+ Token::create();
15+ ?>
16+ <li><input type="submit" value="<?= t('acc.update_comment') ?>"></li>
17+ </ul>
18+</form>
A layouts/default/views/onlinelist.php +107-0 View file
@@ -0,0 +1,107 @@
1+<?php
2+// End cache
3+
4+?>
5+<div class="znx-acct">
6+
7+<div class="znx-acct-head"><?= t('online.heading') ?></div>
8+
9+<?php
10+/**
11+ * $onlineNow, $onlineRecord and $onlineBroken come from onlinelist.php.
12+ * The record lives in znote_config, not in a table of its own.
13+ */
14+if (!empty($onlineRecord['players'])): ?>
15+ <div class="znx-acct-info">
16+ <?php if (!empty($onlineBroken)): ?>
17+ <strong><?= t('online.new_record') ?></strong>
18+ <?= t('online.new_record_line', ['count' => (int)$onlineNow]) ?>
19+ <?php else: ?>
20+ <?= t('online.record_line', ['count' => (int)$onlineRecord['players'], 'date' => htmlspecialchars(getClock((int)$onlineRecord['time'], true), ENT_QUOTES, 'UTF-8')]) ?>
21+ <?php endif; ?>
22+ </div>
23+<?php endif; ?>
24+<?php
25+
26+// Players currently logged in
27+if (!empty($array) && $array !== false): ?>
28+ <div class="znx-acct-head"><?= t('online.currently') ?></div>
29+ <div class="znx-acct-table-wrap">
30+ <table id="onlinelistTable" class="znx-acct-table">
31+ <tr class="yellow">
32+ <?php if ($loadOutfits) echo "<th>". t('common.outfit') ."</th>"; ?>
33+ <th><?= t('online.label_name') ?></th>
34+ <th><?= t('online.label_guild') ?></th>
35+ <th><?= t('online.label_level') ?></th>
36+ <th><?= t('online.label_vocation') ?></th>
37+ </tr>
38+ <?php
39+ foreach ($array as $value):
40+ $url = url("characterprofile.php?name=". $value['name']);
41+ $flag = ($loadFlags === true && strlen($value['flag']) > 1) ? '<img src="' . $config['country_flags']['server'] . '/' . $value['flag'] . '.png"> ' : '';
42+ $guildname = (!empty($value['gname'])) ? '<a href="guilds.php?name='. $value['gname'] .'">'. $value['gname'] .'</a>' : '';
43+ ?>
44+ <tr class="special">
45+ <?php if ($loadOutfits): ?>
46+ <td class="outfitColumn"><img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $value['type']; ?>&addons=<?php echo $value['addons']; ?>&head=<?php echo $value['head']; ?>&body=<?php echo $value['body']; ?>&legs=<?php echo $value['legs']; ?>&feet=<?php echo $value['feet']; ?>" alt="img"></td>
47+ <?php endif; ?>
48+ <td><?php echo $flag; ?><a href="characterprofile.php?name=<?php echo $value['name']; ?>"><?php echo $value['name']; ?></a></td>
49+ <td><?php echo $guildname; ?></td>
50+ <td><?php echo $value['level']; ?></td>
51+ <td><?php echo vocation_id_to_name($value['vocation']); ?></td>
52+ </tr>
53+ <?php
54+ endforeach; ?>
55+ </table>
56+ </div>
57+ <?php
58+else:
59+ ?>
60+ <div class="znx-empty-box"><?= t('online.nobody') ?></div>
61+ <?php
62+endif;
63+
64+// Players online logout history
65+if ($history["enabled"]) {
66+ $time = time();
67+ if (!empty($recents) && $recents !== false): ?>
68+ <div class="znx-acct-head"><?= t('online.past_days', ['days' => $history['days']]) ?></div>
69+ <div class="znx-acct-table-wrap">
70+ <table id="recentlistTable" class="znx-acct-table">
71+ <tr class="yellow">
72+ <?php if ($loadOutfits) echo "<th>". t('common.outfit') ."</th>"; ?>
73+ <th><?= t('online.label_name') ?></th>
74+ <th><?= t('online.label_guild') ?></th>
75+ <th><?= t('online.label_level') ?></th>
76+ <th><?= t('online.logout_days') ?></th>
77+ </tr>
78+ <?php
79+ foreach ($recents as $value):
80+ $days = floor(($time - $value['lastlogout']) / 86400);
81+ $url = url("characterprofile.php?name=". $value['name']);
82+ $flag = ($loadFlags === true && strlen($value['flag']) > 1) ? '<img src="' . $config['country_flags']['server'] . '/' . $value['flag'] . '.png"> ' : '';
83+ $guildname = (!empty($value['gname'])) ? '<a href="guilds.php?name='. $value['gname'] .'">'. $value['gname'] .'</a>' : '';
84+ ?>
85+ <tr class="special">
86+ <?php if ($loadOutfits): ?>
87+ <td class="outfitColumn"><img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $value['type']; ?>&addons=<?php echo $value['addons']; ?>&head=<?php echo $value['head']; ?>&body=<?php echo $value['body']; ?>&legs=<?php echo $value['legs']; ?>&feet=<?php echo $value['feet']; ?>" alt="img"></td>
88+ <?php endif; ?>
89+ <td><?php echo $flag; ?><a href="characterprofile.php?name=<?php echo $value['name']; ?>"><?php echo $value['name']; ?></a></td>
90+ <td><?php echo $guildname; ?></td>
91+ <td><?php echo $value['level']; ?></td>
92+ <td><?php echo "{$days}D: " . getClock($value['lastlogout'], true); ?></td>
93+ </tr>
94+ <?php
95+ endforeach; ?>
96+ </table>
97+ </div>
98+ <?php
99+ else:
100+ ?>
101+ <div class="znx-empty-box"><?= t('online.nobody_past_days', ['days' => $history['days']]) ?></div>
102+ <?php
103+ endif;
104+}
105+?>
106+
107+</div><!-- .znx-acct -->
A layouts/default/views/payment_message.php +4-0 View file
@@ -0,0 +1,4 @@
1+<?php
2+?>
3+<h1><?= $paymentMessage['title'] ?></h1>
4+<p><?= $paymentMessage['text'] ?></p>
A layouts/default/views/powergamers.php +40-0 View file
@@ -0,0 +1,40 @@
1+<?php
2+?>
3+<table id="tbl_powergamers">
4+ <thead>
5+ <tr>
6+ <th colspan="9"><h1><?= t('powergamers.title') ?></h1></th>
7+ </tr>
8+ <tr>
9+ <th><?= t('common.name') ?></th>
10+ <th><?= t('powergamers.diff') ?></th>
11+ <th><?php echo $dates['d0ago']; ?></th>
12+ <th><?php echo $dates['d1ago']; ?></th>
13+ <th><?php echo $dates['d2ago']; ?></th>
14+ <th><?php echo $dates['d3ago']; ?></th>
15+ <th><?php echo $dates['d4ago']; ?></th>
16+ <th><?php echo $dates['d5ago']; ?></th>
17+ <th><?php echo $dates['d6ago']; ?></th>
18+ </tr>
19+ </thead>
20+ <tbody>
21+ <?php foreach($players AS $i => $player): ?>
22+ <tr>
23+ <td><?php echo $i+1 .". "; ?><a href="/characterprofile.php?name=<?php echo $player['name']; ?>"><?php echo $player['name']; ?></a></td>
24+ <td><?php echo number_format($player['diff_exp'] / 1000,0,'',' '); ?></td>
25+ <td><?php echo number_format($player['diff_0'] / 1000,0,'',' '); ?></td>
26+ <td><?php echo number_format($player['diff_1'] / 1000,0,'',' '); ?></td>
27+ <td><?php echo number_format($player['diff_2'] / 1000,0,'',' '); ?></td>
28+ <td><?php echo number_format($player['diff_3'] / 1000,0,'',' '); ?></td>
29+ <td><?php echo number_format($player['diff_4'] / 1000,0,'',' '); ?></td>
30+ <td><?php echo number_format($player['diff_5'] / 1000,0,'',' '); ?></td>
31+ <td><?php echo number_format($player['diff_6'] / 1000,0,'',' '); ?></td>
32+ </tr>
33+ <?php endforeach; ?>
34+ </tbody>
35+</table>
36+<style type="text/css">
37+ #tbl_powergamers {
38+ padding: 0;
39+ }
40+</style>
A layouts/default/views/protected.php +16-0 View file
@@ -0,0 +1,16 @@
1+<?php
2+if (user_logged_in() === true) {
3+?>
4+
5+<h1><?= t('protected.stop') ?></h1>
6+<p><?= t('protected.sniffing') ?></p>
7+
8+<?php
9+} else {
10+?>
11+
12+<h1><?= t('protected.need_login') ?></h1>
13+<p><?= t('protected.register') ?></p>
14+
15+<?php
16+}
A layouts/default/views/register_authenticate_result.php +5-0 View file
@@ -0,0 +1,5 @@
1+<?php if ($ok): ?>
2+ <h1><?= t('common.congrats') ?></h1> <p><?= t('reg.created') ?></p>
3+<?php else: ?>
4+ <h1><?= t('acc.auth_failed') ?></h1> <p><?= t('acc.auth_failed_text') ?></p>
5+<?php endif; ?>
A layouts/default/views/register_form.php +66-0 View file
@@ -0,0 +1,66 @@
1+<form action="" method="post">
2+ <ul>
3+ <li><?= t('reg.label_name') ?><br>
4+ <input type="text" name="username">
5+ </li>
6+
7+ <li><?= t('reg.label_pw') ?><br>
8+ <input type="password" name="password">
9+ </li>
10+
11+ <li><?= t('reg.label_pw2') ?><br>
12+ <input type="password" name="password_again">
13+ </li>
14+
15+ <li><?= t('login.email') ?>:<br>
16+ <input type="text" name="email">
17+ </li>
18+
19+ <li><?= t('reg.label_country') ?><br>
20+ <select name="flag">
21+ <option value=""><?= t('reg.please_choose') ?></option>
22+ <?php
23+ foreach(array('pl', 'se', 'br', 'us', 'gb', ) as $c)
24+ echo '<option value="' . $c . '">' . $config['countries'][$c] . '</option>';
25+
26+ echo '<option value="">----------</option>';
27+ foreach($config['countries'] as $code => $c)
28+ echo '<option value="' . $code . '">' . $c . '</option>';
29+ ?>
30+ </select>
31+ </li>
32+
33+ <?php
34+ if ($config['use_captcha']) {
35+ ?>
36+ <li>
37+ <div class="g-recaptcha" data-sitekey="<?php echo $config['captcha_site_key']; ?>"></div>
38+ </li>
39+ <?php
40+ }
41+ ?>
42+
43+ <li><h2><?= t('reg.rules_title') ?></h2>
44+ <p><?= t('reg.rule_golden') ?></p>
45+ <p><?= t('reg.rule_pwned') ?></p>
46+ <p><?= t('reg.rule_no_cheating', ['link' => '<a href="https://en.wikipedia.org/wiki/Cheating_in_video_games" target="_blank">' . t('reg.cheating_word') . '</a>']) ?></p>
47+ <p><?= t('reg.rule_no_botting', ['link' => '<a href="https://en.wikipedia.org/wiki/Video_game_bot" target="_blank">' . t('reg.botting_word') . '</a>']) ?></p>
48+ <p><?= t('reg.rule_staff_power') ?></p>
49+ </li>
50+
51+ <li><?= t('reg.rules_agree') ?><br>
52+ <select name="selected">
53+ <option value="0"><?= t('reg.agree_umh') ?></option>
54+ <option value="1"><?= t('reg.agree_yes') ?></option>
55+ <option value="2"><?= t('reg.agree_no') ?></option>
56+ </select>
57+ </li>
58+ <?php
59+ /* Form file */
60+ Token::create();
61+ ?>
62+ <li>
63+ <input type="submit" value="<?= t('reg.submit') ?>">
64+ </li>
65+ </ul>
66+</form>
A layouts/default/views/register_header.php +1-0 View file
@@ -0,0 +1,1 @@
1+<h1><?= t('reg.heading') ?></h1>
A layouts/default/views/register_success.php +7-0 View file
@@ -0,0 +1,7 @@
1+<?php if ($emailRequired): ?>
2+ <h1><?= t('reg.email_required') ?></h1>
3+ <p><?= t('reg.activation_sent') ?></p>
4+ <p><?= t('acc.check_junk_spam') ?></p>
5+<?php else: ?>
6+ <?= t('reg.created') ?>
7+<?php endif; ?>
A layouts/default/views/serverinfo.php +213-0 View file
@@ -0,0 +1,213 @@
1+<?php
2+/**
3+ * Server information.
4+ *
5+ * Prepared by serverinfo.php - see the docblock there for the variables.
6+ */
7+?>
8+
9+<div class="znx-acct">
10+
11+<div class="znx-acct-head"><?= t('srv.title') ?></div>
12+<div class="znx-acct-info"><?= t('srv.intro') ?> <b><?php echo $config['site_title']; ?></b></div>
13+
14+<?php minimap_render(); ?>
15+
16+<?php
17+if (
18+ ($stagesData && isset($stagesData['enabled']) && $stagesData['enabled'])
19+ || (isset($luaConfig['experienceStages']) && $luaConfig['experienceStages'] === true)
20+):
21+ $stages = true; ?>
22+ <div class="znx-acct-head"><?= t('srv.rates') ?></div>
23+ <div class="znx-acct-table-wrap">
24+ <table class="znx-acct-table">
25+ <tbody>
26+ <tr class="yellow">
27+ <td><?= t('srv.min_level') ?></td>
28+ <td><?= t('srv.max_level') ?></td>
29+ <td><?= t('srv.multiplier') ?></td>
30+ </tr>
31+ <?php foreach ($stagesData['stages'] as $stage): ?>
32+ <tr>
33+ <td><?php echo $stage['minlevel']; ?></td>
34+ <td><?php echo (isset($stage['maxlevel'])) ? $stage['maxlevel'] : t('common.unlimited'); ?></td>
35+ <td><?php echo $stage['multiplier']; ?>x</td>
36+ </tr>
37+ <?php endforeach; ?>
38+ </tbody>
39+ </table>
40+ </div>
41+<?php endif; ?>
42+
43+<?php if ($luaConfig): ?>
44+ <div class="znx-acct-table-wrap">
45+ <table class="znx-acct-table">
46+ <tbody>
47+ <tr class="yellow">
48+ <?php if (!$stages): ?>
49+ <td><?= t('srv.exp_rate') ?></td>
50+ <?php endif; ?>
51+ <td><?= t('srv.skill_rate') ?></td>
52+ <td><?= t('srv.magic_rate') ?></td>
53+ <td><?= t('srv.loot_rate') ?></td>
54+ </tr>
55+ <tr>
56+ <?php if (!$stages): ?>
57+ <td><?php echo $luaConfig['rateExp']; ?></td>
58+ <?php endif; ?>
59+ <td><?php echo $luaConfig['rateSkill']; ?></td>
60+ <td><?php echo $luaConfig['rateMagic']; ?></td>
61+ <td><?php echo $luaConfig['rateLoot']; ?></td>
62+ </tr>
63+ </tbody>
64+ </table>
65+ </div>
66+
67+ <div class="znx-acct-head"><?= t('srv.misc') ?></div>
68+ <div class="znx-acct-table-wrap">
69+ <table class="znx-acct-table">
70+ <tbody>
71+ <tr class="yellow">
72+ <td colspan="2"><?= t('srv.connection') ?></td>
73+ </tr>
74+ <tr>
75+ <td><?= t('srv.client') ?></td>
76+ <td><?php echo ($config['client'] / 100); ?></td>
77+ </tr>
78+ <tr>
79+ <td>IP</td>
80+ <td><?php echo $_SERVER['SERVER_NAME']; ?></td>
81+ </tr>
82+ <tr>
83+ <td><?= t('srv.port') ?></td>
84+ <td><?php echo $luaConfig['loginProtocolPort']; ?></td>
85+ </tr>
86+ </tbody>
87+ </table>
88+ </div>
89+
90+ <div class="znx-acct-table-wrap">
91+ <table class="znx-acct-table">
92+ <tbody>
93+ <tr class="yellow">
94+ <td colspan="2"><?= t('srv.pvp') ?></td>
95+ </tr>
96+ <tr>
97+ <td><?= t('srv.world_type') ?></td>
98+ <td><?php echo $luaConfig['worldType']; ?></td>
99+ </tr>
100+ <tr>
101+ <td><?= t('srv.hotkey_aimbot') ?></td>
102+ <td><?php echo toYesNo($luaConfig['hotkeyAimbotEnabled']); ?></td>
103+ </tr>
104+ <tr>
105+ <td><?= t('srv.protection_level') ?></td>
106+ <td><?php echo $luaConfig['protectionLevel']; ?></td>
107+ </tr>
108+ <tr>
109+ <td><?= t('srv.red_skull') ?></td>
110+ <td><?php echo $luaConfig['killsToRedSkull']; ?></td>
111+ </tr>
112+ <tr>
113+ <td><?= t('srv.black_skull') ?></td>
114+ <td><?php echo $luaConfig['killsToBlackSkull']; ?></td>
115+ </tr>
116+ <tr>
117+ <td><?= t('srv.rune_charges') ?></td>
118+ <td><?php echo toYesNo($luaConfig['removeChargesFromRunes']); ?></td>
119+ </tr>
120+ <?php if (isset($luaConfig['timeToDecreaseFrags'])): ?>
121+ <tr>
122+ <td><?= t('srv.frag_decrease') ?></td><!-- Legacy servers might need to remove *1000 -->
123+ <td><?php echo toDuration($luaConfig['timeToDecreaseFrags']*1000); ?></td>
124+ </tr>
125+ <?php endif; ?>
126+ <tr>
127+ <td><?= t('srv.exp_by_pk') ?></td>
128+ <td><?php echo toYesNo($luaConfig['experienceByKillingPlayers']); ?></td>
129+ </tr>
130+
131+ <?php if ($luaConfig['experienceByKillingPlayers']): ?>
132+ <tr>
133+ <td><?= t('srv.exp_threshold') ?></td>
134+ <td><?php echo $luaConfig['expFromPlayersLevelRange']; ?>% of your level</td>
135+ </tr>
136+ <?php endif; ?>
137+
138+ <tr>
139+ <td><?= t('srv.white_skull') ?></td>
140+ <td><?php echo toDuration($luaConfig['whiteSkullTime']); ?></td>
141+ </tr>
142+ <tr>
143+ <td><?= t('srv.pz_lock') ?></td>
144+ <td><?php echo toDuration($luaConfig['pzLocked']); ?></td>
145+ </tr>
146+ <tr>
147+ <td><?= t('srv.stair_jump') ?></td>
148+ <td><?php echo toDuration($luaConfig['stairJumpExhaustion']); ?></td>
149+ </tr>
150+ </tbody>
151+ </table>
152+ </div>
153+
154+ <div class="znx-acct-table-wrap">
155+ <table class="znx-acct-table">
156+ <tbody>
157+ <tr class="yellow">
158+ <td colspan="2"><?= t('srv.other') ?></td>
159+ </tr>
160+ <tr>
161+ <td><?= t('srv.free_premium') ?></td>
162+ <td><?php echo toYesNo($luaConfig['freePremium']); ?></td>
163+ </tr>
164+ <tr>
165+ <td><?= t('srv.house_rent') ?></td>
166+ <td><?php echo $luaConfig['houseRentPeriod']; ?></td>
167+ </tr>
168+ <tr>
169+ <td><?= t('srv.house_price') ?></td>
170+ <td><?php echo $luaConfig['housePriceEachSQM']; ?> gp</td>
171+ </tr>
172+ <tr>
173+ <td><?= t('srv.afk_kick') ?></td>
174+ <td><?php echo toDuration($luaConfig['kickIdlePlayerAfterMinutes'] * 60 * 1000); ?></td>
175+ </tr>
176+ <tr>
177+ <td><?= t('srv.one_per_account') ?></td>
178+ <td><?php echo toYesNo($luaConfig['onePlayerOnlinePerAccount']); ?></td>
179+ </tr>
180+ <tr>
181+ <td><?= t('srv.max_players') ?></td>
182+ <td><?php echo ($luaConfig['maxPlayers'] > 0) ? $luaConfig['maxPlayers'] : t('common.unlimited'); ?></td>
183+ </tr>
184+ <tr>
185+ <td><?= t('srv.outfit_change') ?></td>
186+ <td><?php echo toYesNo($luaConfig['allowChangeOutfit']); ?></td>
187+ </tr>
188+ <?php if (isset($luaConfig['staminaSystem'])): ?>
189+ <tr>
190+ <td><?= t('srv.stamina') ?></td>
191+ <td><?php echo toYesNo($luaConfig['staminaSystem']); ?></td>
192+ </tr>
193+ <?php endif; ?>
194+ <?php if (isset($luaConfig['premiumToCreateMarketOffer'])): ?>
195+ <tr>
196+ <td><?= t('srv.market_premium') ?></td>
197+ <td><?php echo toYesNo($luaConfig['premiumToCreateMarketOffer']); ?></td>
198+ </tr>
199+ <?php endif; ?>
200+ <?php if (isset($luaConfig['marketOfferDuration'])): ?>
201+ <tr>
202+ <td><?= t('srv.market_duration') ?></td>
203+ <td><?php echo toDuration($luaConfig['marketOfferDuration'] * 1000); ?></td>
204+ </tr>
205+ <?php endif; ?>
206+ </tbody>
207+ </table>
208+ </div>
209+<?php else: ?>
210+ <div class="znx-empty-box"><?= h(t('srv.not_imported')) ?></div>
211+<?php endif; ?>
212+
213+</div><!-- .znx-acct -->
A layouts/default/views/settings.php +51-0 View file
@@ -0,0 +1,51 @@
1+<?php
2+/**
3+ * Account settings.
4+ *
5+ * Prepared by settings.php:
6+ * $formState 'success' | 'errors' | 'form'
7+ * $errors array of messages, when $formState is 'errors'
8+ *
9+ * The account write happens in settings.php, never here.
10+ */
11+?>
12+<div class="znx-acct">
13+
14+<div class="znx-acct-head"><?= t('settings.title') ?></div>
15+
16+<?php if ($formState === 'success'): ?>
17+
18+ <div class="znx-acct-info znx-editchar-notice znx-editchar-notice--ok"><?= t('settings.success') ?></div>
19+
20+<?php else: ?>
21+
22+ <?php if ($formState === 'errors'): ?>
23+ <div class="znx-acct-info znx-editchar-notice znx-editchar-notice--error"><?= output_errors($errors) ?></div>
24+ <?php endif; ?>
25+
26+ <form action="" method="post" class="znx-editchar-box">
27+ <div class="znx-settings-field">
28+ <label><?= t('settings.email') ?></label>
29+ <input type="text" name="new_email" value="<?php echo $user_data['email']; ?>" class="znx-acct-select">
30+ </div>
31+ <div class="znx-settings-field">
32+ <label><?= t('settings.country') ?></label>
33+ <select name="new_flag" id="flag_select" class="znx-acct-select">
34+ <option value=""><?= t('settings.choose') ?></option>
35+ <?php
36+ foreach(array('pl', 'se', 'br', 'us', 'gb', ) as $c)
37+ echo '<option value="' . $c . '">' . $config['countries'][$c] . '</option>';
38+
39+ echo '<option value="">----------</option>';
40+ foreach($config['countries'] as $code => $c)
41+ echo '<option value="' . $code . '"' . (isset($user_znote_data['flag']) && $user_znote_data['flag'] == $code ? ' selected' : '') . '>' . $c . '</option>';
42+ ?>
43+ </select>
44+ </div>
45+ <?php Token::create(); ?>
46+ <button type="submit" class="znx-acct-btn"><?= t('settings.submit') ?></button>
47+ </form>
48+
49+<?php endif; ?>
50+
51+</div><!-- .znx-acct -->
A layouts/default/views/shop.php +1-0 View file
@@ -0,0 +1,1 @@
1+<?php theme_include('parts/shop-modern.php'); ?>
A layouts/default/views/spells.php +195-0 View file
@@ -0,0 +1,195 @@
1+<?php
2+/**
3+ * Spell list.
4+ *
5+ * Prepared by spells.php - see the docblock there for the variables.
6+ */
7+?>
8+<?php
9+
10+if ($spells) {
11+ // Preparing data
12+ $configVoc = $config['vocations'];
13+ $types = array_keys($spells);
14+ $itemImg = static function($id){ return function_exists('znote_item_image_url') ? htmlspecialchars(znote_item_image_url((int)$id, 'gif'), ENT_QUOTES) : ''; };
15+
16+ // Filter spells by vocation
17+ $getVoc = (isset($_GET['vocation'])) ? getValue($_GET['vocation'] ?? null) : 'all';
18+ if ($getVoc !== 'all') {
19+ $getVoc = (int)$getVoc;
20+ foreach ($types as $type)
21+ foreach ($spells[$type] as $name => $spell)
22+ if (!empty($spell['vocations']))
23+ if (!in_array($getVoc, $spell['vocations']))
24+ unset($spells[$type][$name]);
25+ }
26+
27+ // Render HTML
28+ ?>
29+
30+ <div class="znx-acct">
31+
32+ <div class="znx-acct-head" id="spells"><?= t('spells.title') ?><?php if ($getVoc !== 'all') echo ' ('.$configVoc[$getVoc]['name'].')';?></div>
33+
34+ <form action="#spells" class="znx-acct-toolbar filter_spells">
35+ <div class="znx-acct-toolbar__field">
36+ <label for="vocation"><?= t('spells.filter_voc') ?></label>
37+ <select id="vocation" name="vocation" class="znx-acct-select">
38+ <option value="all"><?= t('spells.all') ?></option>
39+ <?php foreach ($config['vocations'] as $id => $vocation): ?>
40+ <option value="<?php echo $id; ?>" <?php if ($getVoc === $id) echo "selected"; ?>><?php echo $vocation['name']; ?></option>
41+ <?php endforeach; ?>
42+ </select>
43+ </div>
44+ <div class="znx-acct-toolbar__submit"><button type="submit" class="znx-acct-btn"><?= t('common.search') ?></button></div>
45+ </form>
46+
47+ <div class="znx-acct-head"><?= t('spells.types') ?></div>
48+ <div class="znx-pill-nav">
49+ <?php foreach ($types as $type): ?>
50+ <a href="#spell_<?php echo $type; ?>"><?php echo ucfirst($type); ?></a>
51+ <?php endforeach; ?>
52+ </div>
53+
54+ <div class="znx-acct-head" id="spell_instant"><?= t('spells.instant') ?></div>
55+ <div class="znx-jump-top"><a href="#spells"><?= t('spells.jump_top') ?></a></div>
56+ <div class="znx-acct-table-wrap">
57+ <table class="znx-acct-table">
58+ <tbody>
59+ <tr class="yellow">
60+ <td><?= t('common.name') ?></td>
61+ <td><?= t('spells.words') ?></td>
62+ <td><?= t('common.level') ?></td>
63+ <td><?= t('spells.mana') ?></td>
64+ <td><?= t('spells.vocations') ?></td>
65+ </tr>
66+ <?php foreach ($spells['instant'] as $spell): ?>
67+ <tr>
68+ <td><?php echo $spell['name']; ?></td>
69+ <td><?php echo $spell['words']; ?></td>
70+ <td><?php echo $spell['lvl']; ?></td>
71+ <td><?php echo $spell['mana']; ?></td>
72+ <td><?php
73+ if (!empty($spell['vocations'])) {
74+ if ($getVoc !== 'all') {
75+ echo $configVoc[$getVoc]['name'];
76+ } else {
77+ $names = array();
78+ foreach ($spell['vocations'] as $id) {
79+ if (isset($configVoc[$id]))
80+ $names[] = $configVoc[$id]['name'];
81+ }
82+ echo implode(',<br>', $names);
83+ }
84+ }
85+ ?></td>
86+ </tr>
87+ <?php endforeach; ?>
88+ </tbody>
89+ </table>
90+ </div>
91+
92+ <div class="znx-acct-head" id="spell_rune"><?= t('spells.runes') ?></div>
93+ <div class="znx-jump-top"><a href="#spells"><?= t('spells.jump_top') ?></a></div>
94+ <div class="znx-acct-table-wrap">
95+ <table class="znx-acct-table">
96+ <tbody>
97+ <tr class="yellow">
98+ <td><?= t('common.name') ?></td>
99+ <td><?= t('common.level') ?></td>
100+ <td><?= t('spells.magic_level') ?></td>
101+ <td><?= t('spells.image') ?></td>
102+ <td><?= t('spells.vocations') ?></td>
103+ </tr>
104+ <?php foreach ($spells['rune'] as $spell): ?>
105+ <tr>
106+ <td><?php echo $spell['name']; ?></td>
107+ <td><?php echo $spell['lvl']; ?></td>
108+ <td><?php echo $spell['maglv']; ?></td>
109+ <td><img src="<?php echo $itemImg($spell['id']); ?>" alt="<?= h(t('spells.rune_image')) ?>"></td>
110+ <td><?php
111+ if (!empty($spell['vocations'])) {
112+ if ($getVoc !== 'all') {
113+ echo $configVoc[$getVoc]['name'];
114+ } else {
115+ $names = array();
116+ foreach ($spell['vocations'] as $id) {
117+ if (isset($configVoc[$id]))
118+ $names[] = $configVoc[$id]['name'];
119+ }
120+ echo implode(',<br>', $names);
121+ }
122+ }
123+ ?></td>
124+ </tr>
125+ <?php endforeach; ?>
126+ </tbody>
127+ </table>
128+ </div>
129+
130+ <?php if (isset($spells['conjure'])): ?>
131+ <div class="znx-acct-head" id="spell_conjure"><?= t('spells.conjure') ?></div>
132+ <div class="znx-jump-top"><a href="#spells"><?= t('spells.jump_top') ?></a></div>
133+ <div class="znx-acct-table-wrap">
134+ <table class="znx-acct-table">
135+ <tbody>
136+ <tr class="yellow">
137+ <td><?= t('common.name') ?></td>
138+ <td><?= t('spells.words') ?></td>
139+ <td><?= t('common.level') ?></td>
140+ <td><?= t('spells.mana') ?></td>
141+ <td><?= t('spells.soul') ?></td>
142+ <td><?= t('spells.charges') ?></td>
143+ <td><?= t('spells.image') ?></td>
144+ <td><?= t('spells.vocations') ?></td>
145+ </tr>
146+ <?php foreach ($spells['conjure'] as $spell): ?>
147+ <tr>
148+ <td><?php echo $spell['name']; ?></td>
149+ <td><?php echo $spell['words']; ?></td>
150+ <td><?php echo $spell['lvl']; ?></td>
151+ <td><?php echo $spell['mana']; ?></td>
152+ <td><?php echo $spell['soul']; ?></td>
153+ <td><?php echo $spell['conjureCount']; ?></td>
154+ <td><img src="<?php echo $itemImg($spell['conjureId']); ?>" alt="<?= h(t('spells.rune_image')) ?>"></td>
155+ <td><?php
156+ if (!empty($spell['vocations'])) {
157+ if ($getVoc !== 'all') {
158+ echo $configVoc[$getVoc]['name'];
159+ } else {
160+ $names = array();
161+ foreach ($spell['vocations'] as $id) {
162+ if (isset($configVoc[$id]))
163+ $names[] = $configVoc[$id]['name'];
164+ }
165+ echo implode(',<br>', $names);
166+ }
167+ }
168+ ?></td>
169+ </tr>
170+ <?php endforeach; ?>
171+ </tbody>
172+ </table>
173+ </div>
174+ <div class="znx-jump-top"><a href="#spells"><?= t('spells.jump_top') ?></a></div>
175+ <?php endif; ?>
176+
177+ </div><!-- .znx-acct -->
178+ <?php
179+} else {
180+ ?>
181+ <div class="znx-acct">
182+ <div class="znx-acct-head"><?= t('spells.title') ?></div>
183+ <div class="znx-empty-box"><?= h(t('spells.not_loaded')) ?></div>
184+ </div>
185+ <?php
186+}
187+
188+/* Debug tests
189+foreach ($spells as $type => $spells) {
190+ data_dump($spells, false, "Type: $type");
191+}
192+
193+// All spell attributes?
194+'group', 'words', 'lvl', 'level', 'maglv', 'magiclevel', 'charges', 'allowfaruse', 'blocktype', 'mana', 'soul', 'prem', 'aggressive', 'range', 'selftarget', 'needtarget', 'blockwalls', 'needweapon', 'exhaustion', 'groupcooldown', 'needlearn', 'casterTargetOrDirection', 'direction', 'params', 'playernameparam', 'conjureId', 'reagentId', 'conjureCount', 'vocations'
195+*/
A layouts/default/views/success.php +6-0 View file
@@ -0,0 +1,6 @@
1+<?php ?>
2+<h1><?= t('success.title') ?></h1>
3+<?php if (in_array(($_GET['provider'] ?? ''), array('stripe', 'mercadopago'), true)): ?>
4+ <p><?= h(t('success.payment_pending')) ?></p>
5+<?php endif; ?>
6+<?= t('success.go') ?> <script> document.write('<a href="' + document.referrer + '"><?= t('success.back') ?></a>'); </script>
A layouts/default/views/support.php +44-0 View file
@@ -0,0 +1,44 @@
1+<?php
2+/**
3+ * Support list.
4+ *
5+ * Prepared by support.php: $srtGrp - staff grouped by in-game position.
6+ */
7+?>
8+<div class="znx-acct">
9+
10+<div class="znx-acct-head"><?= t('support.title') ?></div>
11+<div class="znx-acct-table-wrap">
12+<?php
13+$writeHeader = true;
14+if (!empty($srtGrp)) {
15+ foreach (array_reverse($srtGrp) as $grpName => $grpList) {
16+ ?>
17+ <table id="supportTable" class="znx-acct-table">
18+ <?php if ($writeHeader) {
19+ $writeHeader = false; ?>
20+ <tr class="yellow">
21+ <th width="30%"><?= t('common.group') ?></th>
22+ <th width="40%"><?= t('common.name') ?></th>
23+ <th width="30%"><?= t('common.status') ?></th>
24+ </tr>
25+ <?php
26+ }
27+ foreach ($grpList as $char) {
28+ if ($char['name'] != $config['website_char']) {
29+ echo '<tr>';
30+ echo "<td width='30%'>". $grpName ."</td>";
31+ echo '<td width="40%"><a href="characterprofile.php?name='. $char['name'] .'">'. $char['name'] .'</a></td>';
32+ echo "<td width='30%'>". online_id_to_name($char['online']) ."</td>";
33+ echo '</tr>';
34+ }
35+ }
36+ ?>
37+ </table>
38+ <?php
39+ }
40+}
41+?>
42+</div>
43+
44+</div><!-- .znx-acct -->
A layouts/default/views/team.php +33-0 View file
@@ -0,0 +1,33 @@
1+<?php
2+/**
3+ * Public staff directory.
4+ *
5+ * Prepared by team.php: $staffGroups (group_id => ['label', 'members']),
6+ * highest group first; $loadOutfits.
7+ */
8+?>
9+<h1><?= t('team.title') ?></h1>
10+
11+<?php if ($staffGroups): ?>
12+ <?php foreach ($staffGroups as $group): ?>
13+ <h2><?= h($group['label']) ?></h2>
14+ <table>
15+ <tr class="yellow">
16+ <?php if ($loadOutfits): ?><td><?= t('common.image') ?></td><?php endif; ?>
17+ <td><?= t('team.col_name') ?></td>
18+ </tr>
19+ <?php foreach ($group['members'] as $member): ?>
20+ <tr>
21+ <?php if ($loadOutfits): ?>
22+ <td>
23+ <img src="<?= h($config['show_outfits']['imageServer']) ?>?id=<?= (int)$member['looktype'] ?>&addons=<?= (int)$member['lookaddons'] ?>&head=<?= (int)$member['lookhead'] ?>&body=<?= (int)$member['lookbody'] ?>&legs=<?= (int)$member['looklegs'] ?>&feet=<?= (int)$member['lookfeet'] ?>" alt="">
24+ </td>
25+ <?php endif; ?>
26+ <td><a href="characterprofile.php?name=<?= urlencode($member['name']) ?>"><?= h($member['name']) ?></a></td>
27+ </tr>
28+ <?php endforeach; ?>
29+ </table>
30+ <?php endforeach; ?>
31+<?php else: ?>
32+ <h2><?= t('team.none') ?></h2>
33+<?php endif; ?>
A layouts/default/views/topguilds.php +34-0 View file
@@ -0,0 +1,34 @@
1+<?php ?>
2+
3+<div class="znx-acct">
4+
5+<?php if (!empty($guilds) && $guilds !== false): ?>
6+ <div class="znx-acct-head"><?= t('topguilds.title') ?></div>
7+ <div class="znx-acct-table-wrap">
8+ <table id="onlinelistTable" class="znx-acct-table">
9+ <tr class="yellow">
10+ <th>#</th>
11+ <th><?= t('online.label_name') ?></th>
12+ <th><?= t('topguilds.frags') ?></th>
13+ </tr>
14+ <?php
15+ foreach ($guilds as $guild):
16+ $url = url("guilds.php?name=". $guild['name']);
17+ ?>
18+ <tr class="special" onclick="javascript:window.location.href='<?php echo $url; ?>'">
19+ <td><?php
20+ echo convert_number_to_words($count);
21+ $count++;
22+ ?></td>
23+ <td><a href="" onclick="return false"><?php echo $guild['name']; ?></a></td>
24+ <td><?php echo $guild['frags']; ?></td>
25+ </tr>
26+ <?php
27+ endforeach; ?>
28+ </table>
29+ </div>
30+<?php else: ?>
31+ <div class="znx-acct-head"><?= t('topguilds.no_frags') ?></div>
32+<?php endif; ?>
33+
34+</div><!-- .znx-acct -->
A layouts/default/views/toponline.php +40-0 View file
@@ -0,0 +1,40 @@
1+<?php
2+
3+echo '<CENTER><H2>'. t('toponline.title', ['site' => $config['site_title']]) .'</H2></CENTER>
4+<BR>
5+<table class="table table-striped">
6+ <td><center><b>#</b></center></td>
7+ <td width="10%"><b>'. t('common.name') .'</b></td>';
8+if($type == "sum")
9+ echo '<td ><center><b><center><a href="?subtopic=onlinetime&type=sum">'. t('common.total') .'</a></center></B></TD>';
10+else
11+ echo '<td ><center><b><center><a href="?subtopic=onlinetime&type=sum">'. t('common.total') .'</a></center></B></TD>';
12+for($i = 3; $i >= 2; $i--)
13+{
14+ if($type == $i)
15+ echo '<TD ><b><center><a href="?subtopic=onlinetime&type='.$i.'">'. t('toponline.days_ago', ['days' => $i]) .'</a></center></B></TD>';
16+ else
17+ echo '<TD ><b><center><a href="?subtopic=onlinetime&type='.$i.'">'. t('toponline.days_ago', ['days' => $i]) .'</a></center></B></TD>';
18+}
19+if($type == 1)
20+ echo '<TD ><b><center><a href="?subtopic=onlinetime&type=1">'. t('toponline.day_ago') .'</a></center></B></TD>';
21+else
22+ echo '<TD ><b><center><a href="?subtopic=onlinetime&type=1">'. t('toponline.day_ago') .'</a></center></B></TD>';
23+if(empty($type))
24+ echo '<TD><b><center><a href="?subtopic=onlinetime">'. t('common.today') .'</a></center></B></TD>';
25+else
26+ echo '<TD ><b><center><a href="?subtopic=onlinetime">'. t('common.today') .'</a></center></B></TD>';
27+echo '</TR>';
28+$number_of_rows = 1;
29+if($znotePlayers)
30+foreach($znotePlayers as $player)
31+{
32+ echo '<td><center>'. $number_of_rows . '.</center></td>';
33+ echo '<td><a href="characterprofile.php?name=' .$player['name']. '">' .$player['name']. '</a>';
34+ echo '<br> ' .$player['level']. ' '.htmlspecialchars(vocation_id_to_name($player['vocation'])).' ';
35+ echo '<td ><center>' .onlineTimeTotal($player['onlinetimeall']).'</td>';
36+ $number_of_rows++;
37+ echo '<td ><center>'.hours_and_minutes($player['onlinetime3']).'</center></td><td ><center>'.hours_and_minutes($player['onlinetime2']).'</center></td><td ><center>'.hours_and_minutes($player['onlinetime1']).'</center></td><td ><center>'.hours_and_minutes($player['onlinetimetoday']).'</center></td></tr>';
38+}
39+echo '</TABLE></div>';
40+?>
A layouts/default/views/twofa2.php +98-0 View file
@@ -0,0 +1,98 @@
1+<h1><?= t_default('twofa2.title', 'Two-factor authentication') ?></h1>
2+
3+<?php if (empty($errors) === false): ?>
4+ <?= output_errors($errors) ?>
5+<?php endif; ?>
6+
7+<?php if (!empty($successes)): ?>
8+ <?php foreach ($successes as $message): ?>
9+ <div class="alert-box alert-success"><p><?= h($message) ?></p></div>
10+ <?php endforeach; ?>
11+<?php endif; ?>
12+
13+<h2><?= t_default('twofa2.app_title', 'Authenticator app') ?></h2>
14+<?php if ($status['totp_enabled']): ?>
15+ <p><?= t_default('twofa2.app_enabled', 'Enabled.') ?></p>
16+ <form method="post" data-confirm="Disable the authenticator app?">
17+ <?php Token::create(); ?>
18+ <button type="submit" name="tfa2_totp_disable" value="1"><?= t_default('twofa2.disable', 'Disable') ?></button>
19+ </form>
20+<?php else:
21+ $pendingRow = znote2fa_row($accountId);
22+ if (empty($pendingRow['totp_secret'])) {
23+ ?>
24+ <form method="post">
25+ <?php Token::create(); ?>
26+ <button type="submit" name="tfa2_totp_start" value="1"><?= t_default('twofa2.app_start', 'Set up an authenticator app') ?></button>
27+ </form>
28+ <?php
29+ } else {
30+ ?>
31+ <img
32+ src="<?php echo TokenAuth6238::getBarCodeUrl($user_data['name'], $_SERVER["HTTP_HOST"], $pendingRow['totp_secret'], preg_replace('/\s+/', '', $config['site_title'])); ?>"
33+ alt="Two-factor authentication QR code image for this account."
34+ />
35+ <form method="post">
36+ <?php Token::create(); ?>
37+ <input type="text" name="tfa2_totp_code" placeholder="000000" autocomplete="one-time-code">
38+ <button type="submit" name="tfa2_totp_confirm" value="1"><?= t_default('twofa2.app_confirm', 'Confirm') ?></button>
39+ </form>
40+ <?php
41+ }
42+endif; ?>
43+
44+<h2><?= t_default('twofa2.email_title', 'E-mail codes') ?></h2>
45+<?php if (znote2fa_v2_config()['email_otp_enabled']): ?>
46+ <p><?= t_default('twofa2.email_help', 'Receive a one-time code by e-mail whenever you log in and have no authenticator app configured.') ?></p>
47+ <form method="post">
48+ <?php Token::create(); ?>
49+ <label>
50+ <input type="checkbox" name="tfa2_email_enabled" value="1" <?= $status['email_otp_enabled'] ? 'checked' : '' ?>>
51+ <?= t_default('twofa2.email_enable', 'Enable e-mail codes') ?>
52+ </label>
53+ <button type="submit" name="tfa2_email_toggle" value="1"><?= t_default('twofa2.save', 'Save') ?></button>
54+ </form>
55+<?php else: ?>
56+ <p><?= t_default('twofa2.email_unavailable', 'E-mail codes are disabled by the site administrator.') ?></p>
57+<?php endif; ?>
58+
59+<h2><?= t_default('twofa2.recovery_title', 'Recovery codes') ?></h2>
60+<?php if ($revealedRecoveryCodes): ?>
61+ <p><strong><?= t_default('twofa2.recovery_reveal', 'Save these somewhere safe. Each one works once and this is the only time they are shown.') ?></strong></p>
62+ <ul>
63+ <?php foreach ($revealedRecoveryCodes as $code): ?>
64+ <li><code><?= h($code) ?></code></li>
65+ <?php endforeach; ?>
66+ </ul>
67+<?php else: ?>
68+ <p><?= t_default('twofa2.recovery_remaining', '{n} unused recovery codes.', ['n' => $status['recovery_remaining']]) ?></p>
69+<?php endif; ?>
70+<form method="post" <?= $status['recovery_remaining'] > 0 ? 'data-confirm="Generating new codes invalidates the old ones. Continue?"' : '' ?>>
71+ <?php Token::create(); ?>
72+ <button type="submit" name="tfa2_recovery_generate" value="1"><?= t_default('twofa2.recovery_generate', 'Generate new recovery codes') ?></button>
73+</form>
74+
75+<h2><?= t_default('twofa2.devices_title', 'Trusted devices') ?></h2>
76+<?php if ($devices): ?>
77+ <ul>
78+ <?php foreach ($devices as $device): ?>
79+ <li>
80+ <?= h($device['label']) ?> - <?= h($device['ip']) ?>
81+ (<?= t_default('twofa2.last_used', 'last used {when}', ['when' => getClock((int)$device['last_used_at'], true)]) ?>)
82+ <form method="post" style="display:inline;">
83+ <?php Token::create(); ?>
84+ <button type="submit" name="tfa2_device_revoke" value="<?= (int)$device['id'] ?>"><?= t_default('twofa2.revoke', 'Revoke') ?></button>
85+ </form>
86+ </li>
87+ <?php endforeach; ?>
88+ </ul>
89+<?php else: ?>
90+ <p><?= t_default('twofa2.no_devices', 'No trusted devices.') ?></p>
91+<?php endif; ?>
92+
93+<h2><?= t_default('twofa2.logout_all_title', 'Log out everywhere') ?></h2>
94+<p><?= t_default('twofa2.logout_all_help', 'Forgets every trusted device and requires the two-factor code again on every session, including this one\'s next login.') ?></p>
95+<form method="post" data-confirm="Log out all devices and forget trusted devices?">
96+ <?php Token::create(); ?>
97+ <button type="submit" name="tfa2_logout_all" value="1"><?= t_default('twofa2.logout_all', 'Log out all devices') ?></button>
98+</form>
Top